클라우드에서 인프라를 구축을 할 때 비용 절감, 배포 속도 향상, 일관성, 안정성 및 재사용성을 고려하여 웹 콘솔로 구축하기보다는 IaC(Infrastructure as Code) 도구를 활용하여 구축하는 것이 좋습니다. 오픈소스이며 IaC 도구 중 가장 많이 사용하는 것이 Terraform입니다. Terraform 코드를 효율적이고 효과적으로 작성하기 위해서는 Terraform에서 제공되는 기능들을 적절하게 사용하는 것이 중요합니다. 그렇지 않으면 예상과 다른 결과가 발생할 수 있습니다. 이번 글에서는 Terraform에서 제공하는 각 반복문의 특징과 차이점을 알아보겠습니다.
Terraform 반복문
일반적인 선언적 언어는 반복문이 없지만, Terraform에서는 다양한 함수를 지원하여 반복문을 사용할 수 있습니다.
대표적으로 사용하는 반복문은 count, for_each가 있습니다. 각각의 특징은 아래와 같습니다.
- count 매개 변수: 리소스와 모듈을 반복
- for_each 표현식: 리소스 및 리소스 내의 인라인 블록과 모듈 반복
각 반복문의 사용 방법을 요약하자면,
- 생성하려는 리소스가 거의 동일하고 변경되지 않을 때
count
를 활용한다면 빠르고 간결하게 생성할 수 있습니다. - 고유한 이름, 데이터가 들어 있는 리소스, 재생성되지 말아야 할 리소스 등에는
for_each
를 활용한다면 안전하게 생성 및 변경할 수 있습니다.
Terraform 코드를 실행해 보면서 count
와 for_each
의 차이점에 대해 알아보겠습니다.
Count
count
매개 변수는 정수를 허용하고 전체 리소스, 모듈을 반복하여 만들 수 있습니다.
count
로 구성하게 되면 count.index
를 활용하여 count
에서 생성한 인덱스에 접근 가능합니다.
아래 코드는 AWS IAM 사용자를 생성하는 코드입니다.
만약 3명의 사용자를 생성하려면 어떻게 해야 할까요?
Terraform 리소스에서 사용할 수 있는 count
를 활용하여 단순하게 반복할 수 있습니다.
resource "aws_iam_user" "Rei" {
name = "Rei"
}
아래 코드에서 count
를 사용하지만 생성되지 않습니다.
IAM 사용자의 이름은 고유해야 생성할 수 있는데 이름이 같아서 오류가 발생합니다.
count
는 단순히 생성할 리소스의 수를 반복하여 작업하기 때문입니다.
resource "aws_iam_user" "count" {
count = 3
name = "Rei"
}
count.index
를 사용하여 이름 뒤에 인덱스를 추가하여 고유한 이름을 만들 수 있습니다.
resource "aws_iam_user" "count" {
count = 3
name = "Rei${count.index}"
}
terraform apply
명령을 사용하면 생성하려는 리소스가 리스트로 저장되는 것을 확인할 수 있고, IAM 사용자 에 Rei0, Rei1, Rei2가 생성된다는 것을 확인할 수 있습니다.
# aws_iam_user.count[0] will be created
+ resource "aws_iam_user" "count" {
+ name = "Rei0"
(...)
}
# aws_iam_user.count[1] will be created
+ resource "aws_iam_user" "count" {
+ name = "Rei1"
(...)
}
# aws_iam_user.count[2] will be created
+ resource "aws_iam_user" "count" {
+ name = "Rei2"
(...)
}
Input Variable을 이용한 Count 활용
만들고 싶은 IAM 사용자를 리스트 타입의 variable
로 선언하고, length
내장 함수를 활용하여 리소스를 생성할 수 있습니다.
variable "user_name" {
type = list(string)
default = ["joe", "kim", "lee", "park"]
}
resource "aws_iam_user" "count" {
count = length(var.user_name)
name = var.user_name[count.index]
}
위와 같이 리소스에 count
를 사용하게 되면 각각의 리소스가 아니라 리소스의 배열로 저장됩니다.
apply
명령 및 tfstate
에서 확인 가능합니다.
IAM 사용자에 joe
, kim
, lee
, park
이 생성된다는 것을 확인할 수 있습니다.
# aws_iam_user.count[0] will be created
+ resource "aws_iam_user" "count" {
+ name = "joe"
(...)
}
# aws_iam_user.count[1] will be created
+ resource "aws_iam_user" "count" {
+ name = "kim"
(...)
}
# aws_iam_user.count[2] will be created
+ resource "aws_iam_user" "count" {
+ name = "lee"
(...)
}
# aws_iam_user.count[3] will be created
+ resource "aws_iam_user" "count" {
+ name = "park"
(...)
}
Output Value에서 Count 활용
각 리소스에 대한 출력 값을 읽으려면, 해당 리소 스가 배열로 저장되었으므로 인덱스를 지정하여 속성을 읽을 수 있습니다.
인덱스 대신 *
을 사용하면 모든 인덱스 조회가 가능합니다.
output "first_arn"{
value = aws_iam_user.count[0].arn
}
output "all_arn"{
value = aws_iam_user.count[*].arn
}
Outputs:
first_arn = "arn:aws:iam::<num>:user/joe"
all_arn = [
"arn:aws:iam::<num>:user/joe",
"arn:aws:iam::<num>:user/kim",
"arn:aws:iam::<num>:user/lee",
"arn:aws:iam::<num>:user/park",
]