更新注册表映像并再次应用服务时,Terraform 不会更新 aws_ecs_service

Tra*_*mas 3 amazon-web-services terraform

我有一个由 EC2 实例支持的 Terraform 配置的 ECS 集群。我正在部署一个自定义的 Wiremock 容器。如果我更改容器中的映射,构建并推送到注册表,我可以看到在尝试推送已经存在的层后,它会向上推送最后一层:

4c6899b75fdb: Layer already exists
cc9a6810e763: Pushed
latest: digest: sha256:1366cd467087b33e3ea3e159adf92ee9d11b53af87911c5563ee028aecbea8d4 size: 1366
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试使用此 Terraform 文件将该图像应用于服务时:

resource "aws_ecs_task_definition" "wiremock" {
    family                = "wiremock"
    tags                  = "${var.default_tags}"
    volume {
      name = "wiremock_logs"
      host_path = "/var/log/wiremock/"
    }
    requires_compatibilities = ["EC2"]
    container_definitions = <<DEFINITION
[
  {
    "name": "wiremock",
    "image": "${var.ecr_url}/${var.repository_name}:${var.tag}",
    "essential": true,
    "portMappings": [
      {
        "containerPort": 8080,
        "hostPort": 80
      }
    ],
    "mountPoints": [
      {
        "sourceVolume" : "wiremock_logs",
        "containerPath" : "/var/log/wiremock/"
      }
    ],
    "memory": 500,
    "cpu": 10
  }
]
DEFINITION
}

resource "aws_ecs_service" "wiremock" {
    name            = "wiremock"
    cluster         = "${data.aws_ecs_cluster.thelma_cluster.id}"
    task_definition = "${aws_ecs_task_definition.wiremock.family}:${max("${aws_ecs_task_definition.wiremock.revision}", "${aws_ecs_task_definition.wiremock.revision}")}"
    desired_count   = "${var.desired_count}"
}
Run Code Online (Sandbox Code Playgroud)

结果是这样的:

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

如何强制 Terraform 或 AWS 检查映像注册表的更新(新哈希)?它似乎只检查新的任务定义,新的图像上传不会改变它。

Tro*_*Dor 9

您可以在 ECS JSON 配置中包含 ECR 图像摘要。为了获取摘要,您首先要在 Terraform 中创建一个 ECR 图像数据源:

data "aws_ecr_image" "wiremock" {
  repository_name = "${var.repository_name}"
  image_tag = "${var.tag}"
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以在 JSON 中引用它,如下所示:

"image": "${var.ecr_url}/${var.repository_name}:${var.tag}@${data.aws_ecr_image.wiremock.image_digest}",
Run Code Online (Sandbox Code Playgroud)

这将导致 Terraform 在每次图像更改时重新创建任务定义并更新服务。


BMW*_*BMW 5

正如其他人所说,当 docker image tag 始终为 时,terraform 很难检测到变化latest

您可以按如下方式更新代码:

准备任务定义模板

$ cat task_definition.tpl

[
  {
    "name": "wiremock",
    "image": "${ecr_url}/${repository_name}:${var.tag}",
    "essential": true,
    "portMappings": [
      {
        "containerPort": 8080,
        "hostPort": 80
      }
    ],
    "mountPoints": [
      {
        "sourceVolume" : "wiremock_logs",
        "containerPath" : "/var/log/wiremock/"
      }
    ],
    "memory": 500,
    "cpu": 10
  }
]
Run Code Online (Sandbox Code Playgroud)

然后更新 terraform 文件

data "template_file" "task_definition" {
  template = "${file("${"${path.module}/task_definition.tpl"}")}"

  vars {
    ecr_url             = "${var.ecr_url}"
    var.repository_name = "${var.repository_name}"
    tag                 = "${var.tag}"
  }
}

resource "aws_ecs_task_definition" "wiremock" {
    family                = "wiremock"
    tags                  = "${var.default_tags}"
    volume {
      name = "wiremock_logs"
      host_path = "/var/log/wiremock/"
    }
    requires_compatibilities = ["EC2"]
    container_definitions = "${data.template_file.task_definition.rendered}"
    ...
}
Run Code Online (Sandbox Code Playgroud)

应用更改时,使用应用于 docker 镜像的新标签,通常我在标签名称中应用构建号,例如1.0.<build_number>构建 docker 镜像时。

TF_VAR_tag=1.0.${BUILD_NUMBER} terraform apply
Run Code Online (Sandbox Code Playgroud)

通过这种方式,terraform将检测到更改(docker镜像标签随着构建号而变化)。


one*_*klc 2

如果更新的 Docker 映像使用与服务的现有任务定义中的标签相同的标签(例如 my_image:latest),则无需创建任务定义的新版本。您可以使用以下命令更新服务按照下面的步骤,保留服务的当前设置,然后选择“强制新部署”。部署启动的新任务在启动时会从存储库中提取当前映像/标签组合。更新任务时也会使用“强制新部署”选项当您指定 LATEST 时,Fargate 任务将使用更新的平台版本。例如,如果您指定了 LATEST 并且您正在运行的任务正在使用 1.0.0 平台版本,并且您希望它们使用更新的平台版本重新启动。

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/update-service.html

太长了;通过 cli 强制更新任务或从 Web 控制台停止/启动任务。

如果不使用 Fargate,则可能无法工作,具体取决于 ECS 代理使用的设置(如果实例已有副本,则可能不会检查新副本)。通过环境变量配置 ECS 代理的拉取行为。

ECS_IMAGE_PULL_BEHAVIOR=始终

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-agent-config.html