티스토리 뷰

T101 study

[3주차] 기본 사용 3/3

haru224 2024. 6. 29. 10:14

lCloudNet@ 가시다님이 진행하는 Terraform 101 Study 4기 스터디 내용 참고.

스터디 교재 : ‘테라폼으로 시작하는 IaC’ (한빛 미디어, 김민수 외 지금) 책의 내용 참고

 -. https://www.aladin.co.kr/m/mproduct.aspx?ItemId=317519064

 

1. 반복문


  • for_each : 반복문, 선언된 key 값 개수만큼 리소스를 생성하는데 사용 - Link 악분
    • for-each는 반복(for)을 할 때 타입 값에 대해 하나하나 each object로 접근한다는 의미입니다.
    • each object는 key, value 2개의 속성을 가지고 있습니다.
      • each.key — The map key (or set member) corresponding to this instance.
      • each.value — The map value corresponding to this instance. (If a set was provided, this is the same as each.key.)
    • 하지만 for_each는 모든 타입에 대해 each object로 접근 할 수 없고 map, set타입만 허용합니다.
    • map, set타입이 아닌 expression은 map 또는 set으로 타입변환(toset 등)을 해야합니다.
## Map
resource "azurerm_resource_group" "rg" {
  for_each = tomap({
    a_group       = "eastus"
    another_group = "westus2"
  })
  name     = each.key
  location = each.value
}

## Set of strings
resource "aws_iam_user" "the-accounts" {
  for_each = toset(["Todd", "James", "Alice", "Dottie"])
  name     = each.key
}

리소스 또는 모듈 블록에서 for_each에 입력된 데이터 형태가 map 또는 set이면, 선언된 key 값 개수만큼 리소스를 생성하게 된다.

mkdir 3.9 && cd 3.9
touch main.tf


## main.tf

resource "local_file" "abc" {
  for_each = {
    a = "content a"
    b = "content b"
  }
  content  = each.value
  filename = "${path.module}/${each.key}.txt"
}

## 실행 후 확인
terraform init && terraform plan && terraform apply -auto-approve
terraform state list
terraform state show 'local_file.abc["a"]'
terraform state show 'local_file.abc["b"]'
ls *.txt
cat a.txt ;echo
cat b.txt ;echo

echo "local_file.abc" | terraform console
echo 'local_file.abc["a"]' | terraform console
echo 'local_file.abc["a"].content' | terraform console
echo 'local_file.abc["b"].content' | terraform console

# VSCODDE 에서 terraform.tfstate 파일 확인 혹은 cat terraform.tfstate

 

  • 생성되는 리소스의 경우 <리소스 타입>.<이름>[<key>], 모듈의 경우 module.<모듈 이름>[<key>]로 해당 리소스의 값을 참조한다.
  • 이 참조 방식을 통해 리소스 간 종속성을 정의하기도 하고 변수로 다른 리소스에서 사용하거나 출력을 위한 결과 값으로 사용한다.
## main.tf 수정

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

resource "local_file" "abc" {
  for_each = var.names
  content  = each.value
  filename = "${path.module}/abc-${each.key}.txt"
}

resource "local_file" "def" {
  for_each = local_file.abc
  content  = each.value.content
  filename = "${path.module}/def-${each.key}.txt"
}


#실행 후 확인
terraform apply -auto-approve
terraform state list
terraform state show 'local_file.abc["a"]'
terraform state show 'local_file.def["a"]'
ls *.txt

# 
echo "local_file.abc" | terraform console
echo 'local_file.abc["a"]' | terraform console
echo 'local_file.abc["a"].content' | terraform console

# terraform.tfstate 파일 확인
cat terraform.tfstate
  • local_file.abc는 변수의 map 형태의 값을 참조,
  • local_file.def의 경우 local_file.abc 도한 결과가 map으로 반환되므로 다시 for_each 구문을 사용할 수 있다

 

  • key 값은 count의 index와는 달리 고유하므로 중간에 값을 삭제한 후 다시 적용해도 삭제한 값에 대해서만 리소스를 삭제한다.
## main.tf 파일 수정 : count 경우와 유사하게 중간 값을 삭제 후 확인
## b = "content b" 삭제


