Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(aws-core): Tags do not persist on constructs imported from another project (outside current dir) #18914

Closed
franciszabala opened this issue Feb 10, 2022 · 3 comments
Labels
@aws-cdk/core Related to core CDK functionality bug This issue is a bug. p1

Comments

@franciszabala
Copy link

franciszabala commented Feb 10, 2022

What is the problem?

Tags are not present on custom constructs that are imported from another project (outside of current project dir).

Consider the following file structure:

├── external-project
│   ├── lib
│   │   └── vpc.ts
│   ├── package.json
│   └── tsconfig.json
└── main-project
    ├── lib
    │   ├── index.ts
    │   ├── one-internal-one-external.ts
    │   └── vpc.ts
    ├── cdk.json
    ├── package.json
    └── tsconfig.json

I am importing a custom construct from external-project/lib/vpc.ts into main-project/lib/one-internal-one-external.ts, then running cdk synth from main-project/. This works without error however the generated CFN template does not include any tags on the externally imported resource. The internally imported custom constructs (e.g. main-project/lib/vpc.ts) are fine as they include the expected tags in the template.

Reproduction Steps

Update: check out this repo https://github.com/ryparker/aws-cdk-external-construct-tags

  1. Create 2 directories. cdk-test-lib and cdk-test-proj

  2. Go to cdk-test-lib and execute cdk init lib --language=typescript

  3. Once done, got to lib folder (it should contain index.ts) then create vpc.ts

  4. In vpc.ts, add this

    import { Construct } from "constructs";
    import { aws_ec2 as ec2 } from "aws-cdk-lib";
    
    export class VPCConstruct extends Construct {
    constructor(scope: Construct, id: string) {
    super(scope, id);
    
    const vpc = new ec2.Vpc(this, "using-external-lib", {
     cidr: "10.0.0.0/16",
     natGateways: 1,
     maxAzs: 3,
     subnetConfiguration: [
       {
         name: "private-subnet-1",
         subnetType: ec2.SubnetType.PRIVATE_WITH_NAT,
         cidrMask: 24,
       },
       {
         name: "public-subnet-1",
         subnetType: ec2.SubnetType.PUBLIC,
         cidrMask: 24,
       },
       {
         name: "isolated-subnet-1",
         subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
         cidrMask: 28,
       },
     ],
    });
    }
    }
  5. Once done, go to the root dir of cdk-test-lib and execute npm run build.

  6. Navigate to cdk-test-proj, execute cdk init app --language=typescript and edit bin/cdk-test-proj.ts

#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { VPCConstruct } from '../../cdk-test-lib/lib/vpc';

export class CdkStarterStack extends cdk.Stack {
        constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
        super(scope, id, props);
                new VPCConstruct(this, "using-external-lib");
        }

}

const app = new cdk.App();
new CdkStarterStack(app, 'CdkStarterStack');
  1. Save it, go to the root directory of cdk-test-proj and execute cdk ls
  2. Check out cdk.out/CdkStarterStack.template.json and see that the subnets don't have any tags.
  3. Sanity check: copy all the files in cdk-test-lib/lib and paste them to cdk-test-proj/ext_lib (create the ext_lib)
  4. Update the codes in bin/cdk-test-proj.ts to
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { VPCConstruct } from '../../cdk-test-lib/lib/vpc';
import { VPCConstruct as VPCInternal } from '../ext_lib/vpc';

export class CdkStarterStack extends cdk.Stack {
        constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
        super(scope, id, props);
                new VPCConstruct(this, "using-external-lib");
                new VPCInternal(this, "using-internal");
        }

}

const app = new cdk.App();
new CdkStarterStack(app, 'CdkStarterStack');
  1. Check out cdk.out/CdkStarterStack.template.json and see that the subnets for "using-internal" construct has its subnet with tag

What did you expect to happen?

