이 포스팅은 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에 프로비저너 정보(실행 및 결과)가 없다
'DevOps > Terraform' 카테고리의 다른 글
Terraform - State (0) | 2023.07.29 |
---|---|
Terraform 기본 사용 (7) - terraform_data & moved blocks (0) | 2023.07.22 |
Terraform 기본 사용 (5) - 종합 실습 1 (0) | 2023.07.10 |
Terraform 기본 사용 (4) - Local & Output & 반복문 (2) | 2023.07.10 |
Terraform 기본 사용 (3) - Data Sources & Variable (0) | 2023.07.10 |