是否可以检测并恢复已取消注册的 ECS 任务定义?

问题描述 投票:0回答:1

我在使用 CDK 管理不活动的 ECS 任务定义时遇到问题。此外,CloudFormation 漂移检测似乎错过了这种“注销”。

重现

将以下内容放入app.py中:

from aws_cdk import (
    aws_ecs as ecs,
    core,
)

class ExampleStack(core.Stack):
    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)
        task_defn = ecs.FargateTaskDefinition(self, "ExampleTaskDefinition", cpu=256, memory_limit_mib=512)
        task_defn.add_container("ExampleContainer", image=ecs.ContainerImage.from_registry("amazon/amazon-ecs-sample"))

app = core.App()
ExampleStack(app, "ExampleStack", env={"region": "us-east-1"})
app.synth()

部署它:

$ cdk deploy
...
 2/4 | 7:10:50 PM | CREATE_IN_PROGRESS   | AWS::ECS::TaskDefinition | ExampleTaskDefinition (ExampleTaskDefinition47549670)
 2/4 | 7:10:50 PM | CREATE_IN_PROGRESS   | AWS::ECS::TaskDefinition | ExampleTaskDefinition (ExampleTaskDefinition47549670) Resource creation Initiated
 3/4 | 7:10:51 PM | CREATE_COMPLETE      | AWS::ECS::TaskDefinition | ExampleTaskDefinition (ExampleTaskDefinition47549670)
 4/4 | 7:10:52 PM | CREATE_COMPLETE      | AWS::CloudFormation::Stack | ExampleStack

 ✅  ExampleStack

Stack ARN:
arn:aws:cloudformation:us-east-1:865458870989:stack/ExampleStack/47a559b0-2386-11ea-a6f0-0a4fdb0c1726
...

确认任务定义:

$ aws ecs list-task-definitions --region=us-east-1
{
    "taskDefinitionArns": [
        "arn:aws:ecs:us-east-1:865458870989:task-definition/ExampleStackExampleTaskDefinition169C2730:1"
    ]
}

注销任务定义:

$ aws ecs deregister-task-definition --task-definition arn:aws:ecs:us-east-1:865458870989:task-definition/ExampleStackExampleTaskDefinition169C2730:1  --region=us-east-1
...
  "status": "INACTIVE",
...

问题 1: 此时,CloudFormation 漂移检测继续将任务定义显示为“IN_SYNC”。

我的猜测是,这是因为 ECS 任务定义保持可发现的方式 (https://docs.aws.amazon.com/AmazonECS/latest/userguide/deregister-task-definition.html): “目前,非活动任务定义仍然可以在您的帐户中无限期地发现”

问题 1: CloudFormation 有没有办法将其检测为漂移?

问题 2:CDK 无法再次部署此堆栈。例如,如果我将 ECS 集群和服务添加到 app.py:

from aws_cdk import (
    aws_ecs as ecs,
    core,
)

class ExampleStack(core.Stack):
    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)
        task_defn = ecs.FargateTaskDefinition(self, "ExampleTaskDefinition", cpu=256, memory_limit_mib=512)
        task_defn.add_container("ExampleContainer", image=ecs.ContainerImage.from_registry("amazon/amazon-ecs-sample"))

        cluster = ecs.Cluster(self, "ExampleServiceCluster")
        ecs.FargateService(
            self,
            "ExampleService",
            cluster=cluster,
            task_definition=task_defn,
            assign_public_ip=False,
            desired_count=1,
            min_healthy_percent=0,
            max_healthy_percent=100,
            service_name="ExampleService"
        )

app = core.App()
ExampleStack(app, "ExampleStack", env={"region": "us-east-1"})
app.synth()

我现在会收到以下错误:

$ cdk deploy
...
 16/27 | 7:18:30 PM | CREATE_FAILED        | AWS::ECS::Service                     | ExampleService/Service (ExampleServiceC7919DA2) TaskDefinition is inactive (Service: AmazonECS; Status Code: 400; Error Code: ClientException; Request ID: dbb927b6-b2ba-495b-be47-b202a2802465)
        new BaseService (/tmp/jsii-kernel-9athIS/node_modules/@aws-cdk/aws-ecs/lib/base/base-service.js:98:25)
        \_ new FargateService (/tmp/jsii-kernel-9athIS/node_modules/@aws-cdk/aws-ecs/lib/fargate/fargate-service.js:35:9)
...

问题2:有没有一种简单的方法可以让这个堆栈再次工作而不完全破坏它?我想我还可以更改 TaskDefinition 的某些内容(例如,将名称更改为“ExampleTaskDefinition1”)以触发新 ARN 的创建,但这似乎有点笨拙。有更好的方法吗?

提前致谢!

amazon-web-services aws-cloudformation amazon-ecs aws-cdk
1个回答
0
投票

问题

我相信我也有同样的问题,在手动更改 ECS 任务定义后,尝试更新 ECS 服务属性 将导致更新失败,因为 CloudFormation 记住的服务的特定任务定义版本现在“不活动” ”。我认为这是因为 CloudFormation 想要应用所有 ECS 服务属性,并且在不更改任务定义的情况下,它将尝试使用非活动任务定义。

解决方案

解决方案是对任务定义进行重大更改,即需要根据 CloudFormation AWS::ECS::TaskDefinition

文档
进行替换。例如,更改任务的内存大小。更改完成后可以改回来。

CloudFormation 实现“需要替换”的方式是创建一个全新的任务定义(而不仅仅是现有任务定义的新版本)并更改 ECS 服务以使用新定义 - 并且它实际上并不关心版本旧的定义。然后,CloudFormation 将尝试通过删除它知道的版本来删除旧任务定义,但如果有更多版本(由于手动更改 - CloudFormation 永远不会创建新版本,它始终以版本 1 为目标),则任务定义本身将不会被删除,所有手动版本将保留。您可能想手动删除它们。

备注:
删除 CloudFormation 创建的任务定义的版本 1 可能不是一个好主意。如果您随后尝试更新服务,您会收到错误消息:

Resource of type 'AWS::ECS::TaskDefinition' with identifier 'arn:aws:ecs:XX-XXXX-X:XXXXXXXXXXXX:task-definition/XXXX...:VERSION' was not found.
    
© www.soinside.com 2019 - 2024. All rights reserved.