Terraform嵌套for_each重构:多域ECR转Sagemaker镜像报错解决
问题与解决方案
问题背景
现有多个存储在ECR中的镜像,需要转为自定义SageMaker Studio镜像,并为多个SageMaker Studio域分别创建并绑定这些镜像。编写的Terraform代码出现索引错误,无法通过字符串key访问列表类型的local.flat_images。
错误原因
local.flat_images是**元组(列表)**类型,只能通过数字索引访问元素,但代码中使用了字符串格式的each.key(如amp-mambakernel)尝试索引,导致Terraform报错"a number is required"。
修复后的代码
variable "sagemaker_domains" { type = list(string) default = ["my_domain", "your_domain"] } locals { custom_docker_images = { for domain in var.sagemaker_domains : domain => [ { ecr_image_name = "smstudio-custom" studio_image_name = "metaflowkernel" display_name = "Metaflow Kernel" }, { ecr_image_name = "studio-sample-default" studio_image_name = "mambakernel" display_name = "Mamba Kernel" } ] } # 将扁平化后的镜像数据转为Map,用domain-studio_image_name作为唯一Key flat_images_map = { for domain, images in local.custom_docker_images : for image in images : "${domain}-${image.studio_image_name}" => merge({ domain = domain }, image) } } data "aws_caller_identity" "current" {} data "aws_region" "current" {} data "aws_ecr_image" "studio_custom_image" { for_each = local.flat_images_map repository_name = each.value.ecr_image_name most_recent = true } resource "aws_sagemaker_image" "sagemaker_custom_images" { for_each = local.flat_images_map image_name = "${each.value.studio_image_name}-${each.key}" display_name = "${each.value.display_name} - ${each.value.domain}" role_arn = "" # 请替换为实际的IAM角色ARN } resource "aws_sagemaker_image_version" "sagemaker_custom_images" { for_each = aws_sagemaker_image.sagemaker_custom_images image_name = each.value.id base_image = "${data.aws_caller_identity.current.account_id}.dkr.ecr.${data.aws_region.current.name}.amazonaws.com/${local.flat_images_map[each.key].ecr_image_name}:${data.aws_ecr_image.studio_custom_image[each.key].image_tags[0]}" }
关键修改说明
- 重构
flat_images为Map类型:将原有的flatten生成的列表改为嵌套for循环生成的Map,用${domain}-${image.studio_image_name}作为唯一key,确保后续可以通过each.key直接定位到对应的镜像配置。 - 统一引用Map数据:所有
for_each都基于local.flat_images_map,确保each.key在各个资源和数据源中保持一致,避免索引不匹配。 - 简化
base_image拼接逻辑:直接通过local.flat_images_map[each.key]获取ECR镜像名称,不再需要使用lookup或列表索引,彻底解决索引错误问题。
内容的提问来源于stack exchange,提问作者Riley Hun
相关产品推荐
相关产品推荐

