Lim Seunghyun Space

[T102] 반복문 본문

IaC/Terraform

[T102] 반복문

Lim Seung Hyun 2023. 7. 16. 08:14

반복문

  • list 형태나 Key-Value 형태의 문자열 집합인 데이터가 있는 경우 동일한 내용에 대해 테라폼 구성 정의를 반복적으로 하지 않고 관리할 수 있다.

 

Count

  • 리소스나 모듈 블록에 count 값이 정수인 인수가 포함된 경우 선언된 정수 값만큼 리소스나 모듈을 생성한다.
  • count에서 생성되는 참조값은 count.iindex이며, 반복하는 경우 0부터 1씩 증가해 인덱스가 부여된다.

main.tf

resource "local_file" "abc" {
  count    = 5
  content  = "abc${count.index}"
  filename = "${path.module}/abc${count.index}.txt"
}

output "fileid" {
  value = local_file.abc.*.id
}

output "filename" {
  value = local_file.abc.*.filename
}

output "filecontent" {
  value = local_file.abc.*.content
}
abc0.txt ~ abc4.txt까지 생성되며, 각 content도 abc0 ~ abc4이다.
  • 여러 리소스나 모듈의 count로 지정되는 수량이 동일해야 하는 상황이 있는데, count에 외부 변수 값을 할당해서 구성하면 된다.

main.tf

variable "names" {
  type    = list(string)
  default = ["a", "b", "c"]
}

resource "local_file" "abc" {
  count   = length(var.names)
  content = "abc"
  # 변수 인덱스에 직접 접근
  filename = "${path.module}/abc-${var.names[count.index]}.txt"
}

resource "local_file" "def" {
  count   = length(var.names)
  content = local_file.abc[count.index].content
  # element function 활용
  filename = "${path.module}/def-${element(var.names, count.index)}.txt"
}
  • count로 생성되는 리소스의 경우 <리소스 타입>.<이름>[<인덱스 번호>], 모듈의 경우 module.<모듈 이름>[<인덱스 번호>]로 해당 리소스의 값을 참조한다.
  • 모듈 내에 count 적용이 불가능한 선언이 있을 수 있으므로 주의해야 한다.
  • 외부 변수가 list 타입인 경우 중간에 값이 삭제되면 인덱스가 줄어들어 의도했던 중간 값에 대한 리소스만 삭제되는 것이 아니라 이후의 정의된 리소스들도 삭제되고 재생성된다.

 

for_each

  • 리소스 또는 모듈 블록에서 for_each가 입력된 데이터 형태가 map 또는 set이면, 선언된 key 값 개수만큼 리소스를 생성하게 된다.
  • for_each에서 each 속성을 사용해 구성을 수정할 수 있다.
    • each.key: 인스턴스에 해당하는 map 타입의 key
    • each.value: 인스턴스에 해당하는 map의 value

main.tf

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

resource "local_file" "abc" {
  for_each = var.names
  content  = each.value
  filename = "${path.module}/abc-${each.key}.txt"
}

resource "local_file" "def" {
  for_each = local_file.abc
  content  = each.value.content
  filename = "${path.module}/def-${each.key}.txt"
}

 

  • 생성되는 리소스의 경우 <리소스 타입>.<이름>[<key>], 모듈의 경우 module.<모듈 이름>[<key>]로 해당 리소스의 값을 참조한다.
  • 리소스 간 종속성을 정의하기도 하고 변수로 다른 리소스에서 사용하거나 출력을 위한 결과 값으로 사용한다.

 

for

  • 복합 형식 값의 형태를 변환하는데 사용
    • list 값의 포맷을 변경하거나 특정 접두사(prefix)를 추가할 수 있고, output에 원하는 형태로 반복적인 결과를 표현할 수 있다.
      • list 타입인 경우, 값 또는 인덱스와 값을 반환
      • map 타입인 경우, 키 또는 키와 값에 대해 반환
      • set 타입인 경우, 키 값에 대해 반환
variable "names" {
  type    = list(string)
  default = ["a", "b"]
}

output "A_upper_value" {
  value = [for v in var.names : upper(v)]
}

output "B_index_and_value" {
  value = [for i, v in var.names : "${i} is ${v}"]
}

output "C_make_object" {
  value = { for v in var.names : v => upper(v) }
}

output "D_with_filter" {
  value = [for v in var.names : upper(v) if v != "a"]
}
  • for 구문을 사용하는 몇 가지 규칙
    1. list 유형의 경우 반환 받는 값이 하나로 되어 있으면 값을, 두 개의 경우 앞의 인수가 인덱스를 반환하고 뒤의 인수가 값을 반환
    2. map 유형의 경우 반환 받는 값이 하나로 되어 있으면 키를, 두 개의 경우 앞의 인수가 키를 반환하고 뒤의 인수가 값을 반환
    3. 결과 값은 for 문을 묶는 기호가 []인 경우 tuple을 반환하고, {}인 경우 object 형태로 반환
    4. obejct 형태의 경우 키와 값에 대한 쌍은 => 기호로 구분
    5. {} 형색을 사용해 object 형태로 결과를 반환하는 경우 키 값은 고유해야 하므로 값 뒤에 그룹화 모드 심볼(...)를 붙여서 키의 중복 방지
    6. if 구문을 추가해 조건 부여 가능

 

Dynamic

  • count나 for_each 구문을 사용한 리소스 전체를 여러 개 생성하는 것 외에도 리소스 내에 선언되는 구성 블록을 다중으로 작성해야 하는 경우가 있다.
  • Dynamic을 통해 리소스 내부 속성 블록을 동적인 블록으로 생성할 수 있다.
  • 속성 이름은 dynamic이고, 기존 블록 속성에 정의된 내용을 content 블록에 작성한다.
  • 반복 선언에 사용되는 반복 구문은 for_each를 사용한다.
    • dynamic에는 dynamic에 지정한 이름에 대해 속성이 부여된다.
variable "names" {
  default = {
    a = "hello a"
    b = "hello b"
    c = "hello c"
  }
}

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

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

'IaC > Terraform' 카테고리의 다른 글

[T102] 함수  (0) 2023.07.22
[T102] 조건식  (0) 2023.07.22
[T102] Output  (0) 2023.07.16
[T102] Local  (0) 2023.07.16
[T102] Variable  (0) 2023.07.16