Skip to content

Commit 3ad41ad

Browse files
fix(core): Suspended accounts failure with respect to construct name change of nested stacks in phase-2 (#546)
* fix(core): Maintaining same construct name when a account is suspended by saving in DDB outputs - (security groups on shared VPC's)
1 parent 4e3d68d commit 3ad41ad

File tree

3 files changed

+43
-13
lines changed

3 files changed

+43
-13
lines changed

src/deployments/cdk/src/apps/phase-2.ts

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import * as cfn from '@aws-cdk/aws-cloudformation';
33
import { getAccountId } from '../utils/accounts';
44
import { JsonOutputValue } from '../common/json-output';
55
import { getVpcConfig } from '../common/get-all-vpcs';
6-
import { VpcOutputFinder } from '@aws-accelerator/common-outputs/src/vpc';
6+
import { VpcOutputFinder, SharedSecurityGroupIndexOutput } from '@aws-accelerator/common-outputs/src/vpc';
77
import * as ec2 from '@aws-cdk/aws-ec2';
88
import { PeeringConnectionConfig, VpcConfigType } from '@aws-accelerator/common-config/src';
99
import { getVpcSharedAccountKeys } from '../common/vpc-subnet-sharing';
@@ -26,6 +26,7 @@ import * as centralServices from '../deployments/central-services';
2626
import * as guardDutyDeployment from '../deployments/guardduty';
2727
import * as snsDeployment from '../deployments/sns';
2828
import * as ssmDeployment from '../deployments/ssm';
29+
import { getStackJsonOutput } from '@aws-accelerator/common-outputs/src/stack-output';
2930

3031
/**
3132
* This is the main entry point to deploy phase 2
@@ -170,11 +171,23 @@ export async function deploy({ acceleratorConfig, accountStacks, accounts, conte
170171
continue;
171172
}
172173

173-
const securityGroupStack = new cfn.NestedStack(
174-
accountStack,
175-
`SecurityGroups${vpcConfig.name}-Shared-${index + 1}`,
176-
);
177-
const securityGroups = new SecurityGroup(securityGroupStack, `SecurityGroups-SharedAccount-${index + 1}`, {
174+
/* **********************************************************
175+
* Saving index in outputs to handle nasty bug occur while
176+
* changing construct name when account is suspended
177+
* *********************************************************/
178+
const sgOutputs: SharedSecurityGroupIndexOutput[] = getStackJsonOutput(outputs, {
179+
accountKey: sharedAccountKey,
180+
outputType: 'SecurityGroupIndexOutput',
181+
region: vpcConfig.region,
182+
});
183+
184+
const vpcSgIndex = sgOutputs.find(sgO => sgO.vpcName === vpcConfig.name);
185+
let sgIndex = index + 1;
186+
if (vpcSgIndex) {
187+
sgIndex = vpcSgIndex.index;
188+
}
189+
const securityGroupStack = new cfn.NestedStack(accountStack, `SecurityGroups${vpcConfig.name}-Shared-${sgIndex}`);
190+
const securityGroups = new SecurityGroup(securityGroupStack, `SecurityGroups-SharedAccount-${sgIndex}`, {
178191
securityGroups: vpcConfig['security-groups']!,
179192
vpcName: vpcConfig.name,
180193
vpcId: vpcOutput.vpcId,
@@ -184,16 +197,10 @@ export async function deploy({ acceleratorConfig, accountStacks, accounts, conte
184197
installerVersion: context.installerVersion,
185198
});
186199

187-
const accountId = getAccountId(accounts, accountKey);
188-
if (!accountId) {
189-
console.warn(`Cannot find account with key ${accountKey}`);
190-
continue;
191-
}
192-
193200
// Add Tags Output
194201
const securityGroupsResources = Object.values(securityGroups.securityGroupNameMapping);
195202

196-
new JsonOutputValue(securityGroupStack, `SecurityGroupOutput${vpcConfig.name}-${index}`, {
203+
new JsonOutputValue(securityGroupStack, `SecurityGroupOutput `, {
197204
type: 'SecurityGroupsOutput',
198205
value: {
199206
vpcId: vpcOutput.vpcId,
@@ -205,6 +212,20 @@ export async function deploy({ acceleratorConfig, accountStacks, accounts, conte
205212
},
206213
});
207214

215+
new JsonOutputValue(securityGroupStack, `SecurityGroupIndexOutput`, {
216+
type: 'SecurityGroupIndexOutput',
217+
value: {
218+
vpcName: vpcConfig.name,
219+
index: sgIndex,
220+
},
221+
});
222+
223+
const accountId = getAccountId(accounts, accountKey);
224+
if (!accountId) {
225+
console.warn(`Cannot find account with key ${accountKey}`);
226+
continue;
227+
}
228+
208229
new AddTagsToResourcesOutput(securityGroupStack, `OutputSharedResources${vpcConfig.name}-Shared-${index}`, {
209230
dependencies: securityGroupsResources,
210231
produceResources: () =>

src/lib/common-outputs/src/stack-output.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export function getStackOutput(outputs: StackOutput[], accountKey: string, outpu
4141
export interface StackJsonOutputFilter {
4242
accountKey?: string;
4343
outputType?: string;
44+
region?: string;
4445
}
4546

4647
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -50,6 +51,9 @@ export function getStackJsonOutput(outputs: StackOutput[], filter: StackJsonOutp
5051
if (filter.accountKey && output.accountKey !== filter.accountKey) {
5152
return null;
5253
}
54+
if (filter.region && output.region !== filter.region) {
55+
return null;
56+
}
5357
try {
5458
if (output.outputValue && output.outputValue.startsWith('{')) {
5559
const json = JSON.parse(output.outputValue);

src/lib/common-outputs/src/vpc.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ export interface SecurityGroupsOutput {
1414
securityGroupIds: VpcSecurityGroupOutput[];
1515
}
1616

17+
export interface SharedSecurityGroupIndexOutput {
18+
vpcName: string;
19+
index: number;
20+
}
21+
1722
export const VpcSubnetOutput = t.interface({
1823
subnetId: t.string,
1924
subnetName: t.string,

0 commit comments

Comments
 (0)