3.5 데이터 소스

  • 테라폼으로 정의되지 않은 외부 리소스 또는 저장된 정보를 테라폼 내에서 참조할 때 사용
  • 데이터 소스 블록은 data로 시작, 이후 데이터 소스 유형 정의
data "<리소스 유형>"	"<이름>" {
	<인수> = <값>
}
  •  
    • 첫번째 _를 기준으로 앞은 프로바이더 이름,
      뒤는 프로바이더에서 제공하는 리소스 유형
      ex)local_file - local이라는 이름의 프로바이더에서 제공하는 file이라는 리소스 유형
    • 데이터 소스 유형 선언 뒤에는 고유한 이름을 붙인다
      • 리소스 이름과 마찬가지로 중복 될 수 없다 -> 식별자 역할
    • 이름 뒤 데이터 소스 유형에 대한 구성 인수들은 {} 안에 선언한다
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

# -auto-approve가 있으면 yes를 묻지 않음
terraform init && terraform plan && terraform apply -auto-approve
terraform state list

# 테라폼 콘솔 : 데이터 소스 참조 확인
echo "data.local_file.abc" | terraform console
  • 데이터 소스 속성 참조

3.6 입력 변수 Variable

  • Input Variable로 테라폼에서는 정의
    • 인프라를 구성하는데 필요한 속성 값을 정의
    • 코드 변경 없이 여러 인프라 생성 가능하게 하는데 목적
  • 변수 선언 방식
    • 변수는 variable로 시작되는 블록으로 구성된다.
    • 변수 블록 뒤의 이름 값은 동일 모듈 내 모든 변수 선언에서 고유해야 하며, 이 이름으로 다른 코드 내에서 참조된다.
    • 테라폼 예약변수 이름으로는 사용이 불가능하다.
# 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, any(명시적으로 모든 유형이 허용됨을 선언)
    • 집합 유형
      • list (<유형>): 인덱스 기반 집합
      • map (<유형>): 값 = 속성 기반 집합이며 키값 기준 정렬
      • set (<유형>): 값 기반 집합이며 정렬 키값 기준 정렬
      • object ({<인수 이름>=<유형>, …})
      • tuple ([<유형>, …])
    • 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"]
}


# 조건 결합1 : 모든 항목이 number인 list
variable "list_numeric_example" {
  description = "An example of a numeric list in Terraform"
  type        = list(number)
  default     = [1, 2, 3]
}




# 조건 결합2 : 모든 값이 String 인 mapvariable "map_example" {
  description = "An example of a map in Terraform"
  type        = map(string)

  default = {
    key1 = "value1"
    key2 = "value2"
    key3 = "value3"
  }
}

# 구조적 유형 (Structural type)
# 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
  }
}

 

3.7 local 지역 값

variable "prefix" {
  default = "hello"
}

locals {
  name    = "terraform"
  content = "${var.prefix} ${local.name}"
  my_info = {
    age    = 20
    region = "KR"
  }
  my_nums = [1, 2, 3, 4, 5]
}

locals {
  content = "content2" # 중복 선언되었으므로 오류가 발생한다.
}
  • 코드 내에서 사용자가 지정한 값 또는 속성 값을 가공해 참조 가능한 local (지역 값)
  • 외부에서 입력되지 않고, 코드 내에서만 가공되어 동작
  • 선언된 모듈 내에서만 접근 가능 (입력변수와 차이점)
  • 변수처럼 실행시 입력받을 수 없음
  • 장단점
    • 장점 : 값이나 표현식을 반복적으로 사용할 수 있는 편의 제공
    • 단점
      • 빈번하게 여러 곳에서 사용되는 경우 실제 값에 대한 추적이 어려움
      • 유지 관리 부담 커짐
      • 주의할 것      

3.8 출력 output

