0

I’m trying to update some AWS CDK code past version 1.9.0 to version 1.152.0. However, there’s one issue that is causing a problem - the setContext code is not valid anymore.


The error message I'm seeing is ‘Cannot set context after children have been added: Tree’

The code I am trying to update is:

const app = new cdk.App();

let stage: string = app.node.tryGetContext('stage');

// AppConfig is a custom defined interface  
// stageConfig is a variable of custom defined interface, StageConfig
const appConfig: AppConfig = {
  domainName: app.node.tryGetContext('domainName'),
  isProduction: stage === 'prod',
  stageName: stage,
  // default to getting dev config if stage is other than prod or test
  stageConfig: app.node.tryGetContext(stage === 'prod' || stage === 'test' ? stage : 'dev')
};

// set appConfig as a context variable for downstream stacks to use
app.node.setContext('config', appConfig);

I believe the main issue is that when the variable app is being defined, it now needs to include the set context data. That means I cannot use app.node.tryGetContext anymore because it's referencing the variable I am trying to define.

I tried to set stage to process.env.STAGE and domainName to process.env.DOMAINNAME but both seem to always return 'undefined':

let stage = process.env.STAGE || 'dev';

let app = new cdk.App({
  context: { ['config']: {
    domainName: process.env.DOMAINNAME,
    isProduction: stage === 'prod',
    stageName: stage,
    stageConfig: process.env.STAGE === (stage === 'prod' || stage === 'test' ? stage : 'dev')
  }}
});
et025
  • 3
  • 3

1 Answers1

0

Setting context on the App level is not possible after 1.9.0 per https://github.com/aws/aws-cdk/issues/4359

Your options are to either set it at a construct level (instead of app) or initialize the app with the context like you're doing in your second example, but then you cannot refer to any existing context variables.

process.env contains your environment variables. If it returns undefined, that means that there's no env variable with that name.

gshpychka
  • 8,523
  • 1
  • 11
  • 31
  • Thanks for the reply! So you're saying `setContext` can still be used in the stack.ts file (where I have the code `export class MyStack extends cdk.Stack {...}`)? The code above is in a separate file (app.ts), where `app` is initialized and `new MyStack` is created. Is there any advantage to either option - either initializing the app with the context in app.ts (with a .env file I assume since the variables I'm trying to access are returning not defined) or using `setContext` in stack.ts? – et025 Jan 27 '23 at 21:53
  • It depends on where you want your context to be available. If you only have a single stack, then I would use the `setContext` method on the stack, since that allows you to refer to existing context values. But other stacks will not see this change in the context. – gshpychka Jan 30 '23 at 12:26
  • I have 3 stacks, 3 stages - dev, test, prod. I've tried setting the context a couple different ways based on what you suggested, both in my app.ts file and:/ in my stack.ts file just to see, but for each attempt I'm receiving an error saying "TypeError: Cannot read properties of undefined (reading 'policyFragment')" at `const fragment = principal.policyFragment;` I'm not sure if that's related to setting the context or maybe a different issue altogether.. – et025 Feb 01 '23 at 16:39
  • Different issue. – gshpychka Feb 01 '23 at 16:40