variable "names" {
  default = {
    a = "content a"
    c = "content c"
  }
}

resource "local_file" "abc" {
  for_each = var.names
  content  = each.value
  filename = "${path.module}/abc-${each.key}.txt"
}

resource "local_file" "def" {
  for_each = local_file.abc
  content  = each.value.content
  filename = "${path.module}/def-${each.key}.txt"
}

# 실행 후 확인
terraform apply -auto-approve
terraform state list
ls *.txt

 

에러 없이 삭제 됨

 

  • for_each : 데이터 유형
    • for_each 문은 map, set타입만 허용합니다. 따라서 다른 유형인 경우 tomap, toset 을 사용하여 변환을 해주어야 합니다. 
## 잘못된 데이터 유형

resource "aws_iam_user" "the-accounts" {
  for_each = ["Todd", "James", "Alice", "Dottie"]
  name     = each.key
}

## 실행 후 확인
terraform init && terraform plan


## 변환된 데이터 유형 

resource "aws_iam_user" "the-accounts" {
  for_each = toset(["Todd", "James", "Alice", "Dottie"])
  name     = each.key
}
  • 잘못된 type

 


데이터 유형 실습

 

  • 기본 유형
    • string : 글자 유형
    • number : 숫자 유형
    • bool : true 또는 false
    • any : 명시적으로 모든 유형이 허용됨을 표시
  • 집합 유형
    • list [<유형>]: 인덱스 기반 집합
    • map (<유형>): 값 = 속성 기반 집합이며 키값 기준 정렬
    • set (<유형>): 값 기반 집합이며 정렬 키값 기준 정렬
    • object ({<인수 이름>=<유형>, …})
    • tuple ([<유형>, …])
  • list와 set은 선언하는 형태가 비슷하지만 참조 방식이 인덱스와 키로 각각 차이가 있고, map와 set의 경우 선언된 값이 정렬되는 특징을 가진다.
## main.tf

variable "string_a" {
  default     = "myString"
}

variable "string_b" {
  type        = string
  default     = "myString"
}

# variable "string_c" {
#   type        = string
#   default     = myString
# }


variable "number_a" {
  default = 123
}

variable "number_b" {
  type    = number
  default = 123
}

variable "number_c" {
  default = "123"
}


variable "boolean" {
  default = true
}


# (Array) list , set , tuple - value , [ ] 사용
variable "list_set_tuple_a" {
  default = ["aaa", "bbb", "ccc"]
}

variable "list_set_tuple_b" {
  type    = list(string)
  default = ["bbb", "ccc", "aaa"]
}

variable "list_set_tuple_c" {
  type    = set(string)
  default = ["bbb", "ccc", "aaa"]
}

variable "list_set_tuple_d" {
  default = ["aaa", 1, false]
}

variable "list_set_tuple_e" {
  type    = tuple([string, number, bool])
  default = ["aaa", 1, false]
}


# (Object) map , object - key : value , { } 사용
variable "map_object_a" {
  default = {"a" : "aaa", "b" : "bbb" , "c" : "ccc"}
}

variable "map_object_b" {
  type    = map(string)
  default = {"b" : "bbb" , "c" : "ccc", "a" : "aaa"}
}

variable "map_object_c" {
  default = {"name" : "gasida", "age" : 27 }
}

variable "map_object_d" {
  type = object({ name = string, age = number })
  default = {"name" : "gasida", "age" : 27 }
}



## 데이터 유형 확인
#
terraform plan && terraform apply -auto-approve

#
terraform console
-----------------
# 기본
type(12)
type("12")

type(a)
type("a")

type(true)
type("true")

# string
var.string_a
var.string_b

type(var.string_a)
type(var.string_b)

# number
var.number_a
var.number_b
var.number_c
type(var.number_a)
type(var.number_b)
type(var.number_c)

# boolean
var.boolean
type(var.boolean)


# list , set , tuple - 'value'
var.list_set_tuple_a
var.list_set_tuple_b
var.list_set_tuple_c
var.list_set_tuple_d
var.list_set_tuple_e
type(var.list_set_tuple_a)
type(var.list_set_tuple_b)
type(var.list_set_tuple_c)
type(var.list_set_tuple_d)
type(var.list_set_tuple_e)

