terraform으로 여러 자원을 만들고 싶을 때count와 for무엇으로

15518 단어 AWSTerraformtech
terraform에서 여러 자원을 만들 때count 또는 foreach를 써야 될 것 같아요.
양자를 정확하게 구분하기 위해 각자의 행동을 총결하였다.
소스 코드는 여기.

카탈로그

  • count의 경우
  • for_each의 경우
  • 요약
  • 1.count의 경우


    count로 여러 자원 만들기


    count의 행동을 확인하기 위해 서브넷을 만듭니다.
    resource "aws_vpc" "this" {
      cidr_block  = var.cidr_block
    }
    
    resource "aws_subnet" "public" {
      count = length(var.public_blocks)
    
      vpc_id            = aws_vpc.this.id
      cidr_block        = element(var.public_blocks, count.index)
      availability_zone = element(var.availability_zones, count.index)
    }
    
    locals {
      region = "ap-northeast-1"
    }
    
    module "count" {
      source = "./count"
    
      cidr_block         = "10.0.0.0/16"
      public_blocks      = ["10.0.1.0/24", "10.0.2.0/24"]
      availability_zones = ["${local.region}a", "${local.region}c"]
    }
    
    count는 만들 자원의 수량을 지정하여 여러 자원을 만들 수 있습니다.
    만들고자 하는 자원의 수량for_each만 지정하면 더욱 간단하게 설명할 수 있습니다.

    output에서 여러 자원을 만들 때


    output "subnet_ids" {
      value = aws_subnet.public.*.id
    }
    
    count에서 제작한 자원을 참조하고 싶을 때*list를 사용하면 얻을 수 있다.
    subnet_ids = [
      "subnet-01eb09ab26904e369",
      "subnet-06c6128ce474cd3eb",
    ]
    
    단, ap-northeast-1a의 서브넷을 참고하려면 다음과 같다.
    module.count.subnet_ids[0]
    
    및 지정된 패턴의 번호로 참조되는 리소스는 무엇입니까?
    이해가 안되네.뒤에 설명for_each하면 이 문제를 해결할 수 있습니다.

    리소스를 삭제하려는 경우


    중간에 AZ가 서브넷ap-northeast-1a을 삭제하려고 합니다.
    module "count" {
      source = "./count"
    
      cidr_block         = "10.0.0.0/16"
      public_blocks      = ["10.0.2.0/24"]
      availability_zones = ["${local.region}c"]
    }
    
    이렇게 플랜을 고쳐 쓰면
    Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
      - destroy
    -/+ destroy and then create replacement
    
    Terraform will perform the following actions:
    
      # module.count.aws_subnet.public[0] must be replaced
    -/+ resource "aws_subnet" "public" {
          ~ arn                             = "arn:aws:ec2:ap-northeast-1:76345784206:subnet/subnet-06f995d8d74733a4b" -> (known after apply)
          ~ availability_zone               = "ap-northeast-1a" -> "ap-northeast-1c" # forces replacement
          ~ availability_zone_id            = "apne1-az4" -> (known after apply)
          ~ cidr_block                      = "10.0.1.0/24" -> "10.0.2.0/24" # forces replacement
          ~ id                              = "subnet-06f995d8d74733a4b" -> (known after apply)
          + ipv6_cidr_block_association_id  = (known after apply)
          - map_customer_owned_ip_on_launch = false -> null
          ~ owner_id                        = "762742784206" -> (known after apply)
          - tags                            = {} -> null
          ~ tags_all                        = {} -> (known after apply)
            # (3 unchanged attributes hidden)
        }
    
      # module.count.aws_subnet.public[1] will be destroyed
      - resource "aws_subnet" "public" {
          - arn                             = "arn:aws:ec2:ap-northeast-1:76274484206:subnet/subnet-0bd46cfab1a7d126e" -> null
          - assign_ipv6_address_on_creation = false -> null
          - availability_zone               = "ap-northeast-1c" -> null
          - availability_zone_id            = "apne1-az1" -> null
          - cidr_block                      = "10.0.2.0/24" -> null
          - id                              = "subnet-0bd46cfab1a7d126e" -> null
          - map_customer_owned_ip_on_launch = false -> null
          - map_public_ip_on_launch         = false -> null
          - owner_id                        = "762742784206" -> null
          - tags                            = {} -> null
          - tags_all                        = {} -> null
          - vpc_id                          = "vpc-00e075e18377e14b8" -> null
        }
    
    Plan: 1 to add, 0 to change, 2 to destroy.
    
    이렇게 리플렉스module.count.aws_subnet.public[0]하는 행위.
    이럴 때 가능하면 ap-northeast-1c의 서브넷을 보존하세요.
    서브넷을 삭제하고 싶은데 아쉽게도 안 됩니다.
    state를 직접 수정하기만 하면 기존의 서브넷을 보존하여 수정할 수 있습니다.
    일단 스테이트부터 확인해.
    ❯ terraform state list  
    module.count.aws_subnet.public[0]
    module.count.aws_subnet.public[1]
    module.count.aws_vpc.this
    
    다음에 ap-northeast-1a 이외의 적당한 번호를 분배한다.
    terraform state mv module.count.aws_subnet.public[0] module.count.aws_subnet.public[10]
    
    그리고 module.count.aws_subnet.public[0] 1변경
    terraform state mv module.count.aws_subnet.public[1] module.count.aws_subnet.public[0]
    
    이 상태에서 플랜을 실행할 때...
    Terraform will perform the following actions:
    
      # module.count.aws_subnet.public[10] will be destroyed
      - resource "aws_subnet" "public" {
          - arn                             = "arn:aws:ec2:ap-northeast-1:762742784206:subnet/subnet-0850badcdfdf2d6b9" -> null
          - assign_ipv6_address_on_creation = false -> null
          - availability_zone               = "ap-northeast-1a" -> null
          - availability_zone_id            = "apne1-az4" -> null
          - cidr_block                      = "10.0.1.0/24" -> null
          - id                              = "subnet-0850badcdfdf2d6b9" -> null
          - map_customer_owned_ip_on_launch = false -> null
          - map_public_ip_on_launch         = false -> null
          - owner_id                        = "762742784206" -> null
          - tags                            = {} -> null
          - tags_all                        = {} -> null
          - vpc_id                          = "vpc-079d79a4be16828a8" -> null
        }
    
    Plan: 0 to add, 0 to change, 1 to destroy.
    
    module.count.aws_subnet.public[1]그렇죠!
    이렇게 하면 module.count.aws_subnet.public[0]의 서브넷만 삭제됩니다.

    2. for_each 사용 시


    for_each에 여러 자원 만들기


    count처럼 foreach의 행동을 확인하고 싶어서 자원을 만들어 봤어요.
    resource "aws_vpc" "this" {
      cidr_block = var.cidr_block
    }
    
    resource "aws_subnet" "public" {
      for_each = var.public_subnets
    
      vpc_id            = aws_vpc.this.id
      cidr_block        = each.value.cidr_block
      availability_zone = each.key
    }
    
    locals {
      public_subnets = {
        ap-northeast-1a = {
          cidr_block = "10.0.64.0/24"
        }
        ap-northeast-1c = {
          cidr_block = "10.0.65.0/24"
        }
      }
    }
    
    module "for_each" {
      source = "./for_each"
    
      cidr_block     = "10.0.0.0/16"
      public_subnets = local.public_subnets
    }
    
    for_1 to destroyap-northeast-1a를 each에 건네주다.mapset에서
    각자의 키와value를 참조할 수 있습니다.

    output에서 만든 자원을 원할 때


    output "public_1a_id" {
      value = aws_subnet.public["ap-northeast-1a"].id
    }
    
    output "subnet_ids" {
      value = [ for value in aws_subnet.public : value.id ]
    }
    
    each.value제작 때와 달리 얻으려면 주의해서 사용하십시오for 문장.
    또한 리소스를 참조하려는 경우 위에서 설명한 대로 each.key키는 count 제작할 때보다 각 자원을 참고하기 쉽다.

    리소스를 삭제하려는 경우


    locals {
      public_subnets = {
        ap-northeast-1c = {
          cidr_block = "10.0.65.0/24"
        }
      }
    }
    
    list의 서브넷을 삭제하고 실행aws_subnet.public["ap-northeast-1a"]해 보십시오.
    Terraform will perform the following actions:
    
      # module.for_each.aws_subnet.public["ap-northeast-1a"] will be destroyed
      - resource "aws_subnet" "public" {
          - arn                             = "arn:aws:ec2:ap-northeast-1:76276724206:subnet/subnet-0f966e9cd41aaf87c" -> null
          - assign_ipv6_address_on_creation = false -> null
          - availability_zone               = "ap-northeast-1a" -> null
          - availability_zone_id            = "apne1-az4" -> null
          - cidr_block                      = "10.0.64.0/24" -> null
          - id                              = "subnet-0f966e9cd41aaf87c" -> null
          - map_customer_owned_ip_on_launch = false -> null
          - map_public_ip_on_launch         = false -> null
          - owner_id                        = "762742784206" -> null
          - tags                            = {} -> null
          - tags_all                        = {} -> null
          - vpc_id                          = "vpc-06767e6aec20a67ca" -> null
        }
    
    Plan: 0 to add, 0 to change, 1 to destroy.
    
    와count가 다르면state를 수정하지 않은 상태에서 특정한 자원을 삭제할 수 있습니다.

    3. 요약


    다른 리소스를 만들 때 대상 리소스를 참조할 필요가 없으며 단순히 여러 개의 리소스를 만들 수 있습니다.
    이러한 경우count 서브넷처럼 각 리소스를 참조해야 하는 경우ap-northeast-1a와는 따로 사용하는 것이 좋습니다.

    참고 자료


    https://www.terraform.io/docs/language/meta-arguments/count.html
    https://www.terraform.io/docs/language/meta-arguments/for_each.html

    좋은 웹페이지 즐겨찾기