DDetB.Log
article thumbnail
이 포스팅은 CloudNet@ 팀이 진행하는 테라폼 기초 입문 스터디에 참여하며 ‘테라폼으로 시작하는 IaC’ 책을 기준하여 정리한 글입니다.

조건문

3항 연산자

테라폼에서 조건식은 기본적으로 3항 연산자를 사용. [condition] ? [true] : [false] 의 형태를 가지며, condition에 해당하는 조건문이 true 일 경우 [ture]의 값을 반환, false일 경우 [false]에 해당하는 값을 반환.

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 : ""
}

실행 및 확인

$ terraform apply -auto-approve
...
Outputs:

content = "foo!"

main.tf 수정

variable "enable_file" {
  default = "string" # 문자형으로 변경
}

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 : ""
}

실행 및 확인

$ terraform apply -auto-approve 
╷
│ Error: Incorrect condition type
│ 
│   on main.tf line 6, in resource "local_file" "foo":
│    6:   count    = var.enable_file ? 1 : 0
│     ├────────────────
│     │ var.enable_file is "string"
│ 
│ The condition expression must be of type bool.
╵

=> 파이썬의 경우 빈 문자열이나 0이 아닌 경우 조건식에서 True인데, 테라텀의 경우는 어떤지 [true] or [false] 위치에 다른 타입을 입력하여 확인.

=> 결론: boolean 형만 가능.

if문

만약 아래와 같은 코드에서 for문 사용 시 조건에 매치되는 값만 필터링하여 반환하고 싶을 땐 3항 연산자로 작성 가능할까?

variable "enable_file" {
  default = ["a", "b", "c", "d", "e", "f"]
}

locals {    
  file_cnt = [for idx, num in var.enable_file: idx % 2 == 1 ? num : null] # false 인 경우엔..?
}

실행 및 확인

$ terraform console
> local.file_cnt
[
  tostring(null),
  "b",
  tostring(null),
  "d",
  tostring(null),
  "f",
]

=> false 인 경우에도 특정 값이 반환되어 원하는 값만 필터링이 불가능.

=> for문의 경우, 아래와 같이 if문을 사용해 필터링 가능.

main.tf 수정

variable "enable_file" {
  default = ["a", "b", "c", "d", "e", "f"]
}

locals {    
  file_cnt = [for idx, num in var.enable_file: num if idx % 2 == 1]
}

resource "local_file" "foo" {
  count    = length(local.file_cnt)
  content  = "foo!"
  filename = "${path.module}/foo${count.index+1}.bar"
}

output "content" {
  value = local.file_cnt
}

실행 및 확인

$ terraform console
> local.file_cnt
[
  "b",
  "d",
  "f",
]

함수

테라폼은 프로그래밍 언어적인 특성을 가지고 있어서, 값의 유형을 변경하거나 조합할 수 있는 내장 함수를 사용 할 수 있다. 프로그래밍 언어처럼 함수를 정의해서 사용할 수는 없지만, Numeric, String, Network 함수 등 다양한 함수를 제공한다.

main.tf

locals {
  a_list = ["alpha", "bravo", "charlie"]
  idx_2nd = index(local.a_list, "bravo")
}

resource "local_file" "foo" {
  content  = "${upper("foo! bar!")}\nindex of bravo is ${local.idx_2nd}"
  filename = "${path.module}/foo.bar"
}

 

foo.bar

FOO! BAR!
index of bravo is 1

 

=> upper() 를 사용한 대문자 변환, index() 를 사용해 list 타입의 특정값 index 반환

