3.5 데이터 소스
- Terraform에서는 데이터 소스를 사용하여 테라폼 코드 외부에서 정의된 리소스나 저장된 정보를 참조할 수 있습니다.
- 이를 통해 기존 리소스를 활용하거나 외부 데이터를 가져와서 테라폼 코드 내에서 사용할 수 있습니다.
데이터 소스 구성
- 데이터 소스 블록은 data로 시작하며, 리소스 블록과 유사하게 구성됩니다.
- 데이터 소스 유형은 '프로바이더_리소스유형' 형태로 정의됩니다.
data "local_file" "abc" {
filename = "${path.module}/abc.txt"
}
- 데이터 소스를 정의할 때 사용할 수 있는 메타인수는 다음과 같습니다
- depends_on: 종속성을 선언하여 특정 리소스의 생성 시점을 정의합니다.
- count: 여러 리소스를 생성합니다.
- for_each: map 또는 set 타입의 데이터 배열을 기반으로 여러 리소스를 생성합니다.
- lifecycle: 리소스의 수명주기를 관리합니다.
- 실습
# 실습을 위한 abc.txt 파일 생성
echo "t101 study - 2week" > abc.txt
# 테라폼 명령어 실행
terraform init && terraform plan && terraform apply -auto-approve
terraform state list
# 테라폼 콘솔에서 데이터 소스 참조 확인
terraform console
> data.local_file.abc
...
> data.local_file.abc.filename
...
> data.local_file.abc.content
...
> data.local_file.abc.id
...
exit
데이터 소스 속성 참조
- 데이터 소스를 테라폼에서 참조하는 방식은 리소스와 구별되게 data가 앞에 붙습니다. 속성 값은 다음과 같이 접근할 수 있습니다.
# Terraform Code
data "<리소스 유형>" "<이름>" {
<인수> = <값>
}
# 데이터 소스 참조
data.<리소스 유형>.<이름>.<속성>
AWS 가용영역 인수 정의 예시
- AWS 가용영역을 데이터 소스로 가져와 서브넷의 가용영역을 설정하는 예시입니다
# Declare the data source
data "aws_availability_zones" "available" {
state = "available"
}
resource "aws_subnet" "primary" {
availability_zone = data.aws_availability_zones.available.names[0]
# e.g. ap-northeast-2a
}
resource "aws_subnet" "secondary" {
availability_zone = data.aws_availability_zones.available.names[1]
# e.g. ap-northeast-2b
}
- 아래 문서에서 데이터 소스로 가져오기 위한 조건인 인수는 Argument로 표현되어 있고, 가져온 데이터 소스의 내용은 Attributes에 안내되어 있다
데이터 소스 속성 참조 확인
- main.tf 파일 수정
data "aws_availability_zones" "seoul" {
state = "available"
}
- 테라폼 명령어 실행
terraform init -upgrade && terraform plan && terraform apply -auto-approve
terraform state list
- 데이터 소스 속성 확인
terraform state show data.aws_availability_zones.seoul
- 테라폼 콘솔에서 데이터 소스 참조 확인
terraform console
> data.aws_availability_zones.seoul
...
> data.aws_availability_zones.seoul.id
...
> data.aws_availability_zones.seoul.names
...
> data.aws_availability_zones.seoul.zone_ids
...
exit
# Tip. terraform console 값 echo로 확인
echo "data.aws_availability_zones.seoul" | terraform console
echo "data.aws_availability_zones.seoul.names" | terraform console
echo "data.aws_availability_zones.seoul.names[0]" | terraform console
echo "data.aws_availability_zones.seoul.names[1]" | terraform console
echo "data.aws_availability_zones.seoul.zone_ids[0]" | terraform console
- main.tf 파일 코드 수정
resource "local_file" "abc" {
content = "123!"
filename = "${path.module}/abc.txt"
}
data "local_file" "abc" {
filename = local_file.abc.filename
}
resource "local_file" "def" {
content = data.local_file.abc.content
filename = "${path.module}/def.txt"
}
- 테라폼 명령어 실행 및 결과 확인
terraform apply -auto-approve
terraform state list
- 파일 확인
- 그래프 확인
- 테라폼 콘솔에서 데이터 소스 참조 확인
3.6 입력 변수 Variable
- 입력 변수는 인프라를 구성하는 데 필요한 속성 값을 정의하여 코드의 변경 없이 여러 인프라를 생성하는 데 목적이 있습니다. 테라폼에서는 이를 입력 변수(Input Variables)로 정의합니다.
변수 선언 방식
- 변수는 variable로 시작하는 블록으로 구성되며, 이 블록 뒤의 이름 값은 동일 모듈 내에서 고유해야 합니다. 변수를 선언한 후, 코드 내에서 해당 변수를 참조할 수 있습니다.
variable "<이름>" {
<인수> = <값>
}
variable "image_id" {
type = string
}
- 다음 예약 변수 이름은 변수로 사용할 수 없습니다.
- source, version, providers, count, for_each, lifecycle, depends_on, locals
- 변수 정의 시 사용 가능한 메타인수
- default: 기본값을 설정합니다. 여러 방법으로 값을 전달하지 않으면 기본값이 사용됩니다. 기본값이 없으면 대화식으로 사용자에게 값을 물어봅니다.
- type: 변수에 허용되는 값 유형을 정의합니다. 지원되는 유형은 string, number, bool, list, map, set, object, tuple 등이 있습니다. 유형을 지정하지 않으면 any 유형으로 간주됩니다.
- description: 입력 변수의 설명을 작성합니다.
- validation: 변수 선언의 제약조건을 추가해 유효성 검사 규칙을 정의합니다.
- sensitive: 민감한 변수 값임을 알리며 테라폼 출력문에서 값 노출을 제한합니다. 주로 암호와 같은 민감 데이터를 다룰 때 사용합니다.
- nullable: 변수에 값이 없어도 됨을 지정합니다.
변수 유형
- 기본 유형
- string: 문자열
- number: 숫자
- bool: true 또는 false
- any: 모든 유형
- 집합 유형
- list (<유형>): 인덱스 기반 집합
- map (<유형>): 값 = 속성 기반 집합, 키값 기준 정렬
- set (<유형>): 값 기반 집합, 정렬 키값 기준 정렬
- object ({<인수 이름>=<유형>, …}): 복잡한 구조체
- tuple ([<유형>, …]): 순서가 있는 복합 데이터 타입
- list와 set은 선언하는 형태가 비슷하지만 참조 방식이 인덱스(list)와 키(set)로 차이가 있습니다. map와 set은 선언된 값이 정렬되는 특징을 가집니다.
입력 변수 사용 예시
- number 유형의 변수 선언 예시
variable "number_example" {
description = "An example of a number variable in Terraform"
type = number
default = 42
}
- list 유형의 변수 선언 예시
variable "list_example" {
description = "An example of a list in Terraform"
type = list
default = ["a", "b", "c"]
}
- 리스트의 모든 항목이 number인 list 예시
variable "list_numeric_example" {
description = "An example of a numeric list in Terraform"
type = list(number)
default = [1, 2, 3]
}
- 모든 값이 string인 map 예시
variable "map_example" {
description = "An example of a map in Terraform"
type = map(string)
default = {
key1 = "value1"
key2 = "value2"
key3 = "value3"
}
}
- object 또는 tuple을 사용한 복잡한 구조적 유형 예시
variable "object_example" {
description = "An example of a structural type in Terraform"
type = object({
name = string
age = number
tags = list(string)
enabled = bool
})
default = {
name = "value1"
age = 42
tags = ["a", "b", "c"]
enabled = true
}
}
- main.tf 파일 코드 수정
variable "string" {
type = string
description = "var String"
default = "myString"
}
variable "number" {
type = number
default = 123
}
variable "boolean" {
default = true
}
variable "list" {
default = [
"google",
"vmware",
"amazon",
"microsoft"
]
}
output "list_index_0" {
value = var.list[0]
}
output "list_all" {
value = [
for name in var.list : upper(name)
]
}
variable "map" { # Sorting
default = {
aws = "amazon",
azure = "microsoft",
gcp = "google"
}
}
variable "set" { # Sorting
type = set(string)
default = [
"google",
"vmware",
"amazon",
"microsoft"
]
}
variable "object" {
type = object({ name = string, age = number })
default = {
name = "abc"
age = 12
}
}
variable "tuple" {
type = tuple([string, number, bool])
default = ["abc", 123, true]
}
variable "ingress_rules" { # optional (>= Terraform 1.3.0)
type = list(object({
port = number,
description = optional(string),
protocol = optional(string, "tcp"),
}))
default = [
{ port = 80, description = "web" },
{ port = 53, protocol = "udp" }
]
}
- 확인
terraform init && terraform plan && terraform apply -auto-approve
terraform state list
terraform output
유효성 검사
- 변수 블록 내 validation 블록에서 정의되며, 사용자가 지정한 유효성 검사를 수행합니다.
- condition: validation 블록 내에 위치하며, true 또는 false를 반환하는 조건을 지정합니다. 이 조건은 유효성 검사를 통과할지 여부를 결정합니다.
- error_message: condition이 false를 반환할 경우 출력되는 메시지를 정의합니다. 즉, 유효성 검사에 실패했을 때 사용자에게 보여줄 오류 메시지입니다.
- regex 함수: 문자열에 대해 정규식을 적용하여 일치하는 부분을 반환합니다. 이 함수는 유효성 검사에서 정규식 불일치를 검출하는 데 사용될 수 있습니다.
- can 함수: regex 함수와 함께 사용하여, 정규식에 일치하지 않는 경우 오류를 검출할 수 있습니다. 즉, 문자열이 정해진 패턴에 맞지 않을 때 오류를 발생시킬 수 있습니다.
- 변수 블록 내에서 여러 개의 validation 블록을 중복하여 선언할 수 있습니다. 이는 여러 개의 유효성 검사를 순서대로 적용할 수 있음을 의미합니다.
- main.tf 파일 코드 수정
variable "image_id" {
type = string
description = "The id of the machine image (AMI) to use for the server."
validation {
condition = length(var.image_id) > 4
error_message = "The image_id value must exceed 4."
}
validation {
# regex(...) fails if it cannot find a match
condition = can(regex("^ami-", var.image_id))
error_message = "The image_id value must starting with \"ami-\"."
}
}
- 확인 - 4자 미만 & ami- 접두사가 없는 image_id를 입력한 경우
# 4자 미만 & "ami-" 접두사가 없는 image_id를 입력한 경우
terraform apply -auto-approve
var.image_id
The id of the machine image (AMI) to use for the server.
Enter a value: ami
...
- 확인 - 4자 미만의 image_id를 입력한 경우
# 4자 미만의 image_id를 입력한 경우#
terraform apply -auto-approve
var.image_id
The id of the machine image (AMI) to use for the server.
Enter a value: ami-
...
- 확인 - 유효한 image_id를 입력한 경우
# 유효성 검사 만족
terraform apply -auto-approve
var.image_id
The id of the machine image (AMI) to use for the server.
Enter a value: ami-12345678
...
변수 참조
- Terraform에서 변수는 var.<이름> 형식으로 코드 내에서 참조됩니다.
- main.tf 파일 코드 수정
variable "my_password" {}
resource "local_file" "abc" {
content = var.my_password
filename = "${path.module}/abc.txt"
}
- 실행
# 초기화 및 적용
terraform init -upgrade && terraform apply -auto-approve
...
var.my_password
Enter a value: qwe123
...
# 상태 확인
terraform state list
terraform state show local_file.abc
# 파일 내용 확인
cat abc.txt ; echo
# 변경 및 재적용
terraform apply -auto-approve
var.my_password
Enter a value: t101mypss
...
# 변경된 파일 내용 확인
cat abc.txt ; echo
민감한 변수 취급
- Terraform에서는 변수를 민감한 값으로 표시할 수 있습니다. 이는 보안상의 이유로 변수 값을 출력할 때 가려진(sensitive) 형태로 나타나도록 만드는 기능입니다.
- 아 예시에서 sensitive = true는 my_password 변수가 민감한 정보를 포함하고 있음을 선언합니다.
variable "my_password" {
default = "password"
sensitive = true
}
resource "local_file" "abc" {
content = var.my_password
filename = "${path.module}/abc.txt"
}
- Terraform에서 terraform apply나 terraform state show 명령어를 사용할 때, 민감한 변수의 값은 출력에서 가려집니다. (sensitive value)로 표시됩니다.
- terraform.tfstate 파일에는 민감한 변수 값이 평문으로 기록되므로 State 파일의 보안에 유의해야 합니다.
# 민감한 값 처리 확인
terraform apply -auto-approve
...
~ content = (sensitive value) # forces replacement
...
terraform state show local_file.abc
...
content = (sensitive value)
...
echo "local_file.abc.content" | terraform console
(sensitive value)
# 결과물 확인
cat abc.txt ; echo
# terraform.tfstate 파일 확인
cat terraform.tfstate | grep '"content":'
"content": "password",
terraform.tfstate 파일을 보안적으로 안전하게 관리하기 위한 주요 방안
- 파일 암호화: terraform.tfstate 파일을 암호화하여 저장하거나 관리합니다. 이를 위해 클라우드 제공자의 키 매니지먼트 서비스나 Terraform Vault와 같은 시크릿 관리 도구를 활용할 수 있습니다.
- 접근 제어 및 권한 관리: 파일에 접근할 수 있는 권한을 최소한의 필요성에 맞춰 제한하고, 접근 로그를 검토하여 보안 사고를 사전에 탐지할 수 있도록 합니다.
- 정기적인 보안 검토: terraform.tfstate 파일을 정기적으로 검토하여 민감한 정보가 노출되지 않도록 유지합니다.
변수 입력 방식과 우선순위
- 변수는 코드 수정 없이 재사용 가능한 값으로, 특히 테라폼의 모듈적 특성을 활용하여 다양한 환경에서 동일한 모듈을 사용할 수 있도록 합니다.
- 사용자는 프로비저닝 실행 시 원하는 값을 변수에 정의할 수 있습니다. 이는 테라폼에서 프로비저닝하고자 하는 리소스나 환경에 필요한 설정 값을 제공하는 데 사용됩니다.
- 변수는 여러 방식으로 선언될 수 있으며, 이에 따라 우선순위가 결정됩니다. 일반적인 우선순위는 다음과 같습니다
- 환경 변수(Environment Variables): 로컬 시스템이나 빌드 서버의 환경 변수를 통해 변수 값이 설정될 수 있습니다. 이는 보통 우선순위가 가장 높습니다.
- tfvars 파일: 테라폼 변수 파일(tfvars 파일)을 사용하여 변수 값을 정의할 수 있습니다. 이 파일은 특정 환경에 맞게 설정할 수 있습니다.
- 모듈 입력 변수: 모듈 호출 시 인라인으로 변수 값을 전달할 수 있습니다. 이는 모듈을 호출하는 부분에서 변수를 설정할 때 사용됩니다.
- 기본값(Default Value): 변수가 선언될 때 기본값을 지정할 수 있습니다. 기본값은 다른 방식으로 값이 설정되지 않았을 때 사용됩니다.
- main.tf 파일 코드 수정
variable "my_var" {}
resource "local_file" "abc" {
content = var.my_var
filename = "${path.module}/abc.txt"
}
'Terraform > Terraform 101 Study' 카테고리의 다른 글
2주차 3편 테라폼 기초 - 기본 사용 2/3 (0) | 2024.06.19 |
---|---|
2주차 2편 테라폼 기초 - 기본 사용 2/3 (0) | 2024.06.19 |
1주차 2편 테라폼 기초 - 기본 사용 1/3 (0) | 2024.06.16 |
1주차 1편 테라폼 기초 - 기본 사용 1/3 (0) | 2024.06.16 |