Terraformのfor_eachとcountを書き比べてみた

Terraformのfor_eachとcountを書き比べてみた

2026.01.29

はじめに

クラウド事業本部、あきやまです。
Terraformコードを書くのって楽しいですよね。
少しでも効率的にコードを記載するため、for_eachとcountを利用する場面があると思います。
様々な技術ブログを見ているとfor_eachを推奨するものが多いのですが、なぜ推奨されているのか興味があり、今回はブログにまとめていきたいと思います。

環境

サービス バージョン
macOS Sequoia(15.7.3)
チップ Apple M1
AWS CLI aws-cli/2.32.6
Terraform Version 1.14.3
AWS Provider 6.28.0

準備

TerraformからAWS操作が可能であること

ゴール

今回はVPCとプライベートサブネットを2つ作成する中で、以下にどのような差があるか確認していきたいと思います。

  • コードの記載方法によって、plan時、apply時にどのような変化があるか理解する
  • リソースに変更を加えた際の挙動を確認する

やってみた

参照したリソースは以下となります。
https://developer.hashicorp.com/terraform/language/meta-arguments/for_each
https://developer.hashicorp.com/terraform/language/meta-arguments/count
利用したコードは以下になります。
コードだけで見ると、記述量に大きな差があるわけではなさそうです。
for_eachで記述したコードです。

for_each
provider "aws" {
  region = "ap-northeast-1"
}

terraform {
  required_version = "~> 1.14.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.28.0"
    }
  }
}

# ===========================================
# 変数定義
# ===========================================
variable "subnets" {

  type = map(object({
    cidr_block        = string
    availability_zone = string
  }))
  default = {
    "1a" = {
      cidr_block        = "10.0.0.0/24"
      availability_zone = "ap-northeast-1a"
    }
    "1c" = {
      cidr_block        = "10.0.1.0/24"
      availability_zone = "ap-northeast-1c"
    }
  }
}

# ===========================================
# VPC
# ===========================================
resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"

  tags = {
    Name = "for-each-vpc"
  }
}

# ===========================================
# サブネット
# ===========================================
resource "aws_subnet" "main" {
  for_each = var.subnets

  vpc_id            = aws_vpc.main.id
  cidr_block        = each.value.cidr_block
  availability_zone = each.value.availability_zone

  tags = {
    Name = "for-each-subnet-${each.key}"
  }
}

# ===========================================
# 作成されたサブネットのidを出力
# ===========================================
output "subnet_ids" {
  description = "作成されたサブネットID(キー名参照)"
  value = {
    public  = aws_subnet.main["1a"].id
    private = aws_subnet.main["1c"].id
  }
}

続いてはcountで記述したコードです。

count
provider "aws" {
  region = "ap-northeast-1"
}

terraform {
  required_version = "~> 1.14.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.28.0"
    }
  }
}

# ===========================================
# VPC
# ===========================================
resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"

  tags = {
    Name = "count-vpc"
  }
}

# ===========================================
# サブネット
# ===========================================
resource "aws_subnet" "main" {
  count = 2

  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.${count.index}.0/24"
  availability_zone = "ap-northeast-1${count.index == 0 ? "a" : "c"}"

  tags = {
    Name = "count-subnet-${count.index}"
  }
}

# ===========================================
# 作成されたサブネットのidを出力
# ===========================================
output "subnet_ids" {
  value = {
    subnet_0 = aws_subnet.main[0].id
    subnet_1 = aws_subnet.main[1].id
  }
}

では早速、applyまでやっていきましょう。
※initの実行結果については両コードで差分がない為、1回分の結果を載せています。

init 実行結果
$ terraform init                                 

Initializing the backend...
Initializing provider plugins...
- Reusing previous version of hashicorp/aws from the dependency lock file
- Using previously-installed hashicorp/aws v6.28.0

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

planでは表示結果に差が現れました。
for_eachではvariablesに指定しているkey(1a、1c)を元にサブネットを作成していることがわかります。
countでは今回サブネットを2つ作成するよう「count = 2」で指定しているため、インデックス番号「0、1」という形でサブネットが作成されていることがわかります。
※0は1aに配置され、1は1cに配置されています。

