AWS CDK跨堆栈参考和部署顺序

时间:2020-08-24 20:07:45

标签: aws-cdk

如何克服AWS CDK中的循环依赖问题: 假设我有一个用于ECS集群的堆栈和一个用于ECS服务的堆栈(其中有几个):

export class EcsClusterStack extends cdk.Stack {
    public readonly cluster: ecs.Cluster
    ...
}

export class EcsServiceStack extends cdk.Stack {
    constructor(scope: cdk.Construct, id: string, cluster: ecs.ICluster) { }
}

现在,我可以编写我的应用了:

const app = new cdk.App();
const vpc = new VpcStack(app,  'vpc');
const cluster = new ClusterStack(app, 'ecs', vpc.vpc);

const service = new EcsServiceStack(app, 'ecs-service', cluster.cluster);

让我们假设之后,我想将ECS服务从一个群集迁移到另一个群集。我将创建另一个ECS群集堆栈,并将其传递给ECS服务,但是这里的事情是: AWS CDK自动生成输出(在群集堆栈中有群集名称等输出),然后,当我想将ECS服务迁移到另一个群集时,如果我将另一个ICluster对象向下传递到ECS服务堆栈构造函数,AWS CDK会尝试从我以前的集群定义中删除输出/导出,这显然会在部署时失败,因为它无法从集群堆栈中删除导出,除非有依赖它的服务。最后,我看到一个错误:

0 | 7:15:19 PM | UPDATE_IN_PROGRESS   | AWS::CloudFormation::Stack            | ecs User Initiated
0 | 7:15:26 PM | UPDATE_ROLLBACK_IN_P | AWS::CloudFormation::Stack            | ecs Export ecs:ExportsOutputFnGetAttdefaultasgspotInstanceSecurityGroup2D2AFE98GroupId1084B7B2 cannot be deleted as it is in use by ecs-service

如果有一种方法可以强制首先部署ECS服务堆栈来解决问题,但是似乎AWS CDK总是始终首先部署依赖项(在我的情况下为ECS集群),并且部署失败。那么有没有办法解决这个问题?

3 个答案:

答案 0 :(得分:2)

我发现一种解决方法是强制CDK将部署分为两个步骤。首先,我部署使用导出的堆栈,以便不再使用它。然后,我部署创建导出的堆栈,以在不再使用导出后将其删除。即使您在命令上指定了堆栈名称,它仍然会部署它所依赖的所有堆栈。所以我必须使用--exclusively标志。

cdk deploy --exclusively ecs-service
cdk deploy

对于您而言,在创建新集群和部署堆栈之前,您需要执行所有步骤,以便在ecs-service中导入一些新内容。

在GitHub上有一个open issue

答案 1 :(得分:0)

我理解您这样的问题:创建另一个集群,将带有Service的TaskDefinition从旧迁移到新集群。

问题是,您的旧任务仍在运行,因为错误告诉您(SG仍在使用中)。 此外,是否可能是您试图重用旧群集中的安全组?

如果不是这样,则需要实例化一个new EcsServiceStack,但要使用新的cluster参数。 或者,如果您不关心“手动蓝色/绿色部署”,则可以销毁old EcsServiceStack。 然后重新运行CDK命令,并运行修改后的代码。

答案 2 :(得分:0)

This 对我很有用。在我的情况下,我使用 CDK 并希望删除一个堆栈(假设为 stackA),其中输出引用为另一个堆栈中的输入(假设为 stackB 和 stackC)。因此,我打破了所有跨堆栈引用,手动将值放在 cloudFormation 模板上,然后将模板部署到每个堆栈(stackB 和 stackC)。然后我把CDK上的stackA去掉,部署成功了。