I expect that regardless of the location of the library file, the synthesized template should be the same and have its subnets tagged. Subnets should have tag.

e.g. (except from template synthesized from above code)

usinginternalusingexternallibprivatesubnet1Subnet1RouteTableE9991CD9": {
      "Type": "AWS::EC2::RouteTable",
      "Properties": {
        "VpcId": {
          "Ref": "usinginternalusingexternallibEBC0D045"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": "CdkStarterStack/using-internal/using-external-lib/private-subnet-1Subnet1"
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "CdkStarterStack/using-internal/using-external-lib/private-subnet-1Subnet1/RouteTable"
      }
    }

What actually happened?

Subnets don't have any tags. Even the VPC wasn't tagged when using library files outside the project directory

CDK CLI Version

2.12.0 (build c9786db)

Framework Version

No response

Node.js Version

v14.18.2

OS

Amazon Linux 2 (ami-02a45d709a415958a)

Language

Typescript

Language Version

No response

Other information

No response

@franciszabala franciszabala added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Feb 10, 2022
@github-actions github-actions bot added the @aws-cdk/aws-ec2 Related to Amazon Elastic Compute Cloud label Feb 10, 2022
@franciszabala franciszabala changed the title (module name): short issue description (aws_ec2): VPC generated has no tags Feb 10, 2022
@franciszabala franciszabala changed the title (aws_ec2): VPC generated has no tags (aws-ec2): VPC generated has no tags Feb 10, 2022
@franciszabala
Copy link
Author

franciszabala commented Feb 12, 2022

I would like to add that it is not isolated to a VPC. Any custom construct being used as library outside the main project's directory will have its tags removed in the final cfn template. One work around is to copy the output of npm run build of the library folder and copy it to the main project folder and use that as the current library.

Also tested using symbolic link. It doesn't work either.

@NGL321 NGL321 added p2 and removed needs-triage This issue or PR still needs to be triaged. labels Feb 14, 2022
@ryparker ryparker added p1 and removed p2 labels Feb 23, 2022
@ryparker ryparker changed the title (aws-ec2): VPC generated has no tags (aws-ec2): VPC has no tags when using construct from outside project dir Mar 18, 2022
@ryparker
Copy link
Contributor

I was able to reproduce this and i've made a repo with the simplest reproduction. I've also created a couple of tests in that repo that validate this problem.

@ryparker ryparker changed the title (aws-ec2): VPC has no tags when using construct from outside project dir (aws-core): Tags do not persist on constructs imported from another project (outside current dir) Mar 18, 2022
@ryparker ryparker added @aws-cdk/aws-ec2 Related to Amazon Elastic Compute Cloud @aws-cdk/custom-resources Related to AWS CDK Custom Resources @aws-cdk/core Related to core CDK functionality and removed @aws-cdk/aws-ec2 Related to Amazon Elastic Compute Cloud @aws-cdk/custom-resources Related to AWS CDK Custom Resources labels Mar 18, 2022
mergify bot pushed a commit that referenced this issue Mar 22, 2022
When construct libraries are purposely symlinked (as opposed of
collectively `npm install`ed), depending on how this is done they may
end up with multiple copies of `aws-cdk-lib`. If that happens, Aspects
from a different `aws-cdk-lib` copy than the one providing `App` will
not be applied.

The reason is the use of `Symbol('...')` instead of `Symbol.for('...')`
to keep the list of aspects on the construct object.

- The first version creates a unique symbol per library, while adding
  a naming hint.
- The second version deduplicates: all symbols with the same naming
  hint will receive the same symbol.

The second version is necessary to make sure that different copies
of the `aws-cdk-lib` library store their aspects under the same key.

Fixes #18921, #18778, #19390, #18914
@github-actions
Copy link

github-actions bot commented Apr 6, 2022

⚠️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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/core Related to core CDK functionality bug This issue is a bug. p1
Projects
None yet
Development

No branches or pull requests

4 participants