aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.53k stars 3.86k forks source link

EC2: renaming a VPC subnet fails #23013

Closed markshep closed 1 year ago

markshep commented 1 year ago

Describe the bug

I had code to create a VPC containing a single subnet and gave it the name "PublicSubnet". When this got created the name used in the CloudFormation tree vies got expanded out to be "PublicSubnetSubnet1". So I changed my code to use a name of "" so that it would just be "Subnet1" in the CloudFormation tree view. Running sdk diff showed that it would do what I wanted, but cdk deploy failed with an error which caused a rollback.

Expected Behavior

That the changes as specified in the cdk diff output would be successfully applied.

Current Behavior

This was the output from cdk deploy:

✨  Synthesis time: 4.63s

odyssey-mobi-domain: building assets...

[0%] start: Building ab0ca545ff9245dfcd846970855710fd5130c1b902d6c8983090f007081c589d:940003561533-us-east-1
[100%] success: Built ab0ca545ff9245dfcd846970855710fd5130c1b902d6c8983090f007081c589d:940003561533-us-east-1

odyssey-mobi-domain: assets built

odyssey-mobi-domain: deploying...
[0%] start: Publishing ab0ca545ff9245dfcd846970855710fd5130c1b902d6c8983090f007081c589d:940003561533-us-east-1
[100%] success: Published ab0ca545ff9245dfcd846970855710fd5130c1b902d6c8983090f007081c589d:940003561533-us-east-1
odyssey-mobi-domain: creating CloudFormation changeset...
12:30:14 | CREATE_FAILED        | AWS::EC2::Subnet                      | VpcSubnet1SubnetA577490B
Resource handler returned message: "The CIDR '172.16.0.0/24' conflicts with another subnet (Service: Ec2, Status Code: 400, Request ID: 7a768a60-7e2e-4e76-b751
-6fb364f6f5b3, Extended Request ID: null)" (RequestToken: b2de7d46-bfa2-3528-fb3c-a545f9821818, HandlerErrorCode: AlreadyExists)

 ❌  odyssey-mobi-domain failed: Error: The stack named odyssey-mobi-domain failed to deploy: UPDATE_ROLLBACK_COMPLETE: Resource handler returned message: "The CIDR '172.16.0.0/24' conflicts with another subnet (Service: Ec2, Status Code: 400, Request ID: 7a768a60-7e2e-4e76-b751-6fb364f6f5b3, Extended Request ID: null)" (RequestToken: b2de7d46-bfa2-3528-fb3c-a545f9821818, HandlerErrorCode: AlreadyExists)
    at FullCloudFormationDeployment.monitorDeployment (/opt/homebrew/Cellar/aws-cdk/2.51.1/libexec/lib/node_modules/aws-cdk/lib/api/deploy-stack.ts:505:13)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at deployStack2 (/opt/homebrew/Cellar/aws-cdk/2.51.1/libexec/lib/node_modules/aws-cdk/lib/cdk-toolkit.ts:264:24)
    at /opt/homebrew/Cellar/aws-cdk/2.51.1/libexec/lib/node_modules/aws-cdk/lib/deploy.ts:39:11
    at run (/opt/homebrew/Cellar/aws-cdk/2.51.1/libexec/lib/node_modules/p-queue/dist/index.js:163:29)

 ❌ Deployment failed: Error: Stack Deployments Failed: Error: The stack named odyssey-mobi-domain failed to deploy: UPDATE_ROLLBACK_COMPLETE: Resource handler returned message: "The CIDR '172.16.0.0/24' conflicts with another subnet (Service: Ec2, Status Code: 400, Request ID: 7a768a60-7e2e-4e76-b751-6fb364f6f5b3, Extended Request ID: null)" (RequestToken: b2de7d46-bfa2-3528-fb3c-a545f9821818, HandlerErrorCode: AlreadyExists)
    at deployStacks (/opt/homebrew/Cellar/aws-cdk/2.51.1/libexec/lib/node_modules/aws-cdk/lib/deploy.ts:61:11)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at CdkToolkit.deploy (/opt/homebrew/Cellar/aws-cdk/2.51.1/libexec/lib/node_modules/aws-cdk/lib/cdk-toolkit.ts:338:7)
    at initCommandLine (/opt/homebrew/Cellar/aws-cdk/2.51.1/libexec/lib/node_modules/aws-cdk/lib/cli.ts:364:12)

Stack Deployments Failed: Error: The stack named odyssey-mobi-domain failed to deploy: UPDATE_ROLLBACK_COMPLETE: Resource handler returned message: "The CIDR '172.16.0.0/24' conflicts with another subnet (Service: Ec2, Status Code: 400, Request ID: 7a768a60-7e2e-4e76-b751-6fb364f6f5b3, Extended Request ID: null)" (RequestToken: b2de7d46-bfa2-3528-fb3c-a545f9821818, HandlerErrorCode: AlreadyExists)

Reproduction Steps

Run once as-is, then change the Name parameter to "" and run again.

var vpc = new Vpc(this, "Vpc", new VpcProps {
        IpAddresses = IpAddresses.Cidr("172.16.0.0/24"),
        MaxAzs = 1,
        SubnetConfiguration = new SubnetConfiguration[] {
            new SubnetConfiguration {
                Name = "PublicSubnet",
                SubnetType = SubnetType.PUBLIC,
                MapPublicIpOnLaunch = false,
            },
        },
    });

Possible Solution

No response

Additional Information/Context

No response

CDK CLI Version

2.51.1 (build 3d30cdb)

Framework Version

No response

Node.js Version

v18.12.1

OS

macOS

Language

.NET

Language Version

Using dotnet 7.0.100 with a target framework of net6.0

Other information

No response

markshep commented 1 year ago

BTW I'm using the aws-cdk and node@18 Homebrew packages.

peterwoodworth commented 1 year ago

There are known issues with specifying the physical names of resources in CloudFormation: see here for more info

Assigning physical names to resources has some disadvantages in AWS CloudFormation. Most importantly, any changes to deployed resources that require a resource replacement, such as changes to a resource's properties that are immutable after creation, will fail if a resource has a physical name assigned. If you end up in that state, the only solution is to delete the AWS CloudFormation stack, then deploy the AWS CDK app again. See the AWS CloudFormation documentation for details.

github-actions[bot] commented 1 year ago

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.

LosD commented 1 year ago

@peterwoodworth Subnet configurations requires a name, at least in the TypeScript lib (comments removed for brevity):

export interface SubnetConfiguration {
    readonly cidrMask?: number;
    readonly subnetType: SubnetType;
    readonly name: string;
    readonly reserved?: boolean;
    readonly mapPublicIpOnLaunch?: boolean;
}
peterwoodworth commented 1 year ago

You're right, that is part of specifying the logical ID (as you would define on any other construct), and it isn't used as part of the physical resource at all. The problem remains however, that CloudFormation will opt to create the new resources before deleting the old ones in this scenario, which causes this conflict.

ronkorving commented 3 weeks ago

How is that not a problem that needs a solution? I'm not sure why this is marked as "completed".