plan 実行結果(for_each)
$ terraform plan

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_subnet.main["1a"] will be created
  + resource "aws_subnet" "main" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "ap-northeast-1a"
      + availability_zone_id                           = (known after apply)
      + cidr_block                                     = "10.0.0.0/24"
      + enable_dns64                                   = false
      + enable_resource_name_dns_a_record_on_launch    = false
      + enable_resource_name_dns_aaaa_record_on_launch = false
      + id                                             = (known after apply)
      + ipv6_cidr_block_association_id                 = (known after apply)
      + ipv6_native                                    = false
      + map_public_ip_on_launch                        = false
      + owner_id                                       = (known after apply)
      + private_dns_hostname_type_on_launch            = (known after apply)
      + region                                         = "ap-northeast-1"
      + tags                                           = {
          + "Name" = "for-each-subnet-1a"
        }
      + tags_all                                       = {
          + "Name" = "for-each-subnet-1a"
        }
      + vpc_id                                         = (known after apply)
    }

  # aws_subnet.main["1c"] will be created
  + resource "aws_subnet" "main" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "ap-northeast-1c"
      + availability_zone_id                           = (known after apply)
      + cidr_block                                     = "10.0.1.0/24"
      + enable_dns64                                   = false
      + enable_resource_name_dns_a_record_on_launch    = false
      + enable_resource_name_dns_aaaa_record_on_launch = false
      + id                                             = (known after apply)
      + ipv6_cidr_block_association_id                 = (known after apply)
      + ipv6_native                                    = false
      + map_public_ip_on_launch                        = false
      + owner_id                                       = (known after apply)
      + private_dns_hostname_type_on_launch            = (known after apply)
      + region                                         = "ap-northeast-1"
      + tags                                           = {
          + "Name" = "for-each-subnet-1c"
        }
      + tags_all                                       = {
          + "Name" = "for-each-subnet-1c"
        }
      + vpc_id                                         = (known after apply)
    }

  # aws_vpc.main will be created
  + resource "aws_vpc" "main" {
      + arn                                  = (known after apply)
      + cidr_block                           = "10.0.0.0/16"
      + default_network_acl_id               = (known after apply)
      + default_route_table_id               = (known after apply)
      + default_security_group_id            = (known after apply)
      + dhcp_options_id                      = (known after apply)
      + enable_dns_hostnames                 = (known after apply)
      + enable_dns_support                   = true
      + enable_network_address_usage_metrics = (known after apply)
      + id                                   = (known after apply)
      + instance_tenancy                     = "default"
      + ipv6_association_id                  = (known after apply)
      + ipv6_cidr_block                      = (known after apply)
      + ipv6_cidr_block_network_border_group = (known after apply)
      + main_route_table_id                  = (known after apply)
      + owner_id                             = (known after apply)
      + region                               = "ap-northeast-1"
      + tags                                 = {
          + "Name" = "for-each-vpc"
        }
      + tags_all                             = {
          + "Name" = "for-each-vpc"
        }
    }

Plan: 3 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + subnet_ids = {
      + private = (known after apply)
      + public  = (known after apply)
    }

