【发布时间】:2020-01-03 22:51:41
【问题描述】:
星期五快乐!希望有人可以帮助我解决这个问题或指出我的想法中的缺陷。
$ terraform --version
Terraform v0.12.7
+ provider.aws v2.25.0
+ provider.template v2.1.2
前言
这是我第一次使用 Terraform。我们有一个现有的 AWS ECS/Fargate 环境启动并运行,这是一个“测试”环境。我们最近(例如在设置测试环境之后)开始将 Terraform 用于 IaC 目的。
当前配置
环境有一个 ECS 集群,我们使用的是 FARGATE,但我不确定这对这个问题很重要。集群有几个服务,每个服务都有一个与之关联的任务(docker镜像)——所以它们可以单独扩展。每个 docker 镜像都有自己的 Repo。
我想要做什么
因此,我希望通过 Terraform 能够创建、更新和破坏环境。然而,创建/销毁似乎相当简单;我遇到了更新的障碍。
正如我所说,每个任务都有自己的 repo,当针对 repo 发出拉取请求时,我们的 CI 平台(如果重要的话是CircleCI)构建新的 docker 镜像,标记并推送它。然后我们使用 API 调用来触发 Terraform Repo 的构建,传递更新的服务/任务的名称。
问题
我们面临的问题是,在通过服务(如下所述)时,我无法弄清楚如何让 Terraform 忽略未更新的服务,或者如何提供正确的 aws_ecs_task_definition 中的>container_definitions,特别是当前图像标签(我们不使用latest tag)。所以我想弄清楚如何获取最新的容器信息(标签),或者只是告诉 Terraform 跳过未修改的任务。
地形脚本
这是我尝试过的精简版,它在一个名为 ecs.tf 的模块中,var.ecs_svc_names 是一个 list 的服务名称。我删除了一些元素,因为我认为它们与这个问题无关,并且拥有它们会使这个问题变得非常大。
注意事项 由于我要问的问题,我没有运行如下所示的 Terraform '脚本',所以我的语法可能是错误的。对不起,如果是这样的话,希望这会告诉你我正在尝试做什么......
ecs.tf
/* ecs_service_names is passed in, but here is its definition:
variable "ecs_service_names" {
type = list(string)
description = "This is a list/array of the images/services that are contained in the cluster"
default = [
"main",
"sub-service1",
"sub-service2"]
}
*/
locals {
numberOfServices = length(var.ecs_svc_names)
}
resource "aws_ecs_cluster" "ecs_cluster" {
name = "${var.env_type}-ecs-cluster"
}
// Create the service objects (1 for each service)
resource "aws_ecs_service" "ecs-service" {
// How many services are being created
count = local.numberOfServices
name = var.ecs_svc_names[count.index]
cluster = aws_ecs_cluster.ecs_cluster.id
definition[count.index].family}:${max(aws_ecs_task_definition.ecs-task-definition[count.index].revision, data.aws_ecs_task_definition.ecs-task-def.revision)}"
desired_count = 1
launch_type = "FARGATE"
// stuff removed
}
resource "aws_ecs_task_definition" "ecs-task-definition" {
// How many tasks. There is a 1-1 relationship between tasks and services
count = local.numberOfServices
family = var.ecs_svc_names[count.index]
network_mode = "awsvpc"
requires_compatibilities = ["FARGATE"]
// cpu/memory stuff removed
task_role_arn = var.ecs_task_role_arn
container_definitions = data.template_file.ecs_containers_json[count.index].rendered
}
data.tf
locals {
numberOfServices = length(var.ecs_svc_names)
}
data "aws_ecs_task_definition" "ecs-task-def" {
// How many services are being created, 1-1 relationship between tasks and services
count = local.numberOfServices
task_definition = aws_ecs_task_definition.ecs-task-definition[count.index].family
depends_on = [
"aws_ecs_task_definition.ecs-task-definition",
]
}
data "template_file" "ecs_containers_json" {
// How many tasks. There is a 1-1 relationship between tasks and services
count = local.numberOfServices
template = file("${path.module}/container.json.template")
vars = {
// vars removed
image = aws_ecs_task_definition.ecs-task-definition[count.index].family
// This is where I hit the road-block, how do I get the current docker tag from Terraform?
tag = var.ecs_svc_name_2_update == var.ecs_svc_names[count.index]
? var.ecs_svc_image_tag
: data.aws_ecs_task_definition.ecs-task-def[count.index].
}
我没有发布 JSON 文档,如果您需要,我可以提供...
谢谢
【问题讨论】:
标签: terraform amazon-ecs terraform-provider-aws aws-fargate