Terraform中如何将EC2模块实例ID传入License Manager相关资源?
问题描述
我正在使用Terraform的EC2实例模块创建多台EC2实例,采用for_each而非count来批量创建。现在需要添加License Manager相关的SSM关联和许可证配置关联资源,但不知道如何正确传递实例ID/ARN,原代码使用count的方式无法适配当前的for_each架构,同时想了解是否有更优的实现方式。
我的现有代码如下:
main.tf
locals { name = "my-app-server" multiple_instances = var.multiple_instances_params } module "ec2_multiple" { source = "../../" for_each = local.multiple_instances name = "${local.name}-${each.key}" instance_type = each.value.instance_type availability_zone = each.value.availability_zone subnet_id = each.value.subnet_id vpc_security_group_ids = [module.security_group.security_group_id] enable_volume_tags = false root_block_device = lookup(each.value, "root_block_device", []) tags = local.tags }
terraform.tfvars
multiple_instances_params = { 1 = { instance_type = "t3.micro" availability_zone = "eu-central-1a" subnet_id = "subnet-xxxxxda3f7e" root_block_device = [ { delete_on_termination = false encrypted = true kms_key_id = "xxx" volume_type = "gp3" throughput = 200 volume_size = 100 tags = { Name = "my-root-block" } } ] } 2 = { instance_type = "t3.small" availability_zone = "eu-central-1a" subnet_id = "subnet-xxxxxa3f7e" root_block_device = [ { delete_on_termination = false encrypted = true volume_type = "gp3" throughput = 200 volume_size = 100 tags = { Name = "my-root-block" } } ] } # 省略其他实例配置 }
需要添加的License Manager相关代码(原基于count,无法直接使用):
resource "aws_ssm_association" "license-manager-ssm-association" { count = var.instance_count name = "AWS-GatherSoftwareInventory" association_name = "license-manager-ssm-association-forxxxxx" targets { key = "InstanceIds" values = [aws_instance.app-server[count.index].id] } } resource "aws_licensemanager_license_configuration" "example_license_config" { name = "chkconfig-${var.Environment}" license_counting_type = "Instance" } resource "aws_licensemanager_association" "example" { count = var.instance_count license_configuration_arn = aws_licensemanager_license_configuration.example_license_config.arn resource_arn = aws_instance.app-server[count.index].arn }
解决方案
因为你用for_each创建EC2实例模块,所以相关依赖资源也需要改用for_each来迭代,直接引用模块输出的实例属性即可。
修改后的License Manager相关代码
# 许可证配置(只需创建一次,无需迭代) resource "aws_licensemanager_license_configuration" "example_license_config" { name = "chkconfig-${var.Environment}" license_counting_type = "Instance" } # SSM关联:遍历EC2模块的实例 resource "aws_ssm_association" "license-manager-ssm-association" { for_each = module.ec2_multiple name = "AWS-GatherSoftwareInventory" association_name = "license-manager-ssm-association-for-${each.value.id}" targets { key = "InstanceIds" values = [each.value.id] } } # 许可证关联:遍历EC2模块的实例 resource "aws_licensemanager_association" "example" { for_each = module.ec2_multiple license_configuration_arn = aws_licensemanager_license_configuration.example_license_config.arn resource_arn = each.value.arn }
关键说明
- 迭代方式对齐:将原来的
count替换为for_each = module.ec2_multiple,EC2模块用for_each创建后,模块输出会是一个以原multiple_instances_params的key为键的映射,每个值包含对应实例的id、arn等属性。 - 属性引用:直接通过
each.value.id和each.value.arn获取实例的ID和ARN,无需手动索引。 - 许可证配置复用:
aws_licensemanager_license_configuration是全局配置,不需要随实例迭代,只需创建一次即可关联所有实例。
优化建议
- 给SSM关联的名称添加实例标识(比如示例中的
-${each.value.id}),方便后续区分不同实例的关联资源。 - 如果需要对不同实例应用不同的许可证配置,可以在
multiple_instances_params中添加对应的配置字段,在迭代时动态引用。
内容的提问来源于stack exchange,提问作者Saurabh
相关产品推荐
相关产品推荐