plan 実行結果(count)
$ terraform plan 

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_subnet.main[0] will be created
  + resource "aws_subnet" "main" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "ap-northeast-1a"
      + availability_zone_id                           = (known after apply)
      + cidr_block                                     = "10.0.0.0/24"
      + enable_dns64                                   = false
      + enable_resource_name_dns_a_record_on_launch    = false
      + enable_resource_name_dns_aaaa_record_on_launch = false
      + id                                             = (known after apply)
      + ipv6_cidr_block_association_id                 = (known after apply)
      + ipv6_native                                    = false
      + map_public_ip_on_launch                        = false
      + owner_id                                       = (known after apply)
      + private_dns_hostname_type_on_launch            = (known after apply)
      + region                                         = "ap-northeast-1"
      + tags                                           = {
          + "Name" = "count-subnet-0"
        }
      + tags_all                                       = {
          + "Name" = "count-subnet-0"
        }
      + vpc_id                                         = (known after apply)
    }

  # aws_subnet.main[1] will be created
  + resource "aws_subnet" "main" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "ap-northeast-1c"
      + availability_zone_id                           = (known after apply)
      + cidr_block                                     = "10.0.1.0/24"
      + enable_dns64                                   = false
      + enable_resource_name_dns_a_record_on_launch    = false
      + enable_resource_name_dns_aaaa_record_on_launch = false
      + id                                             = (known after apply)
      + ipv6_cidr_block_association_id                 = (known after apply)
      + ipv6_native                                    = false
      + map_public_ip_on_launch                        = false
      + owner_id                                       = (known after apply)
      + private_dns_hostname_type_on_launch            = (known after apply)
      + region                                         = "ap-northeast-1"
      + tags                                           = {
          + "Name" = "count-subnet-1"
        }
      + tags_all                                       = {
          + "Name" = "count-subnet-1"
        }
      + vpc_id                                         = (known after apply)
    }

  # aws_vpc.main will be created
  + resource "aws_vpc" "main" {
      + arn                                  = (known after apply)
      + cidr_block                           = "10.0.0.0/16"
      + default_network_acl_id               = (known after apply)
      + default_route_table_id               = (known after apply)
      + default_security_group_id            = (known after apply)
      + dhcp_options_id                      = (known after apply)
      + enable_dns_hostnames                 = (known after apply)
      + enable_dns_support                   = true
      + enable_network_address_usage_metrics = (known after apply)
      + id                                   = (known after apply)
      + instance_tenancy                     = "default"
      + ipv6_association_id                  = (known after apply)
      + ipv6_cidr_block                      = (known after apply)
      + ipv6_cidr_block_network_border_group = (known after apply)
      + main_route_table_id                  = (known after apply)
      + owner_id                             = (known after apply)
      + region                               = "ap-northeast-1"
      + tags                                 = {
          + "Name" = "count-vpc"
        }
      + tags_all                             = {
          + "Name" = "count-vpc"
        }
    }

Plan: 3 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + subnet_ids = {
      + subnet_0 = (known after apply)
      + subnet_1 = (known after apply)
    }

では最後に,applyです。
ボタンひとつでリソースがたくさん作れるのは毎回感動です。

apply 実行結果(for_each)
$ terraform apply

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_subnet.main["1a"] will be created
  + resource "aws_subnet" "main" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "ap-northeast-1a"
      + availability_zone_id                           = (known after apply)
      + cidr_block                                     = "10.0.0.0/24"
      + enable_dns64                                   = false
      + enable_resource_name_dns_a_record_on_launch    = false
      + enable_resource_name_dns_aaaa_record_on_launch = false
      + id                                             = (known after apply)
      + ipv6_cidr_block_association_id                 = (known after apply)
      + ipv6_native                                    = false
      + map_public_ip_on_launch                        = false
      + owner_id                                       = (known after apply)
      + private_dns_hostname_type_on_launch            = (known after apply)
      + region                                         = "ap-northeast-1"
      + tags                                           = {
          + "Name" = "for-each-subnet-1a"
        }
      + tags_all                                       = {
          + "Name" = "for-each-subnet-1a"
        }
      + vpc_id                                         = (known after apply)
    }

  # aws_subnet.main["1c"] will be created
  + resource "aws_subnet" "main" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "ap-northeast-1c"
      + availability_zone_id                           = (known after apply)
      + cidr_block                                     = "10.0.1.0/24"
      + enable_dns64                                   = false
      + enable_resource_name_dns_a_record_on_launch    = false
      + enable_resource_name_dns_aaaa_record_on_launch = false
      + id                                             = (known after apply)
      + ipv6_cidr_block_association_id                 = (known after apply)
      + ipv6_native                                    = false
      + map_public_ip_on_launch                        = false
      + owner_id                                       = (known after apply)
      + private_dns_hostname_type_on_launch            = (known after apply)
      + region                                         = "ap-northeast-1"
      + tags                                           = {
          + "Name" = "for-each-subnet-1c"
        }
      + tags_all                                       = {
          + "Name" = "for-each-subnet-1c"
        }
      + vpc_id                                         = (known after apply)
    }

  # aws_vpc.main will be created
  + resource "aws_vpc" "main" {
      + arn                                  = (known after apply)
      + cidr_block                           = "10.0.0.0/16"
      + default_network_acl_id               = (known after apply)
      + default_route_table_id               = (known after apply)
      + default_security_group_id            = (known after apply)
      + dhcp_options_id                      = (known after apply)
      + enable_dns_hostnames                 = (known after apply)
      + enable_dns_support                   = true
      + enable_network_address_usage_metrics = (known after apply)
      + id                                   = (known after apply)
      + instance_tenancy                     = "default"
      + ipv6_association_id                  = (known after apply)
      + ipv6_cidr_block                      = (known after apply)
      + ipv6_cidr_block_network_border_group = (known after apply)
      + main_route_table_id                  = (known after apply)
      + owner_id                             = (known after apply)
      + region                               = "ap-northeast-1"
      + tags                                 = {
          + "Name" = "for-each-vpc"
        }
      + tags_all                             = {
          + "Name" = "for-each-vpc"
        }
    }

