Overview
2023.04.04 - [Hashicorp] - 1. Terraform 기초 : 설치 및 .tf 파일 설명
2023.04.06 - [Hashicorp] - 2. Terraform 변수 사용법(use-variable)
2023.04.10 - [Hashicorp] - 3. Terraform 다양한 변수(variable, local, data...output, input)
2023.04.12 - [Hashicorp] - 4. Terraform의 다양한 Function(함수)
오늘은 테라폼의 다양한 Expression에 대해 공부해보려고 한다.
1. Types and Values(유형 및 값)
모든 값에는 해당 값을 사용할 수 있는 위치와 적용할 수 있는 변환을 나타내는 유형이 있다.
Type
- string: 와 같은 일부 텍스트를 나타내는 일련의 유니코드 문자이다 "hello".
- number: 숫자 값이다. 유형 은 number와 같은 정수 (15)및 와 같은 소수 값을 모두 나타낼 수 있다 (6.283185.)
- bool: 부울 값, true또는 false. bool값은 조건 논리에서 사용할 수 있다.
- list(또는 tuple): 와 같은 일련의 값 ["us-west-1a", "us-west-1c"]. 목록 또는 튜플의 요소는 0부터 시작하여 연속된 정수로 식별된다.
- map(또는 object): 와 같이 명명된 레이블로 식별되는 값 그룹이다 {name = "Mabel", age = 52}.
- null : 부재 또는 생략을 나타내는 값이다. 리소스의 인수를 로 설정하면 null Terraform은 인수를 완전히 생략한 것처럼 동작한다. 인수가 있는 경우 인수의 기본값을 사용하고 인수가 필수인 경우 오류를 발생한다.
- any : 'any' 유형은 변수가 string, number, bool, list, map, object, 등과 같은 모든 유형의 값을 허용할 수 있는 특수 유형 제약 조건이다.
리스트(list)와 튜플(tuple)의 차이
List
- list는 동일한 데이터 유형을 가진 값의 모음이다.
- list 내의 모든 요소가 동일한 데이터 유형을 공유해야 함을 의미하는 동종 데이터 구조이다.
- 문자열 목록, 숫자 목록, 지도 목록 등을 가질 수 있지만 단일 목록 내에서 다른 데이터 유형을 혼합할 수는 없습다.
- Terraform에서 list(<type>) 함수를 사용하여 목록을 정의할 수 있다.
variable "example_list" {
type = list(string)
default = ["value1", "value2", "value3"]
}
Tuple
- 튜플은 다른 데이터 유형을 가질 수 있는 값의 모음이다.
- 이기종 데이터 구조이다. 즉, 단일 튜플 내에서 데이터 유형이 다른 요소를 가질 수 있다.
- 튜플의 각 요소에는 특정 유형 제약이 있으며 튜플의 유형은 해당 요소 유형의 정렬된 조합에 의해 결정된다.
- Terraform에서 tuple(<types>) 함수를 사용하여 튜플을 정의할 수 있다.
variable "example_tuple" {
type = tuple([string, number, bool])
default = ("value1", 42, true)
}
인덱스 및 속성(Indices and Attributes)
elements of lists, tuples, maps, and objects 에 액세스하는 방법을 설명한다.
리스트 / 튜플 인덱스
- 리스트와 튜플의 요소는 인덱스가 정수인 대괄호 인덱스 표기법을 사용하여 액세스할 수 있다.
- 인덱싱은 0부터 시작한다
locals {
example_list = ["apple", "banana", "cherry"]
example_tuple = ["apple", 42, true]
}
output "list_element" {
value = local.example_list[1] # Output: "banana"
}
output "tuple_element" {
value = local.example_tuple[2] # Output: true
}
리스트 / 튜플 사용법
locals {
example_map = {
apple = "fruit"
number = 42
valid = true
}
example_object = {
apple = "fruit"
number = 42
valid = true
}
}
output "map_element_bracket" {
value = local.example_map["apple"] # Output: "fruit"
}
output "map_element_dot" {
value = local.example_map.apple # Output: "fruit"
}
output "object_element_bracket" {
value = local.example_object["number"] # Output: 42
}
output "object_element_dot" {
value = local.example_object.valid # Output: true
}
대괄호 사용법
값의 type이나 variables.tf 파일에 정의된 방식에 관계없이 값을 대괄호 '[]'로 묶어 단일 요소 목록을 만들 수 있다.
- 보통 variable 사용시 variable.tf 파일에 type을 지정한다.
- 리스트나 튜플 타입이 아니더라도 []를 붙이면 리스트나 튜플이 된다.
variable.tf
variable "example_string" {
type = string
default = "hello"
}
variable "example_map" {
type = map(string)
default = {
key1 = "value1"
key2 = "value2"
}
}
main.tf
locals {
single_element_string_list = [var.example_string] # ["hello"]
single_element_map_list = [var.example_map] # [{"key1"="value1", "key2"="value2"}]
}
output "single_element_string_list" {
value = local.single_element_string_list
}
output "single_element_map_list" {
value = local.single_element_map_list
}
2. Conditional Expressions(조건식)
조건식 은 bool 식의 값을 사용하여 두 값 중 하나를 선택합니다.
Syntax
condition ? true_val : false_val
- condition이 true이면 값은 true_val 이고 false 이면 false_val 이다.
var.a != "" ? var.a : "default-a"
- var.a가 비어있지않으면 true이고 결과는 var.a이가 나온다. 비어있으면 결과는 "default-a" 이다.
두 결과 값은 모든 유형일 수 있지만 Terraform이 조건 값을 모르고 전체 조건식이 반환할 유형을 결정할 수 있도록 둘 다 동일한 유형이여야 한다.
var.example ? tostring(12) : "hello"
Practice .tf code
variable.tf
variable "create" {
description = "Determines whether to create Fargate profile or not"
type = bool
default = true
}
variable "create_iam_role" {
description = "Determines whether an IAM role is created or to use an existing IAM role"
type = bool
default = true
}
- variable "create"
- 해당 변수는 bool 데이터 유형이며 기본값은 true이다. 해당 설명은 Fargate 프로필 생성 여부를 결정하는 데 사용됨을 나타낸다.
- variable "create_iam_role": 해당 변수에는 bool 데이터 유형이며 기본값은 true이다. 해당 설명은 새 IAM 역할을 생성할지 또는 기존 역할을 사용할지 결정하는 데 사용된다.
main.tf
data "aws_iam_policy_document" "assume_role_policy" {
count = var.create && var.create_iam_role ? 1 : 0
statement {
effect = "Allow"
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["eks-fargate-pods.amazonaws.com"]
}
}
}
- data "aws_iam_policy_document" "assume_role_policy": 이 데이터 블록은 역할 가정 정책에 대한 AWS IAM 정책 문서를 생성한다.
- count 매개변수를 사용하여 create 및 create_iam_role 변수의 값을 기반으로 정책 문서 생성을 제어한다.
- var.create와 var.create_iam_role이 모두 true이면 count 값이 1이 되고 정책 문서가 생성된다.
- var.create 또는 var.create_iam_role이 false인 경우 count 값은 0이 되고 정책 문서가 생성되지 않는다.
Result
Fargate 프로필과 IAM 역할의 생성을 제어하는 두 가지 변수를 정의한다. 또한 Amazon EKS Fargate 서비스가 IAM 역할을 맡도록 허용하는 역할 가정 정책에 대한 AWS IAM 정책 문서를 생성한다.
3. for Expressions
'for' 표현식을 사용하면 입력 컬렉션의 각 요소에 표현식을 적용하여 하나의 컬렉션(목록, 집합 또는 맵)을 다른 컬렉션으로 변환할 수 있다. 이는 새 컬렉션을 만들기 위해 값 컬렉션을 조작하거나 필터링해야 할 때 유용하다.
Syntax
[for <item> in <collection>: <result_expression>]
ex.)
[for s in var.list : upper(s)]
- <item>: 입력 <collection>의 각 요소를 나타내는 임시 변수이다.
- <collection>: 반복하려는 input list, set 또는 map이다.
- <result_expression>: 새 컬렉션의 요소를 생성하기 위해 각 <item>에 적용되는 표현식이다.
if 절을 추가하여 입력 컬렉션을 필터링할 수도 있다.
[for <item> in <collection>: <result_expression> if <condition>]
ex.)
[for s in var.list : upper(s) if s != ""]
Practice .tf code
variable.tf
variable "users" {
type = map(object({
is_admin = bool
}))
}
- type: 이 속성은 변수의 데이터 유형을 지정한다.
- 이 경우 bool 값을 보유하는 단일 키 "is_admin"이 있는 객체 map이다.
- 즉, "users" 변수는 각각 고유한 키(이름)와 사용자가 관리자인지 여부를 나타내는 bool 값이 있는 사용자 개체 모음이다.
terraform.tvars
users = {
"user1" = {
is_admin = true
}
"user2" = {
is_admin = false
}
"user3" = {
is_admin = true
}
}
main.tf
locals {
admin_users = {
for name, user in var.users : name => user
if user.is_admin
}
regular_users = {
for name, user in var.users : name => user
if !user.is_admin
}
}
- locals: 이 키워드는 하나 이상의 로컬 값을 정의하는 데 사용된다. "admin_users" 및 "regular_users"라는 두 개의 로컬 값이 정의된다.
- admin_users: 이 로컬 값은 "users" 변수를 필터링하여 "is_admin" 값이 true로 설정된 사용자만 포함하는 map을 생성한다. 이는 "for" 루프를 사용하여 수행되며 "users" 변수의 각 키-값 쌍(이름, 사용자)을 반복하고 "is_admin" 값이 true인 경우 새 map에 포함한다
- regular_users: 마찬가지로 이 로컬 값은 "users" 변수를 필터링하여 "is_admin" 값이 false로 설정된 사용자만 포함하는 새 map을 만든다. "for" 루프가 다시 사용되지만 이번에는 "is_admin"이 false로 설정된 사용자를 확인한다.
Result
즉, bool 속성이 "is_admin"인 사용자 개체 컬렉션을 보유하는 "users" 변수를 정의한다. 그런 다음 "is_admin" 특성을 기반으로 "users" 변수를 필터링하여 "admin_users" 및 "regular_users"라는 두 개의 로컬 값을 만들고 관리 사용자와 비관리 사용자에 대한 별도의 map을 만든다.
admin_users에는 "이름 : user1", "이름 : user3" 인 map이 생성되고,
admin_users = {
"user1" = {
is_admin = true
}
"user3" = {
is_admin = true
}
}
regular_users에는 "이름 : user2"인 map이 생성된다.
regular_users = {
"user2" = {
is_admin = false
}
}
4. dynamic Blocks
dynamic 블록은 collection(list, set 또는 map)을 기반으로 리소스 또는 모듈 내에 중첩된 블록을 동적으로 생성하는 데 사용된다. 생성할 중첩 블록의 수가 입력 데이터에 따라 달라지는 경우 특히 유용하며 유연하고 재사용 가능한 구성을 작성할 수 있다.
또한 특정 리소스 또는 모듈에 유효한 블록 유형을 제공해야 한다. 예를 들어 aws_security_group 리소스를 사용하는 경우 ingress, egress 또는 tags와 같은 유효한 블록 유형과 함께 dynamic 블록을 사용할 수 있다.
Syntax
resource "aws_elastic_beanstalk_environment" "tfenvtest" {
name = "tf-test-name" # can use expressions here
setting {
# but the "setting" block is always a literal block
}
}
Practice .tf code
AWS 보안 그룹 리소스가 있고 CIDR 블록 목록이 포함된 변수를 기반으로 여러 수신 규칙을 추가하려고 한다고 가정한다.
variable.tf
variable "cidr_blocks" {
type = list(string)
default = ["10.0.0.0/16", "192.168.1.0/24"]
}
main.tf
resource "aws_security_group" "example" {
name = "example"
dynamic "ingress" {
for_each = var.cidr_blocks
content {
from_port = 0
to_port = 0
protocol = "tcp"
cidr_blocks = [ingress.value]
}
}
}
Result
'dynmaic' 블록은 'var.cidr_blocks' 목록을 반복하고 목록의 각 CIDR 블록에 대해 'ingress' 블록을 생성한다. content 블록은 중첩된 ingress 블록의 구조를 정의하고 ingress.value는 반복의 현재 CIDR 블록을 나타낸다.
결과적으로 cidr_blocks 변수의 CIDR 블록 "10.0.0.0/16" 및 "192.168.1.0/24"를 사용하여 aws_security_group.example 리소스에 대해 두 개의 수신 규칙이 생성된다.
마지막으로 Terraform의 'dynamic' 블록을 사용하면 컬렉션을 기반으로 리소스 또는 모듈 내에 중첩된 블록을 생성하여 구성을 보다 유연하고 재사용 가능하게 만들 수 있다.
Reference
terraform expressions
terraform type
'IaC > Infrastructure Provisioning' 카테고리의 다른 글
1. Pulumi란? (0) | 2023.09.13 |
---|---|
Terraformer란? (0) | 2023.05.04 |
4. Terraform의 다양한 Function(함수) (0) | 2023.04.11 |
3. Terraform 다양한 변수(variable, local, data...output, input) - AWS (0) | 2023.04.09 |
2. Terraform 변수 사용법(use-variable) - AWS (0) | 2023.04.05 |