星期五快乐!希望有人可以帮助我解决这个问题或指出我的想法中的缺陷。
$ 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映像都有自己的存储库。
因此,我希望使用Terraform能够创建,更新和销毁环境。但是,创建/销毁似乎很简单。我遇到了要更新的障碍。
正如我所说的,每个任务都有自己的存储库,当对存储库发出拉取请求时,我们的CI平台(如果重要的话,为CircleCI)将构建新的docker映像,对其进行标记并推送。然后,我们使用API调用来触发Terraform Repo的构建,并传递已更新的服务/任务的名称。
我们面临的问题是,当通过服务(如下所述)时,我无法弄清楚如何使Terraform忽略未更新的服务,或者如何提供正确的 aws_ecs_task_definition 中的> container_definitions ,特别是当前图像标签(我们不使用latest tag)。因此,我试图弄清楚如何获取最新的容器信息(标签),或者只是告诉Terraform跳过未修改的任务。
这是我尝试过的简化版本,位于一个名为 ecs.tf 的模块中, var.ecs_svc_names 是一个 list < / em>服务名称。我删除了一些元素,因为我认为它们与该问题无关,并且使它们变得非常大。
注意事项 由于我要问的问题,我没有运行如下所示的Terraform'script',所以我的语法可能不正确。抱歉,如果可以的话,希望它能告诉您我要做什么。...
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文档,如果您需要我可以提供它...
谢谢
答案 0 :(得分:0)
必须在任务定义修订版的容器定义中传递更新的图像属性。
您可以data source
服务使用的当前任务修订的容器定义,并将其传递给terraform。您可以按照以下代码进行操作。
data "template_file" "example" {
template = "${file("${path.module}/example.json")}"
vars {
image = "${data.aws_ecs_container_definition.example.image}"
}
}
resource "aws_ecs_task_definition" "example" {
family = "${var.project_name}-${var.environment_name}-example"
container_definitions = "${data.template_file.example.rendered}"
cpu = 192
memory = 512
}
data "aws_ecs_container_definition" "example" {
task_definition = "${var.project_name}-${var.environment_name}-example"
container_name = "example"
}