Plan: 3 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + subnet_ids = {
      + private = (known after apply)
      + public  = (known after apply)
    }

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_vpc.main: Creating...
aws_vpc.main: Creation complete after 1s [id=vpc-093164a0e3f2463ff]
aws_subnet.main["1a"]: Creating...
aws_subnet.main["1c"]: Creating...
aws_subnet.main["1c"]: Creation complete after 1s [id=subnet-0004b880f6354ee40]
aws_subnet.main["1a"]: Creation complete after 1s [id=subnet-0fc2b4c22f6d54d8d]

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

Outputs:

subnet_ids = {
  "private" = "subnet-0004b880f6354ee40"
  "public" = "subnet-0fc2b4c22f6d54d8d"
}
apply 実行結果(count)
$ terraform apply

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_subnet.main[0] will be created
  + resource "aws_subnet" "main" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "ap-northeast-1a"
      + availability_zone_id                           = (known after apply)
      + cidr_block                                     = "10.0.0.0/24"
      + enable_dns64                                   = false
      + enable_resource_name_dns_a_record_on_launch    = false
      + enable_resource_name_dns_aaaa_record_on_launch = false
      + id                                             = (known after apply)
      + ipv6_cidr_block_association_id                 = (known after apply)
      + ipv6_native                                    = false
      + map_public_ip_on_launch                        = false
      + owner_id                                       = (known after apply)
      + private_dns_hostname_type_on_launch            = (known after apply)
      + region                                         = "ap-northeast-1"
      + tags                                           = {
          + "Name" = "count-subnet-0"
        }
      + tags_all                                       = {
          + "Name" = "count-subnet-0"
        }
      + vpc_id                                         = (known after apply)
    }

  # aws_subnet.main[1] will be created
  + resource "aws_subnet" "main" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "ap-northeast-1c"
      + availability_zone_id                           = (known after apply)
      + cidr_block                                     = "10.0.1.0/24"
      + enable_dns64                                   = false
      + enable_resource_name_dns_a_record_on_launch    = false
      + enable_resource_name_dns_aaaa_record_on_launch = false
      + id                                             = (known after apply)
      + ipv6_cidr_block_association_id                 = (known after apply)
      + ipv6_native                                    = false
      + map_public_ip_on_launch                        = false
      + owner_id                                       = (known after apply)
      + private_dns_hostname_type_on_launch            = (known after apply)
      + region                                         = "ap-northeast-1"
      + tags                                           = {
          + "Name" = "count-subnet-1"
        }
      + tags_all                                       = {
          + "Name" = "count-subnet-1"
        }
      + vpc_id                                         = (known after apply)
    }

  # aws_vpc.main will be created
  + resource "aws_vpc" "main" {
      + arn                                  = (known after apply)
      + cidr_block                           = "10.0.0.0/16"
      + default_network_acl_id               = (known after apply)
      + default_route_table_id               = (known after apply)
      + default_security_group_id            = (known after apply)
      + dhcp_options_id                      = (known after apply)
      + enable_dns_hostnames                 = (known after apply)
      + enable_dns_support                   = true
      + enable_network_address_usage_metrics = (known after apply)
      + id                                   = (known after apply)
      + instance_tenancy                     = "default"
      + ipv6_association_id                  = (known after apply)
      + ipv6_cidr_block                      = (known after apply)
      + ipv6_cidr_block_network_border_group = (known after apply)
      + main_route_table_id                  = (known after apply)
      + owner_id                             = (known after apply)
      + region                               = "ap-northeast-1"
      + tags                                 = {
          + "Name" = "count-vpc"
        }
      + tags_all                             = {
          + "Name" = "count-vpc"
        }
    }

