개요
Meta-Argument는 Resource 나 Module에서 사용할 수 있는 Terraform의 특수한 아규먼트이다.
이 글에서는 Resource에 사용할 수 있는 Meta-Argument 중 count와 for_each를 소개한다.
1️⃣ count
하나의 Resource 혹은 Module에서 여러 인프라 리소스를 만들어내고 싶을 때 사용하는 Meta-Argument이다.
- 숫자 표현식을 허용한다.
- 생성할 인스턴스가 거의 동일한경우 for_each 보다는 count 사용이 적절하다.
기본 구문
- 예시 1.
resource "aws_instance" "server" {
count = 4 # create four similar EC2 instances
ami = "ami-a1b2c3d4"
instance_type = "t2.micro"
tags = {
Name = "Server ${count.index}"
}
}
- 예시 2.
resource "aws_ec2_tag" "private_subnet_tag" {
count = length(module.vpc.private_subnets)
resource_id = module.vpc.private_subnets[0]
key = "Name"
value = "${var.name_prefix}private-${count.index}"
}
추가 Object
아래의 추가 object를 사용할 수 있다.
- count.index [0] : 인스턴스에 해당하는 고유의 인덱스 번호로 시작한다.
- 인덱스 번호는 0부터 시작한다.
❗ count 사용 시 리소스를 인덱스로 식별할 수 있기 때문에 취약하다.
list의 요소 중 중간 요소가 삭제된다면 의도치 않은 변경사항이 발생할 수 있음.
2️⃣ for_each
하나의 Resource 혹은 Module에서 여러 인프라 리소스를 만들어내고 싶을 때 사용하는 Meta-Argument이다.
- map 혹은 set 형식을 사용할 수 있다.
- for_each의 map 또는 set의 각 항목에 대해 인스턴스를 생성한다.
기본 구문
- 예시 1. map 형식의 for_each
resource "azurerm_resource_group" "rg" {
for_each = {
a_group = "eastus"
another_group = "westus2"
}
name = each.key
location = each.value
}
- 예시 2. set 형식의 for_each
resource "aws_iam_user" "the-accounts" {
for_each = toset( ["Todd", "James", "Alice", "Dottie"] )
name = each.key
}
- 예시 3. 하위모듈
# my_buckets.tf
module "bucket" {
for_each = toset(["assets", "media"])
source = "./publish_bucket"
name = "${each.key}_bucket"
}
# publish_bucket/bucket-and-cloudfront.tf
variable "name" {} # this is the input parameter of the module
resource "aws_s3_bucket" "example" {
# Because var.name includes each.key in the calling
# module block, its value will be different for
# each instance of this module.
bucket = var.name
# ...
}
resource "aws_iam_user" "deploy_user" {
# ...
}
추가 object
아래의 추가 object를 사용할 수 있다.
- each.key : map 혹은 set의 Key 값이다.
- each.value : map 혹은 set의 Value 값이다.
- 만약 set 형식일 경우 each.value의 결괏값은 each.key와 동일하다.
유의사항
- map 혹은 set 은 known values이어야 한다. 아니라면 -target이 필요하다는 오류 메시지가 표시된다.
- for_each의 결괏값은 항상 UI에 출력되므로 민감한 변수들은 넣지 말자.
Expression
- for_each 인수는 원하는 인스턴스당 하나의 element로 설정된 map이어야 한다.
- 만약, for_each의 인수가 element가 아니라면 toset() 함수를 사용하여 값을 명시적으로 반환하는 식을 사용할 수 있다.
- for_each는 변환 중에 의도치 않은 결과를 방지하기 위하여 암묵적으로 변환하지 않는다.
- 예를 들면 tuple → set 자동 변환..
- 만약 tuple 같은 구조화된 유형을 변환하고자 한다면 flatten() 함수를 이용할 수도 있다.
- 만약, 입력변수로 set 형식을 사용한다면 입력변수의 type을 set(string)으로 지정하면 명시적 유형 변환이 필요하지 않다.
- toset()을 사용하여 명시적으로 유형 변환을 하지 않아도 된다.
'Devops > Terraform' 카테고리의 다른 글
[Terraform] Configuration Syntax (0) | 2022.12.30 |
---|---|
[Terraform] Types (0) | 2022.12.26 |
[Terraform] Terragrunt와 Terraform Cloud(TFC) 연동해보기 (1) | 2022.12.16 |
[Terraform] README.md 작성 자동화 프로그램 ‘Terraform Docs’ 간단소개 (0) | 2022.09.11 |
[Terraform] Terraform으로 만든 AWS ECS에 Codedeploy를 이용하여 Blue/Green 배포 (0) | 2022.08.30 |