본문 바로가기
  • lakescript
스터디 이야기/Terraform

[T101] 3-3. Terraform - 반복문(dynamic)

by lakescript 2024. 6. 26.

 

더보기

이 스터디는 CloudNet@에서 진행하는 T101 스터디를 참여하면서 공부하는 내용을 기록하는 블로그 포스팅입니다.

CloudNet@에서 제공해주는 자료들과 테라폼으로 시작하는 IaC 를 바탕으로 작성되었습니다.

 

반복문

dynamic

리소스 같은 테라폼 구성을 작성하다 보면 count나 for_each구문을 사용한 리소스 전체를 여러 개 생성하는 것 외에도 리소스 내에 선언되는 구성 블록을 다중으로 작성해야 하는 경우가 있습니다.

 

aws_security_group 리소스 내에 선언되는 구성 블록

resource "aws_security_group" "allow_tls" {
  name 			= "allow_tls"
  description 	= "Allow TLS inbound trffic"
  vpc_id		= aws_vpc.main.id
  
  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]
  }
  
  ingress {
  	description			= "HTTP"
    from_port 			= 8080
    to_port				= 8080
    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"]
  }
  
  tags = {
  	Name = "allow TLS"
  }
}

 

리소스 내의 블록 속성(Attributes as Blocks)은 리소스 자체의 반복 선언이 아닌 내부 속성 요소 중 블록으로 표현되는 부분에 대해서만 반복 구문을 사용해야 하므로, 이때 dynamic 블록을 사용하여 동적인 블록을 생성할 수 있습니다. 즉, dynamic 블록을 사용하여 리소스 내부 속성 블록을 동적인 블록으로 생성할 수 있습니다.

dynamic 블록 활용 예시

일반적인 블록 속성 반복 적용 dynamic 블록 적용
resource "provider_resource" "name" {
  name = "some_resource"

    some_setting {
        key = a_value
    }

    some_setting {
        key = b_value
    }

    some_setting {
        key = c_value
    }

    some_setting {
        key = d_value
    }
}
resource "provider_resource" "name" {
    name = "some_resource"

    dynamic "some_setting" {
        for_each = {
             a_key = a_value
             b_key = b_value
             c_key = c_value
             d_key = d_value
        }
    
    content {
        key = some_setting.value
    }
}

dynamic 블록을 작성하려면, 기존 블록의 속성 이름을 dynamic 블록의 이름으로 선언하고 기존 블록 속성에 정의되는 내용을 content 블록에 작성합니다. 또, 반복 선언에 사용되는 반복문 구문은 for_each를 사용합니다. 그리고 기존 for_each 적용 시 each 속성에 key, value가 적용되었다면 dynamic 에서는 dynamic에 지정한 이름에 대해 속성이 부여됩니다.

 

 

리소스 내에 반복적으로 선언되는 구성 블록

data "archive_file" "dotfile" {
    type			= "zip"
    output_path 	= "${path.module}/dotfiles.zip"
    
    source {
    	content		= "hello a"
        filename	= "${path.module}/a.txt"
    }
    
    source {
    	content		= "hello b"
        filename	= "${path.module}/b.txt"
    }
    
    source {
    	content		= "hello c"
        filename	= "${path.module}/c.txt"
    }
}

위와 같이 main.tf를 작성하여 archive provider의 archive_file에 source 블록 선언을 반복하는 경우를 확인해보겠습니다.

새로운 프로바이더가 추가되는 경우엔 terraform init을 실행해야 합니다.

 

 

그 후 terraform apply를 실행하면 dotfiles.zip 파일이 생성되는 것을 확인하실 수 있습니다.

그 압축을 풀고 생성된 파일의 내용을 정의한 source 블록 속성의 정의와 맞는지 확인합니다.

 

 

리소스 내에 반복적으로 선언되는 구성을 dynamic 블록으로 재구성

variable "names" {
    default = {
        a = "hello a"
        b = "hello b"
        c = "hello c"
    }
}

data "archive_file" "dotfiles" {
    type        = "zip"
    output_path = "${path.module}/dotfile.zip"

    dynamic "source" {
      for_each = var.names
      content {
        content = source.value
        filename = "${path.module}/${source.key}.txt"
      }
    }
}

 

dynamic 블록으로 선언하고 다시 terraform apply를 수행해보겠습니다. 

동일한 결과가 예상되므로 변경 사항이 없는 것을 확인할 수 있습니다.