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.52k stars 3.86k forks source link

(core): (Synthesizing an app programmatically does not automatically load cdk.context.json) #31499

Open wmattei opened 16 hours ago

wmattei commented 16 hours ago

Describe the feature

If I run cdk synth it will by default add all variables from the cdk.context.json file to the app context.

However, if I run the synth programmatically (app.synth()) I would have to manually read the json file and pass the context variables to the App constructor.

Here is an example of what I mean:

import * as cdk from "aws-cdk-lib";
import { Vpc } from "aws-cdk-lib/aws-ec2";
import { Construct } from "constructs";

export class TestCdkStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const vpc = Vpc.fromLookup(this, "VPC", {
      // This is a dummy VPC ID. But it is in my context file.
      vpcId: "vpc-01234567890",
    });

    console.info(vpc.vpcId);
  }
}

const app = new cdk.App({});
new TestCdkStack(app, "TestCdkStack", {
  env: {
    account: "01234567890",
    region: "us-east-1",
  },
});

app.synth();

If I run cdk synth the logged value will be vpc-01234567890 (because that's what's in my context file)

However, if I just run ts-node ./stack.ts the logged value will be the default dummy vpc (vpc-12345)

Use Case

This would be useful in scenarios where I don't follow the default cdk structure and don't have a bin folder or a cdk.json file at all.

Instead I just want to execute a typescript file that contains the app and all resources I need.

Defining the whole stack in a single executable file is useful when I don't want the developers of my team to worry about any configuration. Just create the resources they want.

Proposed Solution

I suggest that the cdk.App constructor takes a new property "contextDir" which would automatically load the file and set each variable.

Here is a full example of my suggestion:

import * as cdk from "aws-cdk-lib";
import { Vpc } from "aws-cdk-lib/aws-ec2";
import { Construct } from "constructs";

export class TestCdkStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const vpc = Vpc.fromLookup(this, "VPC", {
      // This is a dummy VPC ID. But it is in my context file.
      vpcId: "vpc-01234567890",
    });

    console.info(vpc.vpcId);
  }
}

const app = new cdk.App({
+   contextDir: resolve(__dirname, "./cdk.context.json"), 
});

new TestCdkStack(app, "TestCdkStack", {
  env: {
    account: "01234567890",
    region: "us-east-1",
  },
});

app.synth();

Other Information

No response

Acknowledgements

CDK version used

2.146.0

Environment details (OS name and version, etc.)

Mac OS Sequoia

pahud commented 16 hours ago

Thank you. I will bring this up to the team's attention.