var.list_set_tuple_a[0]
type(var.list_set_tuple_a[0])

var.list_set_tuple_b[0]
type(var.list_set_tuple_b[0])

var.list_set_tuple_d[0]
var.list_set_tuple_d[1]
var.list_set_tuple_d[2]
type(var.list_set_tuple_d[0])
type(var.list_set_tuple_d[1])
type(var.list_set_tuple_d[2])

var.list_set_tuple_e[0]
type(var.list_set_tuple_e[0])


# map , object - 'key : value'
var.map_object_a
var.map_object_b
var.map_object_c
var.map_object_d
type(var.map_object_a)
type(var.map_object_b)
type(var.map_object_c)
type(var.map_object_d)

var.map_object_a["a"]
type(var.map_object_a["a"])

var.map_object_b["a"]
type(var.map_object_b["a"])

var.map_object_c["name"]
type(var.map_object_c["name"])

var.map_object_d["age"]
type(var.map_object_d["age"])


# tuple > list > set
type(["a","b"])
type(tolist(["a","b"]))
type(toset(["a","b"]))


# object > map
type({a="a", b="b"})
type({a="a", b=1})
type(tomap({a="a", b="b"}))
type(tomap({a="a", b=1}))


exit
-----------------

 

 

for_each vs count 와 비교


  • count 는 index 로 몇번에 어떤 내용이 있는지를 알 수 없다, 중간 리소스 삭제나 추가 시 문제 발생 가능.
  • for_each 표현식을 사용하면 리스트 lists, 집합 sets, 맵 maps 를 사용하여 전체 리소스의 여러 복사본 또는 리소스 내 인라인 블록의 여러 복사본, 모듈의 복사본을 생성 할 수 있음
  • 먼저 for_each 를 사용하여 리소스의 여러 복사본을 만드는 구문
resource "<PROVIDER>_<TYPE>" "<NAME>" {
  for_each = <COLLECTION>

  [CONFIG ...]
}
  •  
  • COLLECTION 은 루프를 처리할 집합 sets 또는 맵 maps
  • 리소스에 for_each 를 사용할 때에는 리스트는 지원하지 않습니다.
  • 그리고 CONFIG 는 해당 리소스와 관련된 하나 이상의 인수로 구성되는데 CONFIG 내에서 each.key 또는 each.value 를 사용하여 COLLECTION 에서 현재 항목의 키와 값에 접근할 수 있습니다.
  • for_each 를 사용하여 3명의 IAM 사용자를 생성하는 방법
    • var.user_names 리스트를 집합(set)으로 변환하기 위해 toset 사용. for_each 는 리소스에 사용될 때는 setmap만 지원.
    • for_each 가 이 집합을 반복하면 each.value 에서 각 사용자 이름을 사용할 수 있습니다.
    • main.tf : 일반적으로는 each.key 는 키/값 쌍 맵에서만 사용가능하지만, 사용자 이름은 each.key 에서도 사용할 수 있습니다.
    • all_users 출력 변수가 for_each 의 키, 즉 사용자 이름을 키로 가지며 값이 해당 리소스의 전체 출력인 맵을 포함합니다.
## main.tf

provider "aws" {
  region = "ap-northeast-2"
}

resource "aws_iam_user" "myiam" {
  for_each = toset(var.user_names)
  name     = each.value
}

variable "user_names" {
  description = "Create IAM users with these names"
  type        = list(string)
  default     = ["gasida", "akbun", "ssoon"]
}

output "all_users" {
  value = aws_iam_user.myiam
}

## 적용 후 확인
#
terraform init -upgrade
terraform plan && terraform apply -auto-approve

# 확인
terraform state list
terraform output
aws iam list-users | jq

# 배포 결과 content만 필터링 확인
cat terraform.tfstate | grep -e key -e name -e "content:"

  • for_each 를 사용하여 3명의 IAM 사용자 중 1명을 삭제
    • for_each 를 사용해 리소스으로 처리하면 컬렉션 중간의 항목도 안전하게 제거할 수 있어서, count리소스를 배열 처리보다 이점이 큽니다.
    • var.user_names 리스트 중간에 값을 제거하고 plan 으로 확인
