
Terraform AWS Provider 中 aws_ecs_container_definition 数据源按容器名读取 ECS 任务定义详情【免费下载链接】terraform-provider-awsThe AWS Provider enables Terraform to manage AWS resources.项目地址: https://gitcode.com/GitHub_Trending/te/terraform-provider-aws本篇技术指南围绕 Terraform AWS Provider 的aws_ecs_container_definition数据源展开介绍如何在 Terraform 配置中从已有的 ECS 任务定义Task Definition里精确提取某一个容器的镜像、内存、CPU、环境变量等配置详情读完后你将掌握该数据源的完整参数与属性参考、底层实现调用链DescribeTaskDefinition 容器名过滤、image_digest的解析规则与边界情况以及可复制的端到端示例与验收测试写法。数据源定位与适用场景官方文档描述见 website/docs/d/ecs_container_definition.html.markdownThe ECS container definition data source allows access to details of a specific container within an AWS ECS service.aws_ecs_container_definition是一个只读数据源它不创建或管理任何 AWS 资源而是根据任务定义 ARN 容器名两个条件从 AWS ECS 控制面查询该任务定义中指定容器的完整配置并把结果导出为 Terraform 属性供其他资源或output引用。典型应用场景用 Terraform 管理了一个aws_ecs_task_definition尤其是container_definitions以 JSON 字符串 heredoc 形式书写、无法用属性直接解析的场景需要把其中某个容器的镜像、内存等配置取出来传递给其他资源如依赖该镜像的其他服务、日志配置、告警规则等跨工作目录/状态引用从另一个 Terraform 根模块或已有环境中已创建的任务定义中按容器名读取镜像与 digest实现配置复用审计与校验确认线上任务定义中某容器实际使用的镜像与内存配置是否符合预期。从 internal/service/ecs/service_package_gen.go 的服务注册表可以看到该数据源以aws_ecs_container_definition类型名注册为 ECS 服务的 SDK 数据源并声明了Region: inttypes.ResourceRegionDefault()即支持按 provider 默认 Region 解析同时可通过region参数覆盖。基本用法文档给出的最小示例data aws_ecs_container_definition ecs-mongo { task_definition aws_ecs_task_definition.mongo.id container_name mongodb }注意task_definition接受任务定义的ARN文档 Argument Reference 中明确写为 ARN of the task definition which contains the container。aws_ecs_task_definition资源的id与arn均可以是 ARN 形式取决于任务定义是否含命名空间前缀传入后由 provider 原样作为DescribeTaskDefinition的入参。参数参考Argument Reference该数据源支持以下参数完整继承自 website/docs/d/ecs_container_definition.html.markdown参数必填类型说明container_name是string要读取的容器定义名称必须与任务定义 JSON 中的name字段完全一致task_definition是string包含该容器的任务定义 ARNregion否string资源所在 Region默认使用 provider 配置中的 RegionSchema 层面的对应定义在 internal/service/ecs/container_definition_data_source.gocontainer_name与task_definition均为Required字符串其余字段全部为Computed符合只读数据源的语义——所有输出字段均不接受用户写入。属性参考Attribute Reference该数据源在参数之外导出以下属性源码中每个字段都与 SDK 的awstypes.ContainerDefinition一一对应属性Schema 类型对应 SDK 字段说明cpuintdef.Cpu该容器定义的 CPU 限制单位与任务定义 JSON 中cpu字段一致disable_networkingbooldef.DisableNetworking是否禁用网络docker_labelsmap(string)def.DockerLabelsDocker 标签键值对environmentmap(string)def.Environment容器环境变量由 SDK 的[name, value]列表在 provider 内转换为mapimagestringdef.Image容器使用的 Docker 镜像含 tag 或 digest 部分image_digeststring—派生字段从image字符串中解析出的冒号后部分见下文专题说明memoryintdef.Memory容器内存硬限制MiBmemory_reservationintdef.MemoryReservation内存软限制MiB系统内存紧张时 Docker 尽力将容器内存保持在该值其中environment的列表转 map 逻辑可以在 internal/service/ecs/container_definition_data_source.go 中直接看到var environment map[string]string{} for _, v : range def.Environment { environment[aws.ToString(v.Name)] aws.ToString(v.Value) } d.Set(names.AttrEnvironment, environment)因此在 Terraform 中用data.aws_ecs_container_definition.mongo.environment.MY_KEY的点号语法即可按 key 取值。实现原理两步查找与错误处理数据源的 Read 函数为dataSourceContainerDefinitionReadinternal/service/ecs/container_definition_data_source.go其工作流程是从 provider 客户端获取 ECS 客户端conn : meta.(*conns.AWSClient).ECSClient(ctx)调用findContainerDefinitionByTwoPartKey(ctx, conn, taskDefinition, containerName)这是一个两段式 key查找先按任务定义 ARN 描述整个任务定义再按容器名过滤若任一步骤出错统一包装为SingularDataSourceFindErrortfresource.SingularDataSourceFindError(ECS Container Definition, err)在 plan/apply 阶段呈现为清晰的找不到该数据源目标错误找到后将各字段d.Set到 Terraform state并生成资源 ID。关键的查找函数findContainerDefinitionByTwoPartKeyinternal/service/ecs/container_definition_data_source.go实现如下func findContainerDefinitionByTwoPartKey(ctx context.Context, conn *ecs.Client, taskDefinitionName, containerName string) (*awstypes.ContainerDefinition, error) { input : ecs.DescribeTaskDefinitionInput{ TaskDefinition: aws.String(taskDefinitionName), } taskDefinition, _, err : findTaskDefinition(ctx, conn, input) if err ! nil { return nil, err } return tfresource.AssertSingleValueResult(tfslices.Filter(taskDefinition.ContainerDefinitions, func(v awstypes.ContainerDefinition) bool { return aws.ToString(v.Name) containerName })) }从源码结构看可以得出三点结论底层 API 是 ECS 的DescribeTaskDefinition由 internal/service/ecs/task_definition.go 中的findTaskDefinition统一封装调用该函数被任务定义资源、数据源与容器定义数据源复用而非针对容器定义的独立 API——ECS API 本身不提供按容器名查询的接口过滤是在 provider 侧完成的任务定义内的所有ContainerDefinitions会经过tfslices.Filter按Name containerName精确匹配过滤随后由tfresource.AssertSingleValueResult断言恰好一个结果任务定义不存在、容器名拼错、或同名容器出现多次都会导致查找失败并报错整个查找是纯读操作不会修改任何 AWS 资源可安全用于terraform plan阶段。数据源自身的 Terraform state ID 由两段 key 拼接而成internal/service/ecs/container_definition_data_source.god.SetId(fmt.Sprintf(%s/%s, taskDefinition, aws.ToString(def.Name)))即task_definition/container_name形式这与该数据源find...ByTwoPartKey的命名保持一致也符合仓库内以 ID 表达定位 key的惯例参见 docs/design-decisions/standardize-use-of-the-id-attribute.md。image_digest的解析规则与边界情况image_digest是一个派生字段并非直接来自 SDK 结构体。源码中的处理逻辑internal/service/ecs/container_definition_data_source.goimage : aws.ToString(def.Image) d.Set(image, image) if strings.Contains(image, :) { d.Set(image_digest, strings.Split(image, :)[1]) }即仅当image字符串包含冒号时取第一个冒号之后的部分作为image_digest。由此推出两种典型取值image配置image_digest输出mongo:latestlatest实际是 tag而非 SHA digest123456789012.dkr.ecr.us-west-2.amazonaws.com/my-appsha256:abc123...sha256:abc123...真正的 digestubuntu无任何冒号不设置state 中为空需要注意文档将其描述为Digest of the docker image in use但从实现看它只是镜像引用字符串的冒号后缀当镜像使用 tag 时取到的就是 tag。若你的场景严格依赖 SHA256 digest如镜像不可变发布校验应在配置侧保证任务定义中使用imagesha256:...形式引用镜像而不是 tag。这一解析行为在验收测试中也有对应断言见下节。完整可运行示例文档示例依赖一个名为mongo的aws_ecs_task_definition。仓库验收测试 internal/service/ecs/container_definition_data_source_test.go 提供了一个包含 Cluster、Task Definition、Service 与数据源的端到端配置可直接参考resource aws_ecs_cluster default { name tf_acc_td_ds_cluster_ecs_containter_definition } resource aws_ecs_task_definition mongo { family tf_acc_td_ds_ecs_containter_definition container_definitions DEFINITION [ { cpu: 128, environment: [ { name: SECRET, value: KEY } ], essential: true, image: mongo:latest, memory: 128, memoryReservation: 64, name: mongodb } ] DEFINITION } data aws_ecs_container_definition mongo { task_definition aws_ecs_task_definition.mongo.id container_name mongodb }对应地该测试在 apply 后断言了数据源各属性internal/service/ecs/container_definition_data_source_test.goresource.TestCheckResourceAttr(data.aws_ecs_container_definition.mongo, image, mongo:latest), resource.TestCheckResourceAttr(data.aws_ecs_container_definition.mongo, image_digest, latest), resource.TestCheckResourceAttr(data.aws_ecs_container_definition.mongo, memory, 128), resource.TestCheckResourceAttr(data.aws_ecs_container_definition.mongo, memory_reservation, 64), resource.TestCheckResourceAttr(data.aws_ecs_container_definition.mongo, cpu, 128), resource.TestCheckResourceAttr(data.aws_ecs_container_definition.mongo, environment.SECRET, KEY),这些断言恰好覆盖了上文属性表中各字段的取值预期也验证了image_digest latest的解析规则。使用限制与注意事项只读且无缓存该数据源只在读取时调用一次DescribeTaskDefinition不会持续跟踪任务定义的新版本。任务定义升级到新版本新版本号对应新 ARN后需更新task_definition引用的 ARN 才会读到新容器配置容器名必须精确匹配查找是大小写敏感的字符串精确比较aws.ToString(v.Name) containerName拼写不一致会直接报 find error 而非静默返回空属性覆盖面有限该数据源只导出上文 8 个属性任务定义中的portMappings、logConfiguration、secrets、mountPoints等字段并未暴露。若需要这些细节可考虑改用 aws_ecs_task_definition 相关数据源或直接在aws_ecs_task_definition资源侧以结构化 schema 管理容器定义Region 行为未指定region时遵循 provider 默认配置与 internal/service/ecs/service_package_gen.go 中ResourceRegionDefault()的注册一致。相关仓库入口内容路径数据源官方文档website/docs/d/ecs_container_definition.html.markdown数据源 Schema 与 Read 实现internal/service/ecs/container_definition_data_source.go验收测试与端到端示例配置internal/service/ecs/container_definition_data_source_test.gofindTaskDefinitionDescribeTaskDefinition封装internal/service/ecs/task_definition.goECS 服务数据源注册表internal/service/ecs/service_package_gen.go【免费下载链接】terraform-provider-awsThe AWS Provider enables Terraform to manage AWS resources.项目地址: https://gitcode.com/GitHub_Trending/te/terraform-provider-aws创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考