이번 시간은
Terraform 모듈을 작성하는 방법
에 대해 알아보겠습니다.
1. Terraform 모듈 구성 규칙
- 단일 리소스를 단순히 감싸는 모듈 작성 ❌
- 모듈을 만들때 의미 있는 추상화(Abstrcation)가 존재해야함.
- 단순히 단일 리소스를 감싸는 역할만 수행한다면, 불필요한 코드 추가 및 가동성 ⬇️
- 논리적인 관계에 있는 리소스들을 하나의 단위로 캡슐화
- 관련된 리소스들을 하나의 그룹으로 묶어서 관리
- 예를 들어,
네트워크 기초 구성(VPC, Subnet, Firewall)이나 보안 제어(IAM 정책, 키 관리)처럼
관련된 리소스들을 하나의 단위로 묶기 - 즉, 하나의 기능 수행을 위해 함께 작동하는 인프라 요소들을 하나로 묶을 것.
- 계층구조를 단순하게 유지
- Terraform 모듈 구성에서 깊은 단계의 중첩은 관리의 어려움 초래
- 1,2 단계 정도까지만 중첩을 허용하여 관리할 것.
- 모듈 내부에서 Provider 설정 ❌
- 자식 모듈은 루트 모듈에서 설정한 Provider를 자동으로 상속받음.
- Provider 설정은 전역에서 1번만 설정하여야 하기에,
개별 자식 모듈 내부에서 중복 선언 ❌
- 외부 모듈의 사용 피할 것
- 리소스 자체에서는 지원을 하지만, 해당 모듈 내부에서 Interface를 제공하지 않을 수 있음
- 사용해야 한다면
- DIY(Do It Yourself) : 조직 내에서 직접 Terraform 모듈을 설계하고 작성 후 관리
- 만드는 Repository 이름의 접두사는 "terraform-" 으로 시작할 것(권장)
- Use After Fork : 외부 모듈 Repository를 직접 복제 후, 커스텀하여 사용
- DIY(Do It Yourself) : 조직 내에서 직접 Terraform 모듈을 설계하고 작성 후 관리
2. Resource 네이밍 규칙
- snake_case로 작성
- 각 리소스에 존재하는 name 속성에는 적용 ❌
- 모듈에서 단 하나만 존재하는 리소스라면, main 또는 this 라는 이름으로 사용
- 예시 : resource "aws_instance" "this" {}
- 의미있는 이름으로 정의할 것
- 단수형 이름으로 정의할 것
- 리소스 이름에 리소스 타입을 반복 ❌
- 예시 : resource "aws_security_group" "security_group" {}
3. Variables 네이밍 규칙
- Boolean 값을 가지는 Variable은 긍정으로 작성
- 예시 : variable "enable_external_access" {}
- 숫자 값을 나타내는 입력 변수, 로컬 변수, 출력 변수에는 단위를 포함하여 작성
- 예시 : variable "ram_size_gb" {}
- Storage 크기와 일반적인 단위 표기법 구분
- Storage 크기(Disk, File System 등)는 이진 단위(MiB, GiB) 사용
- 예시 : variable "disk_size_gib" {}
- 기타 일반적인 메트릭(대역폭, 메모리 크기 등)은 십진 단위(MB, GB) 사용
- 예시 : variable "ram_size_gb" {}
- Storage 크기(Disk, File System 등)는 이진 단위(MiB, GiB) 사용
4. Use attachment resources
- 한 개의 리소스에서 다른 리소스들과 연관 관계를 갖는 변수가 존재할 때,
해당 리소스 내부에서 정의하지 않고, 별도의 Attachment 리소스를 활용해서 관리할 것
▶️ 이해가 잘 안가는 말이지만, 쉽게 생각하면 메서드 단일 책임 원칙을 준수하라는 느낌
- 지양해야 하는 패턴 -
resource "aws_security_group" "allow_tls" {
...
ingress {
description = "TLS from VPC"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = [aws_vpc.main.cidr_block]
ipv6_cidr_blocks = [aws_vpc.main.ipv6_cidr_block]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
}
- 지향해야 하는 패턴 -
# ✅ 보안 그룹 정의 (규칙은 여기에 직접 포함하지 않음)
resource "aws_security_group" "allow_tls" {
name = "allow_tls"
description = "Allow TLS inbound traffic"
vpc_id = aws_vpc.main.id
}
# ✅ 보안 그룹 규칙을 별도의 리소스로 정의
resource "aws_security_group_rule" "ingress_tls" {
type = "ingress"
description = "TLS from VPC"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = [aws_vpc.main.cidr_block]
ipv6_cidr_blocks = [aws_vpc.main.ipv6_cidr_block]
security_group_id = aws_security_group.allow_tls.id
}
resource "aws_security_group_rule" "egress_all" {
type = "egress"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
security_group_id = aws_security_group.allow_tls.id
}
5. Use Default Tags
- 태그를 지원하는 모든 리소스에는 기본적으로 Tag를 할당할 것‼️
- AWS에서는 aws_default_tags datasource를 이용하여
루트 모듈에서 공통적인 태그를 자동으로 적용하는 것이 좋음 - 일관성 유지를 위해 공통 태그 사용
- 권장 태그 목록
- Name : 사람이 읽을 수 있는 리소스 이름
- AppId : 리소스를 사용하는 Application의 ID
- AppRole : 리소스의 기술적 역할 (webserver, database 등)
- AppPurpose : 리소스의 비즈니스 목적 (frontend ui, payment processor 등)
- Environment : 리소스가 속한 환경 (dev, test, prd)
- Project : 이 리소스를 사용하는 프로젝트 이름
6. Pre-commit Hook을 설정하라
Git의 Pre-commit Hook을 활용하여,
작성한 Terraform 모듈의
코드 스타일 검사 및 보안 검사를 자동화
▶️ terraform fmt, tflint, checkov 같은 도구 사용
참고 자료 출처
Best practices for code base structure and organization - AWS Prescriptive Guidance
Best practices for code base structure and organization Proper code base structure and organization is critical as Terraform usage grows across large teams and enterprises. A well-architected code base enables collaboration at scale while enhancing maintai
docs.aws.amazon.com
https://www.youtube.com/watch?v=m9HeYtzeiLI
0. 삽질
저는 이런 내용들을 정확히 인지하기 전,
DIY(Do It Yourself)만 보고
Terraform Registry 사이트에서 속성들을 참고하여
GPT 선생님과 함께
약 2주간에 걸쳐 원하는 리소스들에 대한
Terraform 모듈을 작성했었습니다.
이후,
"캡슐화" 라는 단어를 보고
내 모듈은 잘못 작성되었다는 것을 알게되었습니다.
그래도 나름대로
확장 가능하게 설계하기 위해 최선을 다했고
Terraform 문법들에 대해 좀 더
익숙해지는 시간이었습니다.
+ 처음으로 Apache 라이센스라는 것도 넣어봤습니다.
https://github.com/orgs/GCP-Terraform-Module-steamedEggMaster/repositories
GCP-Terraform-Module-steamedEggMaster
GCP-Terraform-Module-steamedEggMaster has 29 repositories available. Follow their code on GitHub.
github.com
제가 작성했던 깃허브입니다.
terraform- 접두사가 붙어있지 않은 Repository가
제가 작성한 것입니다.
반면교사로 삼아주세요!
'DevOps' 카테고리의 다른 글
| 어떻게 하면 Terraform을 효율적으로 관리할 수 있을까? - 1. Terraform 모듈이란? (0) | 2025.03.10 |
|---|
안녕하세요. 성장하고 싶은 개발자 orElse입니다. 지켜봐주세요.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!