## "akbun" 삭제

...
variable "user_names" {
  description = "Create IAM users with these names"
  type        = list(string)
  default     = ["gasida", "ssoon"]
}
...

## 실행 후 확인
terraform plan
terraform apply -auto-approve
terraform state list
aws iam list-users | jq

# 배포 결과 content만 필터링 확인
cat terraform.tfstate | grep -e key -e name -e "content:"
cat terraform.tfstate.backup | grep -e key -e name -e "content:"

 

tfstate.backup 파일은 직전 상태 파일을 백업한 파일.

 

 

for Expressions : 복합 형식 값의 형태를 변환하는 데 사용 Link ← for_each와 다름


  • list 값의 포맷을 변경하거나 특정 접두사 prefix를 추가할 수도 있고, output에 원하는 형태로 반복적인 결과를 표현할 수 도 있다.
    • list 타입의 경우 또는 인덱스와 값을 반환
    • map 타입의 경우 또는 키와 값에 대해 반환
    • set 타입의 경우 키 값에 대해 반환
## main.tf
## content의 값 정의에 for 구문을 사용하여 내부 값을 일괄적으로 변경

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

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

output "file_content" {
  value = local_file.abc.content
}





## 실행 후 확인
#
terraform apply -auto-approve
terraform state list
terraform output --raw file_content | jq

ls *.txt
cat abc.txt ;echo

# 참고 jsonencode Function
terraform console
-----------------
var.names
type(var.names)
jsonencode(var.names)
jsonencode({"hello"="world"})

exit
-----------------

jsonencode encodes a given value to a string using JSON syntax. Link 

 

jsonencode - Functions - Configuration Language | Terraform | HashiCorp Developer

The jsonencode function encodes a given value as a JSON string.

developer.hashicorp.com

 

 

  • for 구문을 사용하는 몇 가지 규칙은 다음과 같다
    • list 유형의 경우 반환 받는 값이 하나로 되어 있으면 을, 두 개의 경우 앞의 인수가 인덱스를 반환하고 뒤의 인수가 을 반환
      • 관용적으로 인덱스는 i, 값은 v로 표현
    • map 유형의 경우 반환 받는 값이 하나로 되어 있으면 를, 두 개의 경우 앞의 인수가 를 반환하고 뒤의 인수가 을 반환
      • 관용적으로 키는 k, 값은 v로 표현
    • 결과 값은 for 문을 묶는 기호가 **[ ]**인 경우 tuple로 반환되고 **{ }**인 경우 object 형태로 반환
    • object 형태의 경우 에 대한 쌍은 ⇒ 기호로 구분
    • { } 형식을 사용해 object 형태로 결과를 반환하는 경우 키 값은 고유해야 하므로 값 뒤에 그룹화 모드 심볼(…)를 붙여서 키의 중복을 방지(SQL의 group by 문 또는 Java의 MultiValueMap과 같은 개념)
    • if 구문을 추가해 조건 부여 가능
[for item in 조회할 expression: 변환작업]  --> 리턴 타입이 turple

{for item in 조회할 expression: 변환작업} -->  리턴 타입이 object

 

## main.tf : list 유형에 대한 for 구문 처리의 몇 가지 예를 확인


variable "names" {
  type    = list(string)
  default = ["a", "b"]
}

output "A_upper_value" {
  value = [for v in var.names : upper(v)]
}

output "B_index_and_value" {
  value = [for i, v in var.names : "${i} is ${v}"]
}

output "C_make_object" {
  value = { for v in var.names : v => upper(v) }
}

output "D_with_filter" {
  value = [for v in var.names : upper(v) if v != "a"]
}


## 실행 후 확인
#
terraform apply -auto-approve
terraform state list

# 
terraform output
terraform output A_upper_value
terraform output D_with_filter

# 
terraform console
-----------------
var.names
type(var.names)

# 리턴 타입 tuple : 값 v
[for v in var.names : upper(v)]
type([for v in var.names : upper(v)])

