Day 10— Terraform 조건식, 동적 블록 및 스플랫 표현식

발행: (2025년 12월 4일 오전 01:56 GMT+9)
6 min read
원문: Dev.to

Source: Dev.to

조건식

조건식은 조건을 평가하고, 해당 조건이 참인지 거짓인지에 따라 두 값 중 하나를 반환합니다.

구문

condition ? true_value : false_value

사용 사례

  • 환경(dev vs prod)에 따라 인스턴스 유형 선택
  • 설정에 따라 모니터링 활성화/비활성화
  • 지역에 따라 서로 다른 AMI 선택
  • 환경별 리소스 개수 설정
  • 환경‑특화 태그 적용

장점

  • 여러 환경에 대해 하나의 구성만 필요
  • 코드 중복 감소
  • 환경 차이를 명시적으로 표현
  • 구성 관리가 간편
  • 이해와 유지보수가 쉬움

사용 시점

  • 환경‑별 구성
  • 기능 플래그(기능 활성화/비활성화)
  • 조건부 리소스 생성
  • 지역‑별 설정
  • 비용 최적화(개발 환경에서는 작은 리소스 사용)

사용하지 말아야 할 경우

  • 조건이 많아 복잡한 로직(이때는 locals 사용)
  • 별도의 환경 파일이 더 명확할 때
  • 모든 환경이 동일해야 할 때

예시

resource "aws_instance" "conditional_example" {
  ami           = "ami-28765345876"
  instance_type = var.environment == "prod" ? "t3.large" : "t2.micro"

  tags = {
    Name = "conditional-instance-${var.environment}"
  }
}

terraform plan을 실행하면 environment 변수에 따라 선택된 인스턴스 유형이 표시됩니다:

terraform plan
data.aws_ami.amazon_linux: Reading...
data.aws_ami.amazon_linux: Read complete after 1s [id=ami-02610f36df0c59544]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated
with the following symbols:
  + create

# aws_instance.conditional_example will be created
+ resource "aws_instance" "conditional_example" {
    + ami           = "ami-02610f36df0c59544"
    + instance_type = "t2.micro"
    # ... other attributes omitted for brevity
}

이 예시에서 var.environment"prod"이면 인스턴스 유형이 t3.large가 되고, 그 외에는 기본값인 t2.micro가 사용됩니다.

동적 블록

동적 블록은 컬렉션(리스트 또는 맵)을 기반으로 리소스 내에 여러 중첩 블록을 자동으로 생성하여, 유사한 블록 구성을 반복할 필요를 없애줍니다.

구문

dynamic "block_name" {
  for_each = var.collection
  content {
    # each.key와 each.value를 사용한 블록 구성
  }
}
  • for_each는 리스트 또는 맵을 순회합니다.
  • content는 생성되는 각 블록이 포함할 내용을 정의합니다.
  • 값은 each.keyeach.value로 접근합니다.

사용 사례

  • 보안 그룹 인그레스/이그레스 규칙
  • EC2 인스턴스에 여러 EBS 볼륨 연결
  • IAM 정책 문(statement)
  • 로드 밸런서 리스너
  • 라우트 테이블 라우트
  • 반복되는 중첩 블록 구조 전반

장점

  • 반복적인 코드 제거
  • 항목 추가·삭제가 쉬움
  • 변수에 의해 구성이 구동됨
  • 코드가 더 깔끔하고 유지보수 용이
  • 복잡한 데이터 구조 지원

사용 시점

  • 유사한 중첩 블록이 다수 존재할 때
  • 구성 개수가 가변적일 때
  • 보안 그룹 규칙
  • 인라인 정책
  • 모든 반복 블록 패턴

사용하지 말아야 할 경우

  • 하나 혹은 몇 개의 정적 블록만 필요할 때(오버헤드가 불필요)
  • 코드 가독성을 떨어뜨릴 때
  • 최상위 리소스에는(count 또는 for_each 사용)

예시

resource "aws_security_group" "dynamic_sg" {
  name        = "dynamic-sg-${var.environment}"
  description = "Security group with dynamic rules"

  dynamic "ingress" {
    for_each = var.ingress_rules
    content {
      from_port   = ingress.value.from_port
      to_port     = ingress.value.to_port
      protocol    = ingress.value.protocol
      cidr_blocks = ingress.value.cidr_blocks
      description = ingress.value.description
    }
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "dynamic-sg-${var.environment}"
  }
}
variable "ingress_rules" {
  description = "List of ingress rules for security group"
  type = list(object({
    from_port   = number
    to_port     = number
    protocol    = string
    cidr_blocks = list(string)
    description = string
  }))
  default = [
    {
      from_port   = 80
      to_port     = 80
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
      description = "HTTP"
    },
    {
      from_port   = 443
      to_port     = 443
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
      description = "HTTPS"
    }
  ]
}

terraform plan을 실행하면 동적으로 생성된 인그레스 규칙이 표시됩니다:

# aws_security_group.dynamic_sg will be created
+ resource "aws_security_group" "dynamic_sg" {
    + arn         = (known after apply)
    + description = "Security group with dynamic rules"
    + egress      = [
        {
          + cidr_blocks = ["0.0.0.0/0"]
          + from_port   = 0
          + protocol    = "-1"
          + to_port     = 0
        }
      ]
    + ingress = [
        {
          + from_port   = 80
          + to_port     = 80
          + protocol    = "tcp"
          + cidr_blocks = ["0.0.0.0/0"]
          + description = "HTTP"
        },
        {
          + from_port   = 443
          + to_port     = 443
          + protocol    = "tcp"
          + cidr_blocks = ["0.0.0.0/0"]
          + description = "HTTPS"
        }
      ]
    # ... other attributes omitted for brevity
}

동적 블록은 var.ingress_rules를 순회하면서 각 규칙마다 ingress 블록을 자동으로 생성하므로, 수동으로 복제할 필요가 없습니다.

Terraform 동적 블록 일러스트레이션

Back to Blog

관련 글

더 보기 »