output "instance_ip_addr" {
  value = "http://${aws_instance.server.private_ip}"
}
  • 주로 테라폼 코드의 프로비저닝 수행 후의 결과 속성 값을 확인하는 용도로 사용된다.
  • 프로그래밍 언어에서 코드 내 요소 간에 제한된 노출을 지원하듯,
    테라폼 모듈 간, 워크스페이스 간 데이터 접근 요소로도 활용 가능
  • 자바의 getter와 비슷한 역할?
  • output의 용도
    • 루트 모듈에서 사용자가 확인하고자 하는 특정 속성 출력
    • 자식 모듈의 특정 값을 정의하고 루트 모듈에서 결과를 참조
    • 서로 다른 루트 모듈의 결과를 원격으로 읽기 위한 접근 요소
  • 정의시 사용 가능 메타 인수
    • description : 출력 값 설명
    • sensitive : 민감한 출력 값임을 알리고 테라폼의 출력문에서 값 노출을 제한
    • depends_on : value에 담길 값이 특정 구성에 종속성이 있는 경우 생성되는 순서를 임의로 조정
    • precondition : 출력 전에 지정된 조건을 검증
  • 예시
resource "local_file" "abc" {
  content  = "abc123"
  filename = "${path.module}/abc.txt"
}

output "file_id" {
  value = local_file.abc.id
}

output "file_abspath" {
# abspath : 파일 시스템 경로를 포함하는 문자열을 가져와 절대 경로로 변환하는 함수
  value = abspath(local_file.abc.filename)
}
  • 실행
# plan 실행 시, 이미 정해진 속성은 출력을 예측하지만
# file_id는 예측할수 없으므로 known after apply로 표시
terraform init && terraform plan
...
Changes to Outputs:
  + file_abspath = "/Users/gasida/Downloads/workspaces/3.8/abc.txt"
  + file_id      = (known after apply)


# 
terraform apply -auto-approve
...
Outputs:
file_abspath = "/Users/gasida/Downloads/workspaces/3.8/abc.txt"
file_id = "6367c48dd193d56ea7b0baad25b19455e529f5ee"

#
terraform state list
terraform output

3.9 반복문

list 형태의 값 목록이나 Key-Value 형태의 문자열 집합인 데이터가 있는 경우
동일한 내용에 대해 테라폼 구성 정의를 반복적으로 하지 않고 관리할 수 있다.

count : 반복문, 정수 값만큼 리소스나 모듈을 생성

resource "local_file" "abc" {
  count    = 5
  content  = "abc${count.index}"
  filename = "${path.module}/abc${count.index}.txt"
}

output "fileid" {
  value = local_file.abc.*.id
}

output "filename" {
  value = local_file.abc.*.filename
}

output "filecontent" {
  value = local_file.abc.*.content
}

for_each : 반복문, 선언된 key 값 개수만큼 리소스를 생성

  • each.key , each.value :  인스턴스에 해당하는 map의 key, value
resource "local_file" "abc" {
  for_each = {
    a = "content a"
    b = "content b"
  }
  content  = each.value
  filename = "${path.module}/${each.key}.txt"
}

for : 복합 형식 값의 형태를 변환하는 데 사용 (for_each와 다름에 유의)

variable "names" {
  default = ["a", "b", "c"]
}

resource "local_file" "abc" {
  content  = jsonencode(var.names) # 결과 : ["a", "b", "c"]
  filename = "${path.module}/abc.txt"
}

dynamic : 리소스 내부 속성 블록을 동적인 블록으로 생성

variable "names" {
  default = {
    a = "hello a"
    b = "hello b"
    c = "hello c"
  }
}

data "archive_file" "dotfiles" {
  type        = "zip"
  output_path = "${path.module}/dotfiles.zip"

  dynamic "source" {
    for_each = var.names
    content {
      content  = source.value
      filename = "${path.module}/${source.key}.txt"
    }
  }
}
블로그 이미지

감동맨

rkaehdaos의 블로그

,