# 리턴 타입 tuple : 인덱스 i, 값 v
[for i, v in var.names : "${i} is ${v}"]
type([for i, v in var.names : "${i} is ${v}"])

# 리턴 타입 object : object 형태의 경우 키와 값에 대한 쌍은 ⇒ 기호로 구분
{ for v in var.names : v => upper(v) }
type({ for v in var.names : v => upper(v) })

# 조건문 활용 : f 구문을 추가해 조건 부여 가능
[for v in var.names : upper(v) if v != "a"]
type([for v in var.names : upper(v) if v != "a"])

exit

## main.tf : map 유형에 대한 for 구문처리의 예를 확인


variable "members" {
  type = map(object({
    role = string
  }))
  default = {
    ab = { role = "member", group = "dev" }
    cd = { role = "admin", group = "dev" }
    ef = { role = "member", group = "ops" }
  }
}

output "A_to_tupple" {
  value = [for k, v in var.members : "${k} is ${v.role}"]
}

output "B_get_only_role" {
  value = {
    for name, user in var.members : name => user.role
    if user.role == "admin"
  }
}

output "C_group" {
  value = {
    for name, user in var.members : user.role => name...
  }
}


# 실행 후 확인

#
terraform apply -auto-approve
terraform state list

# 
terraform output
terraform output A_to_tupple
terraform output B_get_only_role
terraform output C_group

# 
terraform console
-----------------
var.members
type(var.members)

[for k, v in var.members : "${k} is ${v.role}"]
type([for k, v in var.members : "${k} is ${v.role}"])

{for name, user in var.members : name => user.role}
type({for name, user in var.members : name => user.role})

{for name, user in var.members : name => user.role  if user.role == "admin"}

# { } 형식을 사용해 object 형태로 결과를 반환하는 경우 키 값은 고유해야 하므로 값 뒤에 그룹화 모드 심볼(…)를 붙여서 키의 중복을 방지
{for name, user in var.members : user.role => name...}

exit

 

 

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


  • count 나 for_each 구문을 사용한 리소스 전체를 여러 개 생성하는 것 이외도 리소스 내에 선언되는 구성 블록을 다중으로 작성해야 하는 경우가 있다.
  • 예를 들면 AWS Security Group 리소스 구성에 ingress, egress 요소가 리소스 선언 내부에서 블록 형태로 여러 번 정의되는 경우다.
resource "aws_security_group" "example" {
  name        = "example-security-group"
  description = "Example security group"
  vpc_id.     = aws_vpc.main.id

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    ipv6_cidr_blocks = ["::/0"]
  }
}
  • 리소스 내의 블록 속성(Attributes as Blocks)은 리소스 자체의 반복 선언이 아닌 내부 속성 요소 중 블록으로 표현되는 부분에 대해서만 반복 구문을 사용해야 하므로, 이때 dynamic 블록을 사용해 동적인 블록을 생성 할 수 있다.
  • dynamic 블록을 작성하려면, 기존 블록의 속성 이름을 dynamic 블록의 이름으로 선언하고 기존 블록 속성에 정의되는 내용을 content 블록에 작성한다.
  • 반복 선언에 사용되는 반복문 구문은 for_each를 사용한다. 기존 for_each 적용 시 each 속성에 key, value가 적용되었다면 dynamic에서는 dynamic에 지정한 이름에 대해 속성이 부여된다.
  • dynamic 블록 활용 예
일반적인 블록 속성 반복 적용 시 dynamic 블록 적용 시
resource "provider_resource" "name" {
  name = "some_resource"

  some_setting {
    key = a_value
  }

  some_setting {
    key = b_value
  }

  some_setting {
    key = c_value
  }

  some_setting {
    key = d_value
  }
}
resource "provider_resource" "name" {
  name = "some_resource"

  dynamic "some_setting" {
    for_each = {
      a_key = a_value
      b_key = b_value
      c_key = c_value
      d_key = d_value
    }

    content {
      key = some_setting.value
    }
  }
}

 

## main.tf : archive 프로바이더(링크)의 archive_file에 source 블록 선언을 반복

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

  source {
    content  = "hello a"
    filename = "${path.module}/a.txt"
  }

  source {
    content  = "hello b"
    filename = "${path.module}/b.txt"
  }

  source {
    content  = "hello c"
    filename = "${path.module}/c.txt"
  }
}

