Ssoon

[5주차] 05 테라폼의 팁과 요령 (1) 반복문 - for_each 본문

Terraform 101 Study

[5주차] 05 테라폼의 팁과 요령 (1) 반복문 - for_each

구구달스 2022. 11. 15. 23:10
CloudNet@ 팀의 가시다님이 진행하는 Terraform 101 Study 05주차 정리입니다.

TREE

 

GitHub - kschoi728/T101: Terraform 101 Study

Terraform 101 Study. Contribute to kschoi728/T101 development by creating an account on GitHub.

github.com

for_each 을 사용하면 lists, sets, maps 을 사용하여 전체 resource 의 여러 복사본 또는 resource 내 Inline Block 의 여러 복사본을 생성할 수 있습니다. 

 

resource "<PROVIDER>_<TYPE>" "<NAME>" {

  for_each = <COLLECTION>

  [CONFIG...]

}

 

  • PROVIDER : AWS 와 같은 공급자의 이름
  • TYPE : 생성할 resource 의 유형
  • NAME : 테라폼 코드 전체에서 이 resource 를 참조하기 위해 사용할 식별자
  • COLLECTION : 반복을 처리할 set 또는 map (resource 에 for_each 를 사용할 때 lists 는 지원하지 않습니다.)
  • CONFIG : 해당 resource 와 관련된 하나 이상의 argument 로 구성
    • CONFIG 내에서 each.key 또는 each.value 를 사용하여 COLLECTION 에서 현재 항목의 key 와 vaule 에 접근 할 수 있습니다.

live/global/three-iam-users-for-each/main.tf 

   👉 for_each 를 사용하여 3명의 IAM 사용자를 생성합니다.

resource "aws_iam_user" "main" {
  for_each = toset(var.user_names)
  name     = each.value
}

  ✔ var.user_name list 를 set(집합)으로 변환하기 위해 toset 을 사용합니다.

  ✔ for_each 는 resource 에서 사용될 때만 set 과 map 을 지원하기 때문입니다.

  ✔ for_each 가 이 set(집합)을 반복하면 each.value 에서 각 사용자 이름을 사용할 수 있습니다.

 

resource 에 대해 for_each를 사용하면 하나의 resource 또는 count와 같은 resource array(배열)이 아닌 resource map이 됩니다.

 

 live/global/three-iam-users-for-each/outputs.tf 

output "all_arns" {
  value = values(aws_iam_user.main)[*].arn
}

output "all_users" {
  value = aws_iam_user.main
}

📢 CLI 확인

 

1️⃣ for_each 를 사용해 resource 를 map 으로 처리하면, COLLECTION 중간의 항목도 안전하게 제거할 수 있습니다.   

 👉 resource 의 여러 복사본을 만들 때에는 count 대신 for_each 를 사용하는 것이 바람직합니다.

 

2️⃣ resource 내에서 여러 개의 Inline Block 을 만들 수 있습니다.

 ✅ webserver-cluster module 에서  ASG 에 대한 tag Inline Block 을 동적으로 생성할 수 있습니다.

 

modules/services/webserver-cluster/variables.tf

 👉 custom_tags 라는 새로운 map 입력 변수를 추가합니다.

variable "custom_tags"

variable "custom_tags" {
  description = "Custom tags to set on the Instances in the ASG"
  type        = map(string)
  default     = {}
}

prod/services/webserver-cluster/main.tf

 👉 사용자 정의 태그를 설정합니다

custom_tag = {
    Owner     = "team-Ssoon"
    ManagedBy = "terraform"
  }

module "webserver_cluster" {
  source = "../../../modules/services/webserver-cluster"

  cluster_name  = "ssoon-stage"
  instance_type = "t2.micro"
  min_size      = 2
  max_size      = 2

  custom_tag = {
    Owner     = "team-Ssoon"
    ManagedBy = "terraform"
  }
}

 

📌 for_each 를 사용하여 Inline Block 을 동적으로 생성하는 구문

dynamic "<VAR_NAME>" {

  for_each = <COLLECTION>

  content {

    [CONFIG...]

  }

}

  • VAR_NAME : 각 'iteration(반복)' 값을 저장할 변수에 사용할 이름
  • COLLECTION : 반복되는 list 또는 map
  • content : 각 반복에서 생성되는 항목

 modules/services/webserver-cluster/main.tf

 👉 content 블록 내에서 <VAR_NAME>.key 및 <VAR_NAME>.value 를 사용해 COLLECTION 에 있는 현재 항목의 key 와 value 값에 각각 액세스할 수 잇습니다.

  ✔ for_each 를 list 와 함께 사용 -> key:index , value:해당 index 목록에 있는 항목

  ✔ for_each 를 map 과 함께 사용 -> key, value : map의 key-value 쌍 중 하나

 

  dynamic "tag" {
    for_each = var.custom_tags

    content {
      key                 = tag.key
      value               = tag.value
      propagate_at_launch = true
    }

resource "aws_autoscaling_group" "ssoon_asg" {
  name                 = "ssoon_asg"
  launch_configuration = aws_launch_configuration.ssoon_lauchconfig.name
  vpc_zone_identifier  = [aws_subnet.ssoon_subnet1.id, aws_subnet.ssoon_subnet2.id]
  min_size             = var.min_size
  max_size             = var.max_size
  health_check_type    = "ELB"
  target_group_arns    = [aws_lb_target_group.ssoon_albtg.arn]

  tag {
    key                 = "Name"
    value               = "${var.cluster_name}-asg"
    propagate_at_launch = true
  }

  dynamic "tag" {
    for_each = var.custom_tags

    content {
      key                 = tag.key
      value               = tag.value
      propagate_at_launch = true
    }
  }
}

📢 CLI 확인

😱 key:value -> terraform plan 화살표가 잘못되었네요~!

 

🚩 Console 확인

Comments