Plan: 3 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + subnet_ids = {
      + subnet_0 = (known after apply)
      + subnet_1 = (known after apply)
    }

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_vpc.main: Creating...
aws_vpc.main: Creation complete after 1s [id=vpc-0f3272f1650effa6a]
aws_subnet.main[0]: Creating...
aws_subnet.main[1]: Creating...
aws_subnet.main[0]: Creation complete after 1s [id=subnet-0c9f4afd196ef4f2b]
aws_subnet.main[1]: Creation complete after 1s [id=subnet-043fd961c1ec6e439]

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

Outputs:

subnet_ids = {
  "subnet_0" = "subnet-0c9f4afd196ef4f2b"
  "subnet_1" = "subnet-043fd961c1ec6e439"
}

では最後に,1aに作成したサブネットを削除した場合にどのような挙動になるか確認していきたいと思います。
for_eachではkey「1a」を削除してapplyしました。
実行結果を確認したところ,1aに配置されたサブネットが削除されていることを確認しました。

for_each 1a削除
$ terraform apply

aws_vpc.main: Refreshing state... [id=vpc-093164a0e3f2463ff]
aws_subnet.main["1c"]: Refreshing state... [id=subnet-0004b880f6354ee40]
aws_subnet.main["1a"]: Refreshing state... [id=subnet-0fc2b4c22f6d54d8d]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  - destroy

Terraform will perform the following actions:

  # aws_subnet.main["1a"] will be destroyed
  # (because key ["1a"] is not in for_each map)
  - resource "aws_subnet" "main" {
      - arn                                            = "arn:aws:ec2:ap-northeast-1:430360969074:subnet/subnet-0fc2b4c22f6d54d8d" -> null
      - assign_ipv6_address_on_creation                = false -> null
      - availability_zone                              = "ap-northeast-1a" -> null
      - availability_zone_id                           = "apne1-az4" -> null
      - cidr_block                                     = "10.0.0.0/24" -> null
      - enable_dns64                                   = false -> null
      - enable_lni_at_device_index                     = 0 -> null
      - enable_resource_name_dns_a_record_on_launch    = false -> null
      - enable_resource_name_dns_aaaa_record_on_launch = false -> null
      - id                                             = "subnet-0fc2b4c22f6d54d8d" -> null
      - ipv6_native                                    = false -> null
      - map_customer_owned_ip_on_launch                = false -> null
      - map_public_ip_on_launch                        = false -> null
      - owner_id                                       = "430360969074" -> null
      - private_dns_hostname_type_on_launch            = "ip-name" -> null
      - region                                         = "ap-northeast-1" -> null
      - tags                                           = {
          - "Name" = "for-each-subnet-1a"
        } -> null
      - tags_all                                       = {
          - "Name" = "for-each-subnet-1a"
        } -> null
      - vpc_id                                         = "vpc-093164a0e3f2463ff" -> null
        # (4 unchanged attributes hidden)
    }

Plan: 0 to add, 0 to change, 1 to destroy.

Changes to Outputs:
  ~ subnet_ids = {
      - public  = "subnet-0fc2b4c22f6d54d8d"
        # (1 unchanged attribute hidden)
    }

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_subnet.main["1a"]: Destroying... [id=subnet-0fc2b4c22f6d54d8d]
aws_subnet.main["1a"]: Destruction complete after 0s

Apply complete! Resources: 0 added, 0 changed, 1 destroyed.

Outputs:

subnet_ids = {
  "private" = "subnet-0004b880f6354ee40"
}

countでは「count = 1」としてapply したところ
今回削除したいサブネットはインデックス番号「0」ですが
挙動としてはインデックス番号「1」から削除する挙動となりました。その為、削除されるサブネットも本来とは意図していないものとなっています。

count 1a削除
$ terraform apply

aws_vpc.main: Refreshing state... [id=vpc-0f3272f1650effa6a]
aws_subnet.main[0]: Refreshing state... [id=subnet-0c9f4afd196ef4f2b]
aws_subnet.main[1]: Refreshing state... [id=subnet-043fd961c1ec6e439]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  - destroy