내장함수 참고: (https://developer.hashicorp.com/terraform/language/functions)

프로비저너

리소스 배포 이후 동작이 필요한 경우 사용. 테라폼의 구성과 별개로 동작하며, 상태 파일과 동기화 되지 않으므로 선언적 보장이 되지 않음.

main.tf

variable "sensitive_content" {
  default   = "secret"
  #sensitive = true
}

resource "local_file" "foo" {
  content  = upper(var.sensitive_content)
  filename = "${path.module}/foo.bar"

  provisioner "local-exec" {
    command = "echo The content is ${self.content}"
  }

  provisioner "local-exec" {
    command    = "abc"
    on_failure = continue
  }

  provisioner "local-exec" {
    when    = destroy
    command = "echo The deleting filename is ${self.filename}"
  }
}

실행 및 확인

$ terraform apply -auto-approve
...
local_file.foo: Creating...
local_file.foo: Provisioning with 'local-exec'...
local_file.foo (local-exec): Executing: ["/bin/sh" "-c" "echo The content is SECRET"]
local_file.foo (local-exec): The content is SECRET
local_file.foo: Provisioning with 'local-exec'...
local_file.foo (local-exec): Executing: ["/bin/sh" "-c" "abc"]
local_file.foo (local-exec): /bin/sh: 1: abc: not found
local_file.foo: Creation complete after 0s [id=3c3b274d119ff5a5ec6c1e215c1cb794d9973ac1]

$ terraform state list
local_file.foo

$ terraform state show local_file.foo
# local_file.foo:
resource "local_file" "foo" {
    content              = "SECRET"
    content_base64sha256 = "CRexOpCRkV1UtjNvRZCVOczkUrNmGyHzhkGKJXiDswo="
    content_base64sha512 = "/rZUHUkqHVA5TMRI6cTQisOBxckKZWsZIBus/flGK4eopVeaR4EGCcIwfeyS9SyI8hj9MHWv4CYpvF/QHOc0/Q=="
    content_md5          = "44c7be48226ebad5dca8216674cad62b"
    content_sha1         = "3c3b274d119ff5a5ec6c1e215c1cb794d9973ac1"
    content_sha256       = "0917b13a9091915d54b6336f45909539cce452b3661b21f386418a257883b30a"
    content_sha512       = "feb6541d492a1d50394cc448e9c4d08ac381c5c90a656b19201bacfdf9462b87a8a5579a47810609c2307dec92f52c88f218fd3075afe02629bc5fd01ce734fd"
    directory_permission = "0777"
    file_permission      = "0777"
    filename             = "./foo.bar"
    id                   = "3c3b274d119ff5a5ec6c1e215c1cb794d9973ac1"
}

$ cat terraform.tfstate | jq

{
  "version": 4,
  "terraform_version": "1.5.2",
  "serial": 4,
  "lineage": "2c46e54e-af6a-bb07-a0dc-d820557430f1",
  "outputs": {},
  "resources": [
    {
      "mode": "managed",
      "type": "local_file",
      "name": "foo",
      "provider": "provider[\"registry.terraform.io/hashicorp/local\"]",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "content": "SECRET",
            "content_base64": null,
            "content_base64sha256": "CRexOpCRkV1UtjNvRZCVOczkUrNmGyHzhkGKJXiDswo=",
            "content_base64sha512": "/rZUHUkqHVA5TMRI6cTQisOBxckKZWsZIBus/flGK4eopVeaR4EGCcIwfeyS9SyI8hj9MHWv4CYpvF/QHOc0/Q==",
            "content_md5": "44c7be48226ebad5dca8216674cad62b",
            "content_sha1": "3c3b274d119ff5a5ec6c1e215c1cb794d9973ac1",
            "content_sha256": "0917b13a9091915d54b6336f45909539cce452b3661b21f386418a257883b30a",
            "content_sha512": "feb6541d492a1d50394cc448e9c4d08ac381c5c90a656b19201bacfdf9462b87a8a5579a47810609c2307dec92f52c88f218fd3075afe02629bc5fd01ce734fd",
            "directory_permission": "0777",
            "file_permission": "0777",
            "filename": "./foo.bar",
            "id": "3c3b274d119ff5a5ec6c1e215c1cb794d9973ac1",
            "sensitive_content": null,
            "source": null
          },
          "sensitive_attributes": []
        }
      ]
    }
  ],
  "check_results": null
}

=> state에 프로비저너 정보(실행 및 결과)가 없다

profile

DDetB.Log

@DDetMok

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!