[Terraform] 스터디 2주차. (2) 기본 사용법-3
Terraform 기초 실습 스터디를 진행하고 있으며, 커리큘럼 2주차에 해당하는 내용입니다.
* [테라폼으로 시작하는 IaC] 도서 참조
이전 포스팅에서 테라폼을 구성하는 기본 코드 블록들에 대해서 알아보았다.
이제 테라폼에서 활용되는 반복문에 대해 익혀보도록 하자.
반복문
list 형태의 값 목록이나 Key-Value 형태의 문자열 집합인 데이터가 있는 경우 동일한 내용에 대해 테라폼 구성 정의를 반복적으로 하지 않고, 반복문을 통해 관리할 수 있다.
반복문 1. count
리소스 또는 모듈 블록에 count 값이 정수인 인수가 포함된 경우 선언된 정수 값만큼 리소스나 모듈을 생성하게 된다.
count 에서 생성되는 참조값 은 count.index 이며, 반복하는 경우 0부터 1씩 증가하여 인덱스가 부여된다.
count 를 사용하는 경우 반복되는 정의로 인한 문제를 주의해야 한다.
다음 main.tf 파일에 count.index 값을 추가하여 수행 결과를 확인해보자.

때로는 여러 리소스나 모듈의 count 로 지정되는 수량이 동일해야 하는 경우가 있다.
이 경우 count 에 부여되는 정수 값을 외부 변수 에 식별되도록 구성할 수 있다.
list 형태의 배열을 활용한 반복문 동작 구성의 예시이다.

count 로 생성되는 리소스: <리소스 타입>.<이름>[<인덱스 번호>], 모듈 의 경우: module.<모듈 이름>[<인덱스 번호>] 로 해당 리소스 값을 참조한다.
또한 외부 변수가 list 타입인 경우, 중간에 값이 삭제되면 인덱스가 줄어들어 의도했던 중간 값에 대한 리소스만 삭제되는 것이 아니라, 이후 정의된 리소스들도 삭제되고 재생성된다.
반복문 2. for_each *
리소스 또는 모듈 블록에서 for_each 에 입력된 데이터 형태가 map or set 이면, 선언된 key 값 개수만큼 리소스를 생성하게 된다.
다음 main.tf 파일에 for_each 값을 활용하여 apply 를 실행해보자.
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"
}
반복문 3. for
for문은 복합 형식 값의 형태를 변환하는 데 사용된다.
예를 들어 list 값의 포맷을 변경하거나 특정 접두사(perfix) 를 추가할 수도 있고, output 에 원하는 형태를 표현할 수도 있다.
list 유형에 대한 for 구문 처리의 몇 가지 예를 확인하기 위해 main.tf 를 작성하고 output 을 확인해보자.
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 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"]
}
반복문 4. dynamic
리소스 같은 테라폼 구성에서 count 나 for_each 구문을 사용한 리소스 전체를 여러 개 생성하는 것 외에도
리소스 내에 선언되는 구성 블록을 다중으로 작성해야 하는 경우가 있다.
dynamic 블록을 작성하려면, 기존 블록의 속성 이름을 dynamic 블록의 이름으로 선언하고
기존 블록 속성에 정의되는 내용을 content 블록에 작성한다.
variable "names" {
default = {
a = "hello a"
b = "hello b"
c = "hello c"
}
}
data "archive_file" "dotfile" {
type = "zip"
output_path = "${path.module}/dotfiles.zip"
dynamic "source" {
for_each = var.names
content {
content = source.value
filename = "${path.module}/${source.key}.txt"
}
}
}