Terraform will perform the following actions:

  # aws_subnet.main[1] will be destroyed
  # (because index [1] is out of range for count)
  - resource "aws_subnet" "main" {
      - arn                                            = "arn:aws:ec2:ap-northeast-1:430360969074:subnet/subnet-043fd961c1ec6e439" -> null
      - assign_ipv6_address_on_creation                = false -> null
      - availability_zone                              = "ap-northeast-1c" -> null
      - availability_zone_id                           = "apne1-az1" -> null
      - cidr_block                                     = "10.0.1.0/24" -> null
      - enable_dns64                                   = false -> null
      - enable_lni_at_device_index                     = 0 -> null
      - enable_resource_name_dns_a_record_on_launch    = false -> null
      - enable_resource_name_dns_aaaa_record_on_launch = false -> null
      - id                                             = "subnet-043fd961c1ec6e439" -> null
      - ipv6_native                                    = false -> null
      - map_customer_owned_ip_on_launch                = false -> null
      - map_public_ip_on_launch                        = false -> null
      - owner_id                                       = "430360969074" -> null
      - private_dns_hostname_type_on_launch            = "ip-name" -> null
      - region                                         = "ap-northeast-1" -> null
      - tags                                           = {
          - "Name" = "count-subnet-1"
        } -> null
      - tags_all                                       = {
          - "Name" = "count-subnet-1"
        } -> null
      - vpc_id                                         = "vpc-0f3272f1650effa6a" -> null
        # (4 unchanged attributes hidden)
    }

Plan: 0 to add, 0 to change, 1 to destroy.

Changes to Outputs:
  ~ subnet_ids = {
      - subnet_1 = "subnet-043fd961c1ec6e439"
        # (1 unchanged attribute hidden)
    }

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_subnet.main[1]: Destroying... [id=subnet-043fd961c1ec6e439]
aws_subnet.main[1]: Destruction complete after 0s

Apply complete! Resources: 0 added, 0 changed, 1 destroyed.

Outputs:

subnet_ids = {
  "subnet_0" = "subnet-0c9f4afd196ef4f2b"
}aws_vpc.main: Refreshing state... [id=vpc-0f3272f1650effa6a]
aws_subnet.main[0]: Refreshing state... [id=subnet-0c9f4afd196ef4f2b]
aws_subnet.main[1]: Refreshing state... [id=subnet-043fd961c1ec6e439]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  - destroy

Terraform will perform the following actions:

  # aws_subnet.main[1] will be destroyed
  # (because index [1] is out of range for count)
  - resource "aws_subnet" "main" {
      - arn                                            = "arn:aws:ec2:ap-northeast-1:430360969074:subnet/subnet-043fd961c1ec6e439" -> null
      - assign_ipv6_address_on_creation                = false -> null
      - availability_zone                              = "ap-northeast-1c" -> null
      - availability_zone_id                           = "apne1-az1" -> null
      - cidr_block                                     = "10.0.1.0/24" -> null
      - enable_dns64                                   = false -> null
      - enable_lni_at_device_index                     = 0 -> null
      - enable_resource_name_dns_a_record_on_launch    = false -> null
      - enable_resource_name_dns_aaaa_record_on_launch = false -> null
      - id                                             = "subnet-043fd961c1ec6e439" -> null
      - ipv6_native                                    = false -> null
      - map_customer_owned_ip_on_launch                = false -> null
      - map_public_ip_on_launch                        = false -> null
      - owner_id                                       = "430360969074" -> null
      - private_dns_hostname_type_on_launch            = "ip-name" -> null
      - region                                         = "ap-northeast-1" -> null
      - tags                                           = {
          - "Name" = "count-subnet-1"
        } -> null
      - tags_all                                       = {
          - "Name" = "count-subnet-1"
        } -> null
      - vpc_id                                         = "vpc-0f3272f1650effa6a" -> null
        # (4 unchanged attributes hidden)
    }

Plan: 0 to add, 0 to change, 1 to destroy.

Changes to Outputs:
  ~ subnet_ids = {
      - subnet_1 = "subnet-043fd961c1ec6e439"
        # (1 unchanged attribute hidden)
    }

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_subnet.main[1]: Destroying... [id=subnet-043fd961c1ec6e439]
aws_subnet.main[1]: Destruction complete after 0s

Apply complete! Resources: 0 added, 0 changed, 1 destroyed.

Outputs:

subnet_ids = {
  "subnet_0" = "subnet-0c9f4afd196ef4f2b"
}

countの性質を考えると当たり前の挙動といえますが、意図としていないリソースを削除してしまう可能性や、頻繁に更新が入るリソースなどでは管理のしづらさが発生することからcountよりfor_eachの方がより運用面では優れているという結論です。

現場からは以上です。

この記事をシェアする

FacebookHatena blogX

関連記事