for 표현식
for 표현식 (for Expressions)
for 표현식은 다른 복합 타입 값을 변환해 복합 타입 값을 만드는 방식이에요. 입력 값의 각 요소는 결과에서 하나 또는 0개의 값에 대응할 수 있으며, 임의의 표현식을 사용해 각 입력 요소를 출력 요소로 변환할 수 있어요.
출처: 문서
본문
기본 사용법
예를 들어 var.list가 문자열 리스트라면 다음 표현식은 모두 대문자인 문자열 튜플을 만들어요:
[for s in var.list : upper(s)]
이 for 표현식은 var.list의 각 요소를 반복한 다음 s를 각각의 해당 요소로 설정한 채 upper(s) 표현식을 평가해요. 그런 다음 같은 순서로 그 표현식을 실행한 모든 결과를 담은 새 튜플 값을 만들어요.
입력 타입 (Input Types)
for 표현식의 입력(in 키워드 뒤에 주어짐)은 list, set, tuple, map, object 중 하나일 수 있어요.
위 예제는 임시 기호 s 하나만 있는 for 표현식을 보여줬지만, for 표현식은 각 항목의 키나 인덱스도 사용하기 위해 선택적으로 임시 기호 쌍을 선언할 수 있어요:
[for k, v in var.map : length(k) + length(v)]
위처럼 map이나 object 타입의 경우 k 기호는 현재 요소의 키나 속성 이름을 나타내요. 리스트와 튜플에서도 두 기호 형태를 사용할 수 있으며, 그 경우 추가 기호는 0부터 시작하는 각 요소의 인덱스예요. 관례적으로 더 구체적인 이름을 고르는 것이 도움이 되지 않는 한 i나 idx라는 기호 이름을 사용해요:
[for i, v in var.list : "${i} is ${v}"]
인덱스나 키 기호는 항상 선택적이에요. for 키워드 뒤에 단일 기호만 지정하면 그 기호는 항상 입력 컬렉션의 각 요소의 값을 나타내요.
결과 타입 (Result Types)
for 표현식 주변의 괄호 타입이 생성되는 결과 타입을 결정해요.
위 예제는 [와 ]를 사용하며 튜플을 생성해요. 대신 {와 }를 사용하면 결과는 객체이며 => 기호로 구분된 두 개의 결과 표현식을 제공해야 해요:
{for s in var.list : s => upper(s)}
이 표현식은 속성이 var.list의 원래 요소이고 대응 값이 대문자 버전인 객체를 생성해요. 예를 들어 결과 값은 다음과 같을 수 있어요:
{
foo = "FOO"
bar = "BAR"
baz = "BAZ"
}
for 표현식 단독으로는 객체 값이나 튜플 값만 생성할 수 있지만, Terraform의 자동 타입 변환 규칙 덕분에 list, map, set이 기대되는 위치에서 결과를 보통 사용할 수 있어요.
요소 필터링 (Filtering Elements)
for 표현식은 선택적 if 절을 포함해 소스 컬렉션에서 요소를 필터링할 수 있으며, 소스 값보다 적은 요소를 가진 값을 생성해요:
[for s in var.list : upper(s) if s != ""]
for 표현식에서 컬렉션을 필터링하는 일반적인 이유는 하나의 소스 컬렉션을 어떤 기준에 따라 두 개의 별도 컬렉션으로 나누는 것이에요. 예를 들어 입력 var.users가 각각 is_admin 속성을 가진 객체들의 맵이라면 관리자/비관리자 객체가 있는 별도의 맵을 생성하고 싶을 수 있어요:
variable "users" {
type = map(object({
is_admin = bool
}))
}
locals {
admin_users = {
for name, user in var.users : name => user
if user.is_admin
}
regular_users = {
for name, user in var.users : name => user
if !user.is_admin
}
}
요소 순서 (Element Ordering)
for 표현식은 순서가 없는 타입(map, object, set)에서 순서가 있는 타입(list, tuple)으로 변환할 수 있으므로, Terraform은 순서가 없는 컬렉션의 요소에 대해 암시적 순서를 선택해야 해요.
map과 object의 경우 Terraform은 요소를 키나 속성 이름으로 사전순 정렬해요.
문자열 set의 경우 Terraform은 요소를 값으로 사전순 정렬해요.
다른 타입의 set의 경우 Terraform은 향후 버전에서 바뀔 수 있는 임의의 순서를 사용해요. 구성의 다른 곳에서 결과가 순서가 없다는 것을 명확히 하기 위해 표현식 결과를 set으로 변환하는 것을 권장해요. the toset function을 사용해 for 표현식 결과를 간결하게 set 타입으로 변환할 수 있어요.
toset([for e in var.set : e.example])
결과 그룹화 (Grouping Results)
결과 타입이 객체({와 } 구분 기호 사용)라면 보통 주어진 키 표현식이 결과의 모든 요소에 걸쳐 유일해야 하며, 그렇지 않으면 Terraform이 오류를 반환해요.
때때로 결과 키가 유일하지 않으므로 그 상황을 지원하기 위해 Terraform은 키당 여러 요소를 지원하도록 결과를 변경하는 특별한 그룹화 모드를 지원해요.
그룹화 모드를 활성화하려면 값 표현식 뒤에 ... 기호를 추가하세요. 예를 들어:
variable "users" {
type = map(object({
role = string
}))
}
locals {
users_by_role = {
for name, user in var.users : user.role => name...
}
}
위는 모듈이 각각 단일 "role"을 가진 여러 사용자를 설명하는 맵을 기대하는 상황을 나타내며, 맵 키는 사용자 이름이에요. 사용자 이름은 입력의 맵 키이므로 유일함이 보장되지만, 여러 사용자가 하나의 역할 이름을 공유할 수 있어요.
local.users_by_role 표현식은 입력 맵을 반전시켜 키가 역할 이름이고 값이 사용자 이름이 되도록 하지만, (name 뒤의 ... 때문에) 표현식이 그룹화 모드에 있으므로 결과는 문자열 리스트의 맵이 돼요:
{
"admin": [
"ps",
],
"maintainer": [
"am",
"jb",
"kl",
"ma",
],
"viewer": [
"st",
"zq",
],
}
요소 순서 규칙 때문에 Terraform은 for 표현식 평가의 일부로 사용자를 사용자 이름 기준 사전순으로 정렬하므로, 각 역할에 연결된 사용자 이름은 그룹화 후 사전순으로 정렬돼요.
반복 구성 블록 (Repeated Configuration Blocks)
for 표현식 메커니즘은 표현식 안에서 다른 컬렉션 값으로부터 컬렉션 값을 구성하는 것이며, 이를 복합 값을 기대하는 개별 리소스 인자에 할당할 수 있어요.
일부 리소스 타입은 또한 중첩 블록 타입을 정의하며, 이는 보통 포함하는 리소스에 어떤 식으로든 속하는 별도의 객체를 나타내요. for 표현식으로 중첩 블록을 동적으로 생성할 수는 없지만, dynamic 블록으로 리소스의 중첩 블록을 동적으로 생성할 수 있어요.
더 알아보기 (Learn more)
- Splat 표현식 (Splat Expressions): 리스트 변환 축약
- dynamic 블록 (dynamic Blocks): 동적 중첩 블록
- toset 함수: set 변환
- 타입과 값 (Types and Values): 복합 타입