문자열과 템플릿

문자열과 템플릿 (Strings and Templates)

문자열 리터럴은 Terraform에서 가장 복잡한 종류의 리터럴 표현식이면서, 가장 많이 사용되는 표현식이에요.

출처: 문서

본문

Terraform은 문자열에 대해 큰따옴표 문법과 "heredoc" 문법을 모두 지원해요. 두 문법 모두 값 보간과 텍스트 조작을 위한 템플릿 시퀀스를 지원해요.

큰따옴표 문자열 (Quoted Strings)

큰따옴표 문자열은 곧은 큰따옴표 문자(")로 구분된 일련의 문자예요.

"hello"

이스케이프 시퀀스

큰따옴표 문자열에서 백슬래시 문자는 이스케이프 시퀀스 역할을 하며, 다음 문자들이 이스케이프 동작을 선택해요:

시퀀스 대체
\n 줄바꿈
\r 캐리지 리턴
\t
\" 리터럴 따옴표 (문자열을 종료하지 않음)
\\ 리터럴 백슬래시
\uNNNN 기본 다국어 평면의 유니코드 문자 (NNNN은 4자리 16진수)
\UNNNNNNNN 보조 평면의 유니코드 문자 (NNNNNNNN은 8자리 16진수)

백슬래시를 사용하지 않는 두 가지 특별한 이스케이프 시퀀스도 있어요:

시퀀스 대체
$${ 보간 시퀀스를 시작하지 않는 리터럴 ${
%%{ 템플릿 지시자 시퀀스를 시작하지 않는 리터럴 %{

Heredoc 문자열

Terraform은 Unix 셸 언어에서 영감을 받은 "heredoc" 스타일의 문자열 리터럴을 지원하며, 여러 줄 문자열을 더 명확하게 표현할 수 있게 해줘요.

<<EOT
hello
world
EOT

heredoc 문자열은 다음으로 구성돼요:

  • 여는 시퀀스:
    • heredoc 마커(<< 또는 <<- — 두 개의 less-than 기호, 들여쓰기된 heredoc에는 선택적 하이픈)
    • 직접 고른 구분 단어
    • 줄바꿈
  • 여러 줄에 걸칠 수 있는 문자열의 내용
  • 직접 고른 구분 단어가 단독으로 있는 줄(들여쓰기된 heredoc에는 들여쓰기 허용)

줄 끝의 식별자와 함께 온 << 마커가 시퀀스를 시작해요. Terraform은 소개자에 주어진 식별자로만 구성된 줄을 찾을 때까지 다음 줄들을 처리해요.

위 예제에서 EOT가 선택된 식별자예요. 어떤 식별자도 허용되지만, 관례적으로 이 식별자는 모두 대문자이며 "end of"를 뜻하는 EO로 시작해요. 여기서 EOT는 "end of text"를 뜻해요.

JSON이나 YAML을 생성하는 데 "heredoc" 문자열을 사용하지 마세요. 대신 the jsonencode function이나 the yamlencode function을 사용해 Terraform이 유효한 JSON 또는 YAML 문법을 보장하도록 하세요.

example = jsonencode({
  a = 1
  b = "hello"
})

들여쓰기된 Heredoc (Indented Heredocs)

표준 heredoc 형식(위에 표시)은 모든 공백 문자를 리터럴 공백으로 취급해요. 각 줄이 공백으로 시작하지 않게 하려면 각 줄이 왼쪽 여백에 딱 맞아야 하는데, 들여쓰기된 블록 안의 표현식에는 불편할 수 있어요:

block {
  value = <<EOT
hello
world
EOT
}

이를 개선하기 위해 Terraform은 <<- 시퀀스로 시작하는 들여쓰기된 heredoc 문자열 변형도 받아들여요:

block {
  value = <<-EOT
  hello
    world
  EOT
}

이 경우 Terraform은 시퀀스 안의 줄들을 분석해 선행 공백이 가장 적은 줄을 찾은 다음, 모든 줄의 시작 부분에서 그만큼의 공백을 잘라내 다음과 같은 결과를 만들어요:

hello
  world

이스케이프 시퀀스

heredoc 문자열 표현식에서는 백슬래시 시퀀스가 이스케이프로 해석되지 않아요. 대신 백슬래시 문자는 리터럴로 해석돼요.

Heredoc은 백슬래시를 사용하지 않는 두 가지 특별한 이스케이프 시퀀스를 지원해요:

시퀀스 대체
$${ 보간 시퀀스를 시작하지 않는 리터럴 ${
%%{ 템플릿 지시자 시퀀스를 시작하지 않는 리터럴 %{

문자열 템플릿 (String Templates)

큰따옴표 및 heredoc 문자열 표현식 안에서 ${%{ 시퀀스는 템플릿 시퀀스를 시작해요. 템플릿은 표현식을 문자열 리터럴에 직접 임베드해 다른 값들로부터 문자열을 동적으로 구성할 수 있게 해줘요.

보간 (Interpolation)

${ ... } 시퀀스는 보간으로, 마커 사이에 주어진 표현식을 평가하고 그 결과를 필요하면 문자열로 변환한 다음 최종 문자열에 삽입해요:

"Hello, ${var.name}!"

위 예제에서 명명된 객체 var.name에 접근해 그 값을 문자열에 삽입해 "Hello, Juan!" 같은 결과를 만들어요.

지시자 (Directives)

%{ ... } 시퀀스는 지시자로, 조건부 결과와 컬렉션 반복을 허용하며 조건부 및 for 표현식과 유사해요.

다음 지시자가 지원돼요:

  • %{if <BOOL>}/%{else}/%{endif} 지시자는 불리언 표현식의 값에 따라 두 템플릿 중 하나를 선택해요:

    "Hello, %{ if var.name != "" }${var.name}%{ else }unnamed%{ endif }!"
    

    else 부분은 생략할 수 있으며, 조건식이 false를 반환하면 결과는 빈 문자열이 돼요.

  • %{for <NAME> in <COLLECTION>} / %{endfor} 지시자는 주어진 컬렉션이나 구조적 값의 요소들을 반복하며 각 요소에 대해 주어진 템플릿을 한 번씩 평가하고 결과를 연결해요:

    <<EOT
    %{ for ip in aws_instance.example[*].private_ip }
    server ${ip}
    %{ endfor }
    EOT
    

    for 키워드 바로 뒤에 주어진 이름은 임시 변수 이름으로 사용되며, 중첩 템플릿에서 참조할 수 있어요.

공백 제거 (Whitespace Stripping)

템플릿 지시자가 결과에 원치 않는 공백과 줄바꿈을 추가하지 않고 가독성을 위해 형식화될 수 있도록, 모든 템플릿 시퀀스는 여는 문자 바로 뒤 또는 끝 바로 앞에 선택적 스트립 마커(~)를 포함할 수 있어요. 스트립 마커가 있으면 템플릿 시퀀스는 (마커가 시작에 있으면) 시퀀스 앞의, 또는 (마커가 끝에 있으면) 뒤의 모든 리터럴 공백(공백과 줄바꿈)을 소비해요:

<<EOT
%{ for ip in aws_instance.example[*].private_ip ~}
server ${ip}
%{ endfor ~}
EOT

위 예제에서 각 지시자 뒤의 줄바꿈은 출력에 포함되지 않지만, server ${ip} 시퀀스 뒤의 줄바꿈은 유지돼 요소마다 한 줄만 생성돼요:

server 10.1.16.154
server 10.1.16.1
server 10.1.16.34

템플릿 지시자를 사용할 때는 항상 "heredoc" 문자열 리터럴 형식을 사용하고 가독성을 위해 템플릿을 여러 줄로 형식화하는 것을 권장해요. 큰따옴표 문자열 리터럴은 보통 보간 시퀀스만 포함해야 해요.

더 알아보기 (Learn more)