v0.12.6以降のループ処理について。
countの問題点:
Manage Similar Resources with For Each | Terraform - HashiCorp Learn:
locals { users = [ "user01", "user02", ] } resource null_resource user { for_each = toset(local.users) triggers = { user = each.value } }
terraform plan -target null_resource.user ... # null_resource.user["user01"] will be created + resource "null_resource" "user" { + id = (known after apply) + triggers = { + "user" = "user01" } } # null_resource.user["user02"] will be created + resource "null_resource" "user" { + id = (known after apply) + triggers = { + "user" = "user02" } }
index(local.users, each.value)
locals { site_prefix = "example1" default_ami = "ami-xxxx" web_instances = { "web-01" = { # ami = "ami-xxxx" # 省略すると default_ami が使われるように instance_type = "t4g.large" subnet_id = data.aws_subnets.private.ids[0] ebs1_size = 20 } "web-02" = { ami = "ami-xxxx" instance_type = "t4g.large" subnet_id = data.aws_subnets.private.ids[1] ebs1_size = 20 } } }
resource "aws_instance" "web" { for_each = local.web_instances ami = ami_name_el9(local.default_ami, each.value.ami) instance_type = each.value.instance_type key_name = var.key_name subnet_id = each.value.subnet_id iam_instance_profile = aws_iam_instance_profile.web.id disable_api_termination = var.disable_api_termination associate_public_ip_address = false vpc_security_group_ids = [ aws_security_group.web.id, ] metadata_options { http_tokens = "required" } tags = { Name = "${local.site_prefix}-${each.key}" } root_block_device { volume_size = 20 volume_type = "gp3" iops = 3000 throughput = 125 tags = { "Name" = "${local.site_prefix}-${each.key}-root" } } ephemeral_block_device { device_name = "/dev/sdb" virtual_name = "ephemeral0" } ephemeral_block_device { device_name = "/dev/sdc" virtual_name = "ephemeral1" } ephemeral_block_device { device_name = "/dev/sdd" virtual_name = "ephemeral2" } ephemeral_block_device { device_name = "/dev/sde" virtual_name = "ephemeral3" } credit_specification { cpu_credits = "unlimited" } } resource "aws_ebs_volume" "web_ebs1" { for_each = local.web_instances availability_zone = aws_instance.web[each.key].availability_zone size = each.value.ebs1_size type = "gp3" iops = 3000 throughput = 125 encrypted = true tags = { Name = "${local.site_prefix}-${each.key}-ebs1" } } resource "aws_volume_attachment" "web_ebs1" { for_each = aws_instance.web device_name = "/dev/sdf" instance_id = each.value.id volume_id = aws_ebs_volume.web_ebs1[each.key].id }
locals { ses_email_ids = { slack-channel1 = { email = "user1@example.com" }, } } resource "aws_ses_email_identity" "main" { for_each = local.ses_email_ids email = each.value.email }
ses_id_arns = concat( values(aws_ses_email_identity.main)[*].arn, [data.aws_ses_domain_identity.domain1.arn], )
variable users {
type = map(map(string))
default = {
user01 = {
home = "/home/user01"
shell = "/bin/bash"
}
www01 = {
home = "/var/www/html"
shell = "/bin/false"
}
}
}
resource null_resource user {
for_each = var.users
triggers = {
user = each.key
home = each.value.home
shell = each.value.shell
}
}
terraform plan
...
# null_resource.user["user01"] will be created
+ resource "null_resource" "user" {
+ id = (known after apply)
+ triggers = {
+ "home" = "/home/user01"
+ "shell" = "/bin/bash"
+ "user" = "user01"
}
}
# null_resource.user["www01"] will be created
+ resource "null_resource" "user" {
+ id = (known after apply)
+ triggers = {
+ "home" = "/var/www/html"
+ "shell" = "/bin/false"
+ "user" = "www01"
}
}
Plan: 2 to add, 0 to change, 0 to destroy.output "user_home" {
value = [ for value in null_resource.user : value.home ]
}
locals {
# ses dkimのdataリソースで参照したほうが良いが、まだ存在しない
ses_dkim = [
{
"type" = "CNAME"
"name" = "dummy1._domainkey.example.com"
"value" = "dummy1.dkim.amazonses.com"
},
{
"type" = "CNAME"
"name" = "dummy2._domainkey.example.com"
"value" = "dummy2.dkim.amazonses.com"
},
{
"type" = "CNAME"
"name" = "dummy3._domainkey.example.com"
"value" = "dummy3.dkim.amazonses.com"
},
]
}
resource "aws_route53_record" "ses_dkim" {
for_each = { for i in local.ses_dkim : i.name => i }
zone_id = data.aws_route53_zone.example_com.zone_id
name = each.value.name
type = each.value.type
ttl = "600"
records = [each.value.value]
}