명명된 값에 대한 참조
명명된 값에 대한 참조 (References to Named Values)
실습: 동적 식 만들기 튜토리얼을 따라 해 보세요. Terraform은 여러 종류의 명명된 값(named value)을 제공하며, 각 이름은 그와 연관된 값을 참조하는 식이에요. 이 값들은 독립적인 식으로 사용하거나 다른 식과 결합해 새 값을 계산할 수 있어요. 이 페이지에서는 리소스, 입력 변수, 로컬 값, 모듈 출력, 데이터 소스 등을 비롯한 다양한 명명된 값의 종류와 사용법을 다룰게요.
출처: 문서
본문
실습: 동적 식 만들기 튜토리얼을 따라 해 보세요.
Terraform은 여러 종류의 명명된 값을 제공해요. 각 이름은 그와 연관된 값을 참조하는 식이에요. 이 값들은 독립적인 식으로 사용하거나 다른 식과 결합해 새 값을 계산할 수 있어요.
명명된 값의 종류 (Types of Named Values)
Terraform에서 사용 가능한 주요 명명된 값의 종류는 다음과 같아요:
- 리소스 (Resources)
- 입력 변수 (Input variables)
- 로컬 값 (Local values)
- 자식 모듈 출력 (Child module outputs)
- 데이터 소스 (Data sources)
- 파일시스템 및 워크스페이스 정보 (Filesystem and workspace info)
- 블록-로컬 값 (Block-local values)
아래 섹션에서 각 명명된 값의 종류를 자세히 설명해요.
이 이름들 중 많는 점으로 구분된 경로를 사용하며, 이것이 오브젝트 값 요소의 속성 표기법과 닮았지만, 실제 오브젝트로 구현되지 않아요. 즉 정확히 작성한 대로 사용해야 해요. 대괄호 표기법으로 점으로 구분된 경로를 대체할 수 없고, 명명된 개체의 "부모 오브젝트"를 반복할 수도 없어요. 예를 들어 모든 AWS 인스턴스 리소스를 반복하기 위해 for 식에서 aws_instance를 사용할 수 없어요.
리소스 (Resources)
<RESOURCE TYPE>.<NAME>은 주어진 타입과 이름의 관리 리소스를 나타내요.
리소스 참조의 값은 리소스가 count나 for_each를 사용하는지에 따라 달라질 수 있어요:
- 리소스가
count나for_each를 사용하지 않으면 참조 값은 오브젝트예요. 리소스의 속성은 오브젝트의 요소이며, 점 또는 대괄호 표기법으로 접근할 수 있어요. - 리소스에
count인자가 설정되어 있으면 참조 값은 그 인스턴스들을 나타내는 오브젝트의 리스트예요. - 리소스에
for_each인자가 설정되어 있으면 참조 값은 그 인스턴스들을 나타내는 오브젝트의 맵이에요.
아래에 나열된 다른 패턴과 일치하지 않는 명명된 값은 Terraform이 관리 리소스에 대한 참조로 해석해요.
리소스 참조를 사용하는 방법에 대한 자세한 내용은 아래 리소스 속성에 대한 참조를 참고해요.
입력 변수 (Input Variables)
var.<NAME>은 주어진 이름의 입력 변수의 값이에요.
변수 선언의 일부로 타입 제약(type 인자)이 있으면 Terraform은 호출자가 준 값을 타입 제약에 맞게 자동으로 변환해요.
그래서 var.를 사용한 참조는 호출자가 자동 변환된 다른 타입의 값을 제공했더라도 항상 타입 제약에 맞는 값을 만들어 낸다고 안전하게 가정할 수 있어요.
특히 변수를 특정 속성을 가진 오브젝트 타입으로 정의하면, 호출자가 실제로 추가 속성을 가진 값을 전달했더라도 모듈의 다른 곳의 식에서는 그 특정 속성들만 사용 가능해요. 모듈의 다른 곳에서 사용하려는 모든 속성을 타입 제약에 정의해야 해요.
로컬 값 (Local Values)
local.<NAME>은 주어진 이름의 로컬 값이에요. 로컬 값은 순환 의존성을 만들지 않는 한 같은 locals 블록 안에서도 다른 로컬 값을 참조할 수 있어요.
자식 모듈 출력 (Child Module Outputs)
module.<NAME>은 a module 블록의 결과를 나타내는 값이에요.
해당 module 블록에 count도 for_each도 설정되어 있지 않으면 그 값은 자식 모듈에 정의된 각 출력 값에 대한 속성을 하나씩 가진 오브젝트예요. 모듈의 출력 값 중 하나에 접근하려면 module.<NAME>.<OUTPUT NAME>을 사용해요.
해당 module이 for_each를 사용하면 그 값은 for_each 식의 키에 대응하는 키와, 각각 자식 모듈에 정의된 각 출력 값에 대한 속성을 하나씩 가진 오브젝트인 값들의 맵이에요. 각 값은 하나의 모듈 인스턴스를 나타내요.
해당 모듈이 count를 사용하면 결과는 for_each와 비슷하지만, 값이 요청된 수의 요소를 가진 리스트이고 각 요소가 하나의 모듈 인스턴스를 나타내요.
데이터 소스 (Data Sources)
data.<TYPE>.<NAME>은 주어진 데이터 소스 타입과 이름의 데이터 리소스를 나타내는 오브젝트예요. 리소스에 count 인자가 설정되어 있으면 값은 그 인스턴스들을 나타내는 오브젝트의 리스트예요. 리소스에 for_each 인자가 설정되어 있으면 값은 그 인스턴스들을 나타내는 오브젝트의 맵이에요.
자세한 내용은 리소스 속성에 대한 참조를 참고해요. 이 내용은 참조가 데이터 리소스용임을 표시하는 data. 접두사가 추가된 것을 제외하면 데이터 리소스에도 동일하게 적용돼요.
파일시스템 및 워크스페이스 정보 (Filesystem and Workspace Info)
다음 값들을 사용할 수 있어요:
path.module은 식이 배치된 모듈의 파일시스템 경로예요.path.module은 원격 또는 로컬 모듈 소스를 사용하는지에 따라 다른 동작을 만들 수 있으므로 쓰기 연산에서 사용하는 것을 권장하지 않아요. 로컬 모듈을 여러 번 호출하면 같은 소스 디렉터리를 사용하므로 호출할 때마다path.module의 데이터를 덮어써요. 이는 경쟁 조건(race condition)과 예기치 않은 결과를 초래할 수 있어요.path.root는 구성의 루트 모듈의 파일시스템 경로예요.path.cwd는-chdir인자를 적용하기 전에 Terraform을 실행한 원래 작업 디렉터리의 파일시스템 경로예요. 이 경로는 파일시스템 구조에 대한 세부 정보를 포함하는 절대 경로예요. 또한 Terraform이 루트 모듈 디렉터리 외의 디렉터리에서 실행되는 일부 고급 사례에서도 유용해요. 가능하면path.cwd보다path.root나path.module을 사용할 것을 권장해요.terraform.workspace는 현재 선택된 워크스페이스의 이름이에요.
이 섹션의 값들은 구성이 적용되는 맥락에 대한 정보를 포함하므로 모듈의 이식성이나 조합성을 의도치 않게 해칠 수 있어 주의해서 사용해요.
예를 들어 path.cwd를 직접 사용해 리소스 인자의 경로를 채우면, 나중에 다른 디렉터리나 다른 디렉터리 구조의 다른 컴퓨터에서 같은 구성을 적용할 때 프로바이더가 경로가 여전히 같은 파일을 가리키더라도 경로의 변경을 적용할 변경으로 간주해요.
마찬가지로 공유 모듈에서 이름 공간 지정의 한 형태로 이 값들 중 어떤 것을 사용하면, 예를 들어 전역적으로 고유한 오브젝트 이름의 접두사로 terraform.workspace를 사용하면 같은 구성에서 모듈을 두 번 이상 호출하지 못할 수 있어요.
path.module을 제외하면 이 섹션의 값들은 구성의 루트 모듈에서만 사용할 것을 권장해요. 고유한 이름을 만들기 위한 접두사가 필요한 공유 모듈을 작성한다면 모듈의 입력 변수를 정의하고 호출하는 모듈이 접두사를 정의하도록 해요. 호출하는 모듈은 적절하다면 terraform.workspace를 사용하거나 그렇지 않으면 다른 값을 사용해 정의할 수 있어요:
module "example" {
# ...
name_prefix = "app-${terraform.workspace}"
}
블록-로컬 값 (Block-Local Values)
특정 블록의 본문이나 다른 특정 맥락 안에서는 위에 나열된 전역 값 외에도 다른 명명된 값이 사용 가능해요. 이런 로컬 이름은 나타나는 특정 맥락의 문서에서 설명해요. 가장 흔한 로컬 이름 중 일부는 다음과 같아요:
- the
count메타-인자를 사용하는 리소스의count.index. - the
for_each메타-인자를 사용하는 리소스의each.key/each.value. - 프로비저너와 connection 블록의
self.
참고: 로컬 이름은 문서에서 종종 변수나 임시 변수라고 불려요. 이것들은 입력 변수가 아니라 값을 일시적으로 나타내는 임의의 이름일 뿐이에요.
이 섹션의 이름은 최상위 구성 블록에만 관련돼요. dynamic 블록을 사용해 resource와 data 블록 안에 리소스-타입-특정 중첩 블록을 동적으로 생성한다면 각 요소의 키와 값을 다르게 참조해야 해요. 자세한 내용은 dynamic 블록 문서를 참고해요.
명명된 값과 의존성 (Named Values and Dependencies)
리소스와 모듈 호출 같은 구성은 블록 본문에서 종종 명명된 값에 대한 참조를 사용하며, Terraform은 이 식들을 분석해 객체 사이의 의존성을 자동으로 추론해요. 예를 들어 리소스 인자에서 다른 관리 리소스를 참조하는 식은 두 리소스 사이에 암시적 의존성을 만들어요.
리소스 속성에 대한 참조 (References to Resource Attributes)
가장 흔한 참조 유형은 resource 또는 data 블록으로 선언된 리소스의 속성에 대한 참조예요. 이런 블록의 내용 자체가 꽤 복잡할 수 있으므로, 이 내용을 참조하는 식도 복잡할 수 있어요.
다음 예시 리소스 블록을 살펴봐요:
resource "aws_instance" "example" {
ami = "ami-abc123"
instance_type = "t2.micro"
ebs_block_device {
device_name = "sda2"
volume_size = 16
}
ebs_block_device {
device_name = "sda3"
volume_size = 20
}
}
aws_instance 문서는 이 리소스 타입에 지원되는 모든 인자와 중첩 블록을 나열하고, 이 리소스 타입이 내보내는 여러 속성도 나열해요. 이 모든 서로 다른 리소스 타입 스키마 구성은 다음과 같이 참조에 사용할 수 있어요:
- 구성에 설정된
ami인자는 참조 식aws_instance.example.ami로 다른 곳에서 사용할 수 있어요. - 이 리소스 타입이 내보내는
id속성은 같은 구문으로 읽을 수 있으며,aws_instance.example.id가 돼요. ebs_block_device중첩 블록의 인자는 스플랫 식으로 접근할 수 있어요. 예를 들어 모든device_name값의 리스트를 얻으려면aws_instance.example.ebs_block_device[*].device_name을 사용해요.- 이 특정 리소스 타입의 중첩 블록은 내보내는 속성이 없지만,
ebs_block_device에 문서화된id속성이 있다면 그 리스트도aws_instance.example.ebs_block_device[*].id와 같이 접근할 수 있어요. - 때로 중첩 블록은 각 블록을 식별하는 논리적 키를 받도록 정의되는데, 이는 리소스 자체의 이름과 비슷한 목적을 제공하며 식에서 그 단일 블록을 편리하게 참조하는 방법을 제공해요.
aws_instance에 이러한 키를 받는 가상의 중첩 블록 타입device가 있다면 구성에서는 다음과 같을 거예요:
device "foo" {
size = 2
}
device "bar" {
size = 4
}
키가 있는 블록 안의 인자는 aws_instance.example.device["foo"].size처럼 인덱스 구문으로 접근할 수 있어요. 레이블이 있는 중첩 블록 타입의 특정 인자 값의 맵을 얻으려면 for 식을 사용해요: {for k, device in aws_instance.example.device : k => device.size}.
리소스에 count 인자가 설정되어 있으면 리소스 자체가 단일 오브젝트가 아니라 인스턴스 오브젝트의 리스트가 돼요. 이 경우 스플랫 식이나 인덱스 구문으로 인스턴스의 속성에 접근해요:
aws_instance.example[*].id는 각 인스턴스의 모든 id의 리스트를 반환해요.aws_instance.example[0].id는 첫 번째 인스턴스의 id만 반환해요.
리소스에 for_each 인자가 설정되어 있으면 리소스 자체가 단일 오브젝트가 아니라 인스턴스 오브젝트의 맵이 되고, 인스턴스의 속성은 키로 지정하거나 for 식으로 접근할 수 있어요.
aws_instance.example["a"].id는 "a" 키를 가진 리소스의 id를 반환해요.[for value in aws_instance.example: value.id]는 각 인스턴스의 모든 id의 리스트를 반환해요.
count와 달리 스플랫 식은 리스트 값에 작용해야 하므로 for_each로 관리되는 리소스에는 직접 적용할 수 없다는 점을 주의하세요. 하지만 values() 함수를 사용해 인스턴스를 리스트로 추출하고 그 리스트 값을 스플랫 식에 사용할 수 있어요:
민감한 리소스 속성 (Sensitive Resource Attributes)
리소스 타입의 스키마를 정의할 때 프로바이더 개발자는 특정 속성을 민감으로 표시할 수 있으며, 이 경우 Terraform은 해당 속성이 포함된 plan을 렌더링할 때 실제 값 대신 자리표시자 표시인 (sensitive value)를 보여줘요.
민감으로 표시된 프로바이더 속성은 민감으로 선언된 입력 변수와 비슷하게 동작하며, Terraform은 plan과 apply 메시지에서 값을 숨기고 그 값에서 파생한 다른 값도 민감으로 숨겨요.
하지만 Terraform이 민감한 변수를 공개할 수 있는 경우에서 설명한 대로 그 동작에는 몇 가지 제한이 있어요.
리소스 속성의 민감한 값을 출력 값의 일부로 사용하면 Terraform은 출력 값 자체도 민감으로 표시하도록 요구해, 그것을 내보낼 의도가 있었음을 확인하게 해요.
Terraform은 여전히 민감한 값을 상태에 기록하므로, 상태 데이터에 접근할 수 있는 사람은 민감한 값을 평문으로 접근할 수 있어요. 자세한 내용은 민감한 데이터 관리를 참고해요.
참고: 민감한 리소스 속성에서 파생된 값을 그 자체로 민감으로 취급하는 것은 Terraform v0.15에서 도입됐어요. 이전 버전의 Terraform은 민감한 리소스 속성의 직접 값을 숨기지만, 민감한 리소스 속성에서 파생된 다른 값은 자동으로 숨기지 않아요.
아직 알 수 없는 값 (Values Not Yet Known)
Terraform이 구성을 적용할 변경 사항 집합을 계획할 때, 일부 리소스 속성 값은 원격 시스템이 동적으로 결정하므로 즉시 채울 수 없어요. 예를 들어 특정 원격 오브젝트 타입이 생성 시 생성된 고유 id를 할당받으면 Terraform은 오브젝트가 생성될 때까지 이 id의 값을 예측할 수 없어요.
Terraform은 plan 단계에서 예측할 수 없는 정보에 특별한 알 수 없는 값(unknown value) 자리표시자를 사용해요. Terraform 언어는 식에서 알 수 없는 값을 자동으로 처리해요. 예를 들어 알 수 없는 값에 알려진 값을 더하면 자동으로 알 수 없는 값이 결과로 나와요.
하지만 알 수 없는 값이 중요한 영향을 미치는 상황도 몇 가지 있어요:
- 리소스의
count메타-인자는 알 수 없을 수 없어요. 생성할 인스턴스 수를 결정하려면 plan 단계에서 평가되어야 하기 때문이에요. - 데이터 리소스의 구성에 알 수 없는 값이 사용되면 그 데이터 리소스는 plan 단계에서 읽을 수 없으므로 apply 단계로 지연돼요. 이 경우 데이터 리소스의 결과도 알 수 없는 값이 돼요.
module블록의 인자에 알 수 없는 값이 할당되면 자식 모듈 내의 해당 입력 변수에 대한 모든 참조가 그 알 수 없는 값을 사용해요.- 출력 값의
value인자에 알 수 없는 값이 사용되면 부모 모듈에서 그 출력 값에 대한 모든 참조가 그 알 수 없는 값을 사용해요. - Terraform은 가능하면 알 수 없는 값이 적절한 타입인지 검증하려고 시도하지만, 이런 값의 잘못된 사용은 apply 단계까지 감지되지 않아 apply가 실패할 수 있어요.
알 수 없는 값은 terraform plan 출력에서 (known after apply)로 나타나요.