## 실행 후 확인

terraform init -upgrade && terraform apply -auto-approve
terraform state list
terraform state show data.archive_file.dotfiles
ls *.zip
unzip dotfiles.zip
ls *.txt
cat a.txt ; echo

## main.tf : 리소스 내에 반복 선언 구성을 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"
    }
  }
}


## 실행 후 확인: 동일한 결과가 나옴

#
terraform apply -auto-approve
terraform state list
terraform state show data.archive_file.dotfiles
ls *.zip

 

 

2. 조건문


 

[Conditional Expressions] 테라폼에서의 조건식3항 연산자 형태를 갖는다. 조건은 true 또는 false로 확인되는 모든 표현식을 사용할 수 있다 - Link 

 

  • 일반적으로 비교, 논리 연산자를 사용해 조건을 확인한다.
  • 조건식은 ? 기호를 기준으로 왼쪽조건이며, 오른쪽: 기호를 기준으로 왼쪽이 조건에 대해 true가 반환되는 경우이고 오른쪽false가 반환되는 경우다.
  • 다음의 예에서 var.a가 빈 문자열이 아니라면 var.a를 나타내지만, 비어 있을 때는 “default-a”를 반환한다
# <조건 정의> ? <옳은 경우> : <틀린 경우>
var.a != "" ? var.a : "default-a"
  • 조건식의 각 조건은 비교 대상의 형태가 다르면 테라폼 실행 시 조건 비교를 위해 형태를 추론하여 자동으로 변환하는데, 명시적인 형태 작성을 권장
# 조건식 형태 권장 사항 
var.example ? 12 : "hello"            # 비권장
var.example ? "12" : "hello"          # 권장
var.example ? tostring(12) : "hello"  # 권장

 

  • 조건식은 단순히 특정 속성에 대한 정의, 로컬 변수에 대한 재정의, 출력 값에 대한 조건 정의 뿐만 아니라 리소스 생성 여부에 응용할 수 있다. count에 조건식을 결합한 경우 다음과 같이 특정 조건에 따라 리소스 생성 여부를 선택할 수 있다.
mkdir 3.10 && cd 3.10
touch main.tf

## main.tf

variable "enable_file" {
  default = true
}

resource "local_file" "foo" {
  count    = var.enable_file ? 1 : 0
  content  = "foo!"
  filename = "${path.module}/foo.bar"
}

output "content" {
  value = var.enable_file ? local_file.foo[0].content : ""
}


## 실행

# 변수 우선순위3 : 환경 변수 (TF_VAR 변수 이름)
export TF_VAR_enable_file=false
export | grep TF_VAR_enable_file

# 
terraform init && terraform plan && terraform apply -auto-approve
terraform state list
echo "var.enable_file ? 1 : 0" | terraform console

# 환경 변수 삭제
unset TF_VAR_enable_file
export | grep TF_VAR_enable_file

# 재실행
terraform plan && terraform apply -auto-approve
terraform state list

#
echo "local_file.foo[0]" | terraform console
echo "local_file.foo[0].content" | terraform console
echo "var.enable_file ? 1 : 0" | terraform console

 

환경변수 삭제 결과

 

3. 함수


 

테라폼은 프로그래밍 언어적인 특성을 가지고 있어서, 값의 유형을 변경하거나 조합할 수 있는 내장 함수를 사용 할 수 있다 - Link 

 

  • 단, 내장된 함수 외에 사용자가 구현하는 별도의 사용자 정의 함수를 지원하지는 않는다.
  • 함수 종류에는 숫자, 문자열, 컬렉션, 인코딩, 파일 시스템, 날짜/시간, 해시/암호화, IP 네트워크, 유형 변환이 있다.
  • 테라폼 코드에 함수를 적용하면 변수, 리소스 속성, 데이터 소스 속성, 출력 값 표현 시 작업을 동적이고 효과적으로 수행할 수 있다.

 

4. CLI를 위한 시스템 환경 변수


