Skip to content

Commit e9a4a79

Browse files
Elad Ben-Israelshivlaks
Elad Ben-Israel
authored andcommitted
fix(core): use default account/region when environment is not specified (#2867)
The PR #2728 caused a regression on how the framework behaves when a stack's environment (account and/or region) are not specified. The behavior is: if account and/or region are not specified at the stack level (or set to Aws.accountId and Aws.region, respectively), the cloud assembly manifest of this stack will have an environment specification based on the defaults passed in from the CLI. This is a temporary solution which fixes #2853 but doesn't fully implement the behavior we eventually want (which is documented in #2866).
1 parent a691900 commit e9a4a79

File tree

2 files changed

+154
-8
lines changed

2 files changed

+154
-8
lines changed

packages/@aws-cdk/cdk/lib/stack.ts

+16-7
Original file line numberDiff line numberDiff line change
@@ -505,17 +505,24 @@ export class Stack extends Construct implements ITaggable {
505505
*/
506506
private parseEnvironment(env: Environment = {}) {
507507
// if an environment property is explicitly specified when the stack is
508-
// created, it will be used as concrete values for all intents.
509-
const region = env.region;
510-
const account = env.account;
508+
// created, it will be used as concrete values for all intents. if not, use
509+
// tokens for account and region but they do not need to be scoped, the only
510+
// situation in which export/fn::importvalue would work if { Ref:
511+
// "AWS::AccountId" } is the same for provider and consumer anyway.
512+
const region = env.region || Aws.region;
513+
const account = env.account || Aws.accountId;
514+
515+
// temporary fix for #2853, eventually behavior will be based on #2866.
516+
// set the cloud assembly manifest environment spec of this stack to use the
517+
// default account/region from the toolkit in case account/region are undefined or
518+
// unresolved (i.e. tokens).
519+
const envAccount = !Token.isUnresolved(account) ? account : Context.getDefaultAccount(this) || 'unknown-account';
520+
const envRegion = !Token.isUnresolved(region) ? region : Context.getDefaultRegion(this) || 'unknown-region';
511521

512-
// account and region do not need to be scoped, the only situation in which
513-
// export/fn::importvalue would work if { Ref: "AWS::AccountId" } is the
514-
// same for provider and consumer anyway.
515522
return {
516523
account: account || Aws.accountId,
517524
region: region || Aws.region,
518-
environment: EnvironmentUtils.format(account || 'unknown-account', region || 'unknown-region')
525+
environment: EnvironmentUtils.format(envAccount, envRegion)
519526
};
520527
}
521528

@@ -651,9 +658,11 @@ function cfnElements(node: IConstruct, into: CfnElement[] = []): CfnElement[] {
651658
import { Arn, ArnComponents } from './arn';
652659
import { CfnElement } from './cfn-element';
653660
import { CfnResource, TagType } from './cfn-resource';
661+
import { Context } from './context';
654662
import { CfnReference } from './private/cfn-reference';
655663
import { Aws, ScopedAws } from './pseudo';
656664
import { ITaggable, TagManager } from './tag-manager';
665+
import { Token } from './token';
657666

658667
/**
659668
* Find all resources in a set of constructs

packages/@aws-cdk/cdk/test/test.environment.ts

+138-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { DEFAULT_ACCOUNT_CONTEXT_KEY, DEFAULT_REGION_CONTEXT_KEY } from '@aws-cdk/cx-api';
2+
import cxapi = require('@aws-cdk/cx-api');
23
import { Test } from 'nodeunit';
3-
import { App, Stack, Token } from '../lib';
4+
import { App, Aws, Stack, Token } from '../lib';
45

56
export = {
67
'By default, environment region and account are not defined and resolve to intrinsics'(test: Test) {
@@ -40,4 +41,140 @@ export = {
4041

4142
test.done();
4243
},
44+
45+
'environment defaults': {
46+
'default-account-unknown-region'(test: Test) {
47+
// GIVEN
48+
const app = new App();
49+
50+
// WHEN
51+
app.node.setContext(cxapi.DEFAULT_ACCOUNT_CONTEXT_KEY, 'my-default-account');
52+
const stack = new Stack(app, 'stack');
53+
54+
// THEN
55+
test.deepEqual(stack.resolve(stack.account), { Ref: 'AWS::AccountId' }); // TODO: after we implement #2866 this should be 'my-default-account'
56+
test.deepEqual(stack.resolve(stack.region), { Ref: 'AWS::Region' });
57+
test.deepEqual(app.synth().getStack(stack.stackName).environment, {
58+
account: 'my-default-account',
59+
region: 'unknown-region',
60+
name: 'aws://my-default-account/unknown-region'
61+
});
62+
63+
test.done();
64+
},
65+
66+
'default-account-explicit-region'(test: Test) {
67+
// GIVEN
68+
const app = new App();
69+
70+
// WHEN
71+
app.node.setContext(cxapi.DEFAULT_ACCOUNT_CONTEXT_KEY, 'my-default-account');
72+
const stack = new Stack(app, 'stack', { env: { region: 'explicit-region' }});
73+
74+
// THEN
75+
test.deepEqual(stack.resolve(stack.account), { Ref: 'AWS::AccountId' }); // TODO: after we implement #2866 this should be 'my-default-account'
76+
test.deepEqual(stack.resolve(stack.region), 'explicit-region');
77+
test.deepEqual(app.synth().getStack(stack.stackName).environment, {
78+
account: 'my-default-account',
79+
region: 'explicit-region',
80+
name: 'aws://my-default-account/explicit-region'
81+
});
82+
83+
test.done();
84+
},
85+
86+
'explicit-account-explicit-region'(test: Test) {
87+
// GIVEN
88+
const app = new App();
89+
90+
// WHEN
91+
app.node.setContext(cxapi.DEFAULT_ACCOUNT_CONTEXT_KEY, 'my-default-account');
92+
const stack = new Stack(app, 'stack', { env: {
93+
account: 'explicit-account',
94+
region: 'explicit-region'
95+
}});
96+
97+
// THEN
98+
test.deepEqual(stack.resolve(stack.account), 'explicit-account');
99+
test.deepEqual(stack.resolve(stack.region), 'explicit-region');
100+
test.deepEqual(app.synth().getStack(stack.stackName).environment, {
101+
account: 'explicit-account',
102+
region: 'explicit-region',
103+
name: 'aws://explicit-account/explicit-region'
104+
});
105+
106+
test.done();
107+
},
108+
109+
'default-account-default-region'(test: Test) {
110+
// GIVEN
111+
const app = new App();
112+
113+
// WHEN
114+
app.node.setContext(cxapi.DEFAULT_ACCOUNT_CONTEXT_KEY, 'my-default-account');
115+
app.node.setContext(cxapi.DEFAULT_REGION_CONTEXT_KEY, 'my-default-region');
116+
const stack = new Stack(app, 'stack');
117+
118+
// THEN
119+
test.deepEqual(stack.resolve(stack.account), { Ref: 'AWS::AccountId' }); // TODO: after we implement #2866 this should be 'my-default-account'
120+
test.deepEqual(stack.resolve(stack.region), { Ref: 'AWS::Region' }); // TODO: after we implement #2866 this should be 'my-default-region'
121+
test.deepEqual(app.synth().getStack(stack.stackName).environment, {
122+
account: 'my-default-account',
123+
region: 'my-default-region',
124+
name: 'aws://my-default-account/my-default-region'
125+
});
126+
127+
test.done();
128+
},
129+
130+
'token-account-token-region-no-defaults'(test: Test) {
131+
// GIVEN
132+
const app = new App();
133+
134+
// WHEN
135+
app.node.setContext(cxapi.DEFAULT_ACCOUNT_CONTEXT_KEY, 'my-default-account');
136+
app.node.setContext(cxapi.DEFAULT_REGION_CONTEXT_KEY, 'my-default-region');
137+
const stack = new Stack(app, 'stack', {
138+
env: {
139+
account: Aws.accountId,
140+
region: Aws.region
141+
}
142+
});
143+
144+
// THEN
145+
test.deepEqual(stack.resolve(stack.account), { Ref: 'AWS::AccountId' });
146+
test.deepEqual(stack.resolve(stack.region), { Ref: 'AWS::Region' });
147+
test.deepEqual(app.synth().getStack(stack.stackName).environment, {
148+
account: 'my-default-account',
149+
region: 'my-default-region',
150+
name: 'aws://my-default-account/my-default-region'
151+
});
152+
153+
test.done();
154+
},
155+
156+
'token-account-token-region-with-defaults'(test: Test) {
157+
// GIVEN
158+
const app = new App();
159+
160+
// WHEN
161+
const stack = new Stack(app, 'stack', {
162+
env: {
163+
account: Aws.accountId,
164+
region: Aws.region
165+
}
166+
});
167+
168+
// THEN
169+
test.deepEqual(stack.resolve(stack.account), { Ref: 'AWS::AccountId' });
170+
test.deepEqual(stack.resolve(stack.region), { Ref: 'AWS::Region' });
171+
test.deepEqual(app.synth().getStack(stack.stackName).environment, {
172+
account: 'unknown-account',
173+
region: 'unknown-region',
174+
name: 'aws://unknown-account/unknown-region'
175+
});
176+
177+
test.done();
178+
}
179+
},
43180
};

0 commit comments

Comments
 (0)