IaC(Infrastructure as Code)

AWS + Terraform (For-Each)

cwchoiit 2024. 3. 6. 21:49
728x90
반응형
SMALL
728x90
SMALL

이번에는 HCL의 for-each문을 활용해서 여러개의 리소스를 만들어보자.

 

count

우선, for-each를 사용하기 전 count를 먼저 사용해보자. 이 count는 HCL에서 예전부터 있던 기능인데 이 기능에 대한 문제점을 보완하고자 for-each가 나왔다고 생각하면 된다. 우선 코드를 바로 보자.

# ---------
# count

provider "aws" {
  region = "ap-northeast-2"
}

resource "aws_iam_user" "count" {
  count = 5
  name  = "count-user-${count.index}"
}

output "count_user_arns" {
  value = aws_iam_user.count.*.arn
}

 

이 코드에서 "count = 5"를 보면 5개를 만들어낼 것을 예측할 수 있다. 그리고 이 count는 자체적으로 가지는 변수 index라는 것이 있다. 그래서 aws_iam_user를 만들어낼 때 그 이름을 count.index로 변형을 주어 5명의 사용자를 만들어낸다.

 

그리고 output을 보면 aws_iam_user.count 리소스가 리스트로 만들어지는데 [count-user-0, count-user-2, ..., count-user-9] 이런식으로 말이다. 그러면 그 각각의 유저들의 arn을 output으로 지정한다는 뜻이다.

 

이 코드를 Init - Apply 해보자. Apply 결과는 다음과 같다. 잘 만들어졌지만 다음 사진이 바로 count의 문제점이다. 

인덱스로 각각의 리소스를 나타내기 때문에 그래서 0번이 누구인지, 1번이 누구인지 알아보기가 상당히 까다롭고, 만약 아래처럼 0, 1, 2, 3, 4 총 5명의 유저가 있을 때 2번 유저를 삭제하면 3, 4이 한칸씩 앞으로 옮겨지게된다. 이러면 또 골머리가 아파진다.

 

AWS Console에서 확인해보면 다음과 같이 잘 만들어졌음을 확인할 수 있다.

 

 

For-Each

For-Each는 Set/Map을 지원한다. Set은 리스트인데 유니크한 값만을 가지는 리스트이고, Map은 {"key": "value", ...} 이러한 형식이다. 바로 코드를 보자. 다음은 Set을 사용한 For-Each문이다.

# ForEach (Set)

resource "aws_iam_user" "for_each_set" {
  for_each = toset([
    "for-each-set-user-1",
    "for-each-set-user-2",
    "for-each-set-user-3",
  ])

  name = each.key
}

output "for_each_set_user_arns" {
  value = values(aws_iam_user.for_each_set).*.arn
}

For-Each의 Set을 사용하면 자체적으로 제공하는 key라는 property가 존재한다. 그래서 사용자 이름을 each.key로 지정했다. 

output을 보면 values()를 사용한다. 이는 aws_iam_user.for_each_set 이라는 리소스는 다음과 같이 생겼다.

for-each-set-user-1: {...}
for-each-set-user-2: {...}
for-each-set-user-3: {...}

그래서 각각의 value가 {...} 이 부분인데 이것 전체를 가져온다는 의미가 values(aws_iam_user.for_each_set)이다. 그래서 그 모양은 [{...}, {...}, ..] 이렇게 될 것이다. 그리고 그 각각의 value가 가지는 모든것을 의미하는 '*'에서 arn을 찍어낸다.

 

Apply를 해보자. 결과는 다음과 같다.

 

AWS Console에서도 확인해보자. 잘 만들어졌다.

 

다음은 Set이 아닌 Map으로 ForEach를 사용해보자. 뭐 크게 달라지는 건 없다. Map이니까 데이터 모양새가 좀 다를것이고 더 많은 정보가 들어갈 수 있을 것 같다.

# ForEach (Map)

resource "aws_iam_user" "for_each_map" {
  for_each = {
    "alice" = {
      level   = "low"
      manager = "chyonee"
    }
    "bob" = {
      level   = "mid"
      manager = "chyonee"
    }
    "john" = {
      level   = "high"
      manager = "chyonee"
    }
  }

  name = each.key
  tags = each.value
}

output "for_each_map_user_arns" {
  value = values(aws_iam_user.for_each_map).*.arn
}

 

Apply 해보자. 잘 만들어졌다.

적용한 태그 역시 잘 들어갔다.

 

 

결론

같은 형태의 리소스를 여러번 만들기위해 반복문(For-Each)을 사용해봤다. 

728x90
반응형
LIST

'IaC(Infrastructure as Code)' 카테고리의 다른 글

AWS + Terraform (Loop)  (0) 2024.03.07
AWS + Terraform (Conditions)  (0) 2024.03.07
AWS + Terraform (Module)  (0) 2024.03.06
AWS + Terraform  (2) 2024.03.05
Terraform 소개 및 간단하게 다루어보기  (0) 2024.03.05