테라폼은 환경 변수를 통해 실행 방식과 출력 내용에 대한 옵션을 조절할 수 있다  - Link

 

  • 시스템 환경 변수를 설정하면, 영구적으로 로컬 환경에 적용되는 옵션이나 별도 서버 환경에서 실행하기 위한 옵션을 부여할 수 있다.
  • 이를 통해 로컬 작업 환경과 다른 환경 구성에서만 사용될 특정 옵션을 적용한다.
Mac/리눅스/유닉스: export <환경 변수 이름>=<값>
Windows CMD: set <환경 변수 이름>=<값>
Windows PowerShell: $Env:<환경 변수 이름>='<값>

 

TF_LOG : 테라폼의 stderr 로그에 대한 레벨을 정의

  • trace, debug, info, warn, error, off를 설정할 수 있고 관련 환경 변수가 없는 경우 off와 동일하다
  • 디버깅을 위한 로그 관련 환경 변수 설명은 다음과 같다
    • TF_LOG: 로깅 레벨 지정 또는 해제
    • TF_LOG_PATH: 로그 출력 파일 위치 지정
    • TF_LOG_CORE: TF_LOG와 별도로 테라폼 자체 코어에 대한 로깅 레벨 지정 또는 해제
    • TF_LOG_PROVIDER: TF_LOG와 별도로 테라폼에서 사용하는 프로바이더에 대한 로깅 레벨 지정 또는 해제
  • 환경에 맞게 TF_LOG를 info로 설정하고, terraform plan 동작을 실행하면 테라폼 출력에 관련 로그가 출력된다
TF_LOG=info terraform plan
...

 

TF_INPUT : 값을 false 또는 0으로 설정하면 테라폼 실행 시 인수에 -input=false 를 추가한 것과 동일한 수행 결과를 확인

  • 환경에 맞게 TF_INPUT을 0으로 설정하고 terraform plan 동작 실행하면 입력받는 동작을 수행하지 않으므로 입력 변수를 입력해야 하는 경우 에러가 출력된다
TF_INPUT=0 terraform plan
Error : No value for required variable

 

TF_VAR_name : TF_VAR_<변수 이름>을 사용하면 입력 시 또는 default로 선언된 변수 값을 대체한다

 

TF_CLI_ARGS / TF_CLI_ARGS_subcommand : 테라폼 실행 시 추가할 인수를 정의

# TF_CLI_ARGS="-input=false" terraform apply -auto-approve 는 terraform apply -input=false -auto-approve 와 같다
TF_CLI_ARGS="-input=false" terraform apply -auto-approve
Error: No value for required variable

# TF_CLI_ARGS_apply로 인수를 정의하면 terraform apply 커맨드 수행 시에만 동작한다
export TF_CLI_ARGS_apply="-input=false"
terraform apply -auto-approve
<에러>

terraform plan
<정상 계획 예측 출력>

 

TF_DATA_DIR : State 저장 백엔드 설정과 같은 작업 디렉터리별 데이터를 보관하는 위치를 지정

  • 이 데이터는 .terraform 디렉터리 위치에 기록되지만 TF_DATA_DIR에 경로가 정의되면 기본 경로를 대체하여 사용된다.
  • 일관된 테라폼 사용을 위해서 해당 변수는 실행 시마다 일관되게 적용될 수 있도록 설정하는 것이 중요하다.
  • 설정 값이 이전 실행 시에만 적용되는 경우 init 명령으로 수행된 모듈, 아티팩트 등의 파일을 찾지 못한다.
  • 이미 terraform init이 수행된 상태에서 TF_DATA_DIR로 경로를 재지정하고 실행하는 경우 플러그인 설치가 필요하다는 메시지 출력을 확인할 수 있다.
TF_DATA_DIR=./.terraform_tmp terraform plan
Error: Required plugins anr not installed

'T101 study' 카테고리의 다른 글

[7주차] 테라폼으로 AWS EKS 배포  (0) 2024.07.27
[5주차] Module & Runner  (0) 2024.07.13
[4주차] Provider & State  (0) 2024.06.30
[2주차] 기본 사용 2/3  (0) 2024.06.22
[1주차] 기본 사용 1/3  (0) 2024.06.13
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함