in src/core/runtime/src/save-outputs-to-ssm/network-outputs.ts [55:275]
export async function saveNetworkOutputs(props: SaveOutputsInput) {
const {
acceleratorPrefix,
account,
config,
dynamodb,
outputsTableName,
assumeRoleName,
region,
outputUtilsTableName,
} = props;
const oldNetworkOutputUtils = await getIndexOutput(
outputUtilsTableName,
`${account.key}-${region}-network`,
dynamodb,
);
// Existing index check happens on this variable
let networkOutputUtils: OutputUtilNetwork;
if (oldNetworkOutputUtils) {
networkOutputUtils = oldNetworkOutputUtils;
} else {
networkOutputUtils = {
vpcs: [],
};
}
// Storing new resource index and updating DDB in this variable
const newNetworkOutputs: OutputUtilNetwork = {
vpcs: [],
};
if (!newNetworkOutputs.vpcs) {
newNetworkOutputs.vpcs = [];
}
// Removal from SSM Parameter store happens on left over in this variable
const removalObjects: OutputUtilNetwork = {
vpcs: [...(networkOutputUtils.vpcs || [])],
};
const vpcConfigs = config.getVpcConfigs();
const localVpcConfigs = vpcConfigs.filter(
vc => vc.accountKey === account.key && vc.vpcConfig.region === region && !vc.ouKey,
);
const localOuVpcConfigs = vpcConfigs.filter(
vc => vc.accountKey === account.key && vc.vpcConfig.region === region && vc.ouKey,
);
const sharedVpcConfigs = vpcConfigs.filter(
vc =>
vc.accountKey !== account.key &&
vc.vpcConfig.region === region &&
vc.ouKey === account.ou &&
(vc.vpcConfig.subnets?.find(sc => sc['share-to-ou-accounts']) ||
vc.vpcConfig.subnets?.find(sc => sc['share-to-specific-accounts']?.includes(account.key))),
);
let localOutputs: StackOutput[] = [];
if (localVpcConfigs.length > 0 || localOuVpcConfigs.length > 0) {
localOutputs = await getOutput(outputsTableName, `${account.key}-${region}-1`, dynamodb);
}
if (!networkOutputUtils.vpcs) {
networkOutputUtils.vpcs = [];
}
const lvpcIndices = networkOutputUtils.vpcs.filter(lv => lv.type === 'lvpc').flatMap(v => v.index) || [];
let lvpcMaxIndex = lvpcIndices.length === 0 ? 0 : Math.max(...lvpcIndices);
const sts = new STS();
const credentials = await sts.getCredentialsForAccountAndRole(account.id, assumeRoleName);
const ssm = new SSM(credentials, region);
for (const resolvedVpcConfig of localVpcConfigs) {
let currentIndex: number;
const previousIndex = networkOutputUtils.vpcs.findIndex(
vpc => vpc.type === 'lvpc' && vpc.name === resolvedVpcConfig.vpcConfig.name,
);
if (previousIndex >= 0) {
currentIndex = networkOutputUtils.vpcs[previousIndex].index;
} else {
currentIndex = ++lvpcMaxIndex;
}
const vpcResult = await saveVpcOutputs({
index: currentIndex,
resolvedVpcConfig,
outputs: localOutputs,
ssm,
acceleratorPrefix,
vpcPrefix: 'lvpc',
account,
vpcUtil: previousIndex >= 0 ? networkOutputUtils.vpcs[previousIndex] : undefined,
});
if (vpcResult) {
newNetworkOutputs.vpcs.push(vpcResult);
}
const removalIndex = removalObjects.vpcs?.findIndex(
vpc => vpc.type === 'lvpc' && vpc.name === resolvedVpcConfig.vpcConfig.name,
);
if (removalIndex! >= 0) {
removalObjects.vpcs?.splice(removalIndex!, 1);
}
}
const vpcIndices = networkOutputUtils.vpcs.filter(vpc => vpc.type === 'vpc').flatMap(v => v.index) || [];
let vpcMaxIndex = vpcIndices.length === 0 ? 0 : Math.max(...vpcIndices);
for (const resolvedVpcConfig of localOuVpcConfigs) {
let currentIndex: number;
const previousIndex = networkOutputUtils.vpcs.findIndex(
vpc => vpc.type === 'vpc' && vpc.name === resolvedVpcConfig.vpcConfig.name,
);
if (previousIndex >= 0) {
currentIndex = networkOutputUtils.vpcs[previousIndex].index;
} else {
currentIndex = ++vpcMaxIndex;
}
const vpcResult = await saveVpcOutputs({
index: currentIndex,
resolvedVpcConfig,
outputs: localOutputs,
ssm,
acceleratorPrefix,
vpcPrefix: 'vpc',
account,
vpcUtil: previousIndex >= 0 ? networkOutputUtils.vpcs[previousIndex] : undefined,
});
if (vpcResult) {
newNetworkOutputs.vpcs.push(vpcResult);
}
const removalIndex = removalObjects.vpcs?.findIndex(
vpc => vpc.type === 'vpc' && vpc.name === resolvedVpcConfig.vpcConfig.name,
);
if (removalIndex! >= 0) {
removalObjects.vpcs?.splice(removalIndex!, 1);
}
}
if (sharedVpcConfigs.length > 0) {
const sharedSgOutputs: StackOutput[] = await getOutput(outputsTableName, `${account.key}-${region}-2`, dynamodb);
const sgOutputs: SecurityGroupsOutput[] = getStackJsonOutput(sharedSgOutputs, {
accountKey: account.key,
outputType: 'SecurityGroupsOutput',
});
for (const resolvedVpcConfig of sharedVpcConfigs) {
let currentIndex: number;
const previousIndex = networkOutputUtils.vpcs.findIndex(
vpc => vpc.type === 'vpc' && vpc.name === resolvedVpcConfig.vpcConfig.name,
);
if (previousIndex >= 0) {
currentIndex = networkOutputUtils.vpcs[previousIndex].index;
} else {
currentIndex = ++vpcMaxIndex;
}
const rootOutputs: StackOutput[] = await getOutput(
outputsTableName,
`${resolvedVpcConfig.accountKey}-${region}-1`,
dynamodb,
);
const vpcSgOutputs = sgOutputs.find(sg => sg.vpcName);
const vpcResult = await saveVpcOutputs({
index: currentIndex,
resolvedVpcConfig,
outputs: rootOutputs,
ssm,
acceleratorPrefix,
vpcPrefix: 'vpc',
account,
sgOutputs: vpcSgOutputs?.securityGroupIds,
sharedVpc: true,
vpcUtil: previousIndex >= 0 ? networkOutputUtils.vpcs[previousIndex] : undefined,
});
if (vpcResult) {
newNetworkOutputs.vpcs.push(vpcResult);
}
const removalIndex = removalObjects.vpcs?.findIndex(
vpc => vpc.type === 'vpc' && vpc.name === resolvedVpcConfig.vpcConfig.name,
);
if (removalIndex! >= 0) {
removalObjects.vpcs?.splice(removalIndex!, 1);
}
}
}
await saveIndexOutput(
outputUtilsTableName,
`${account.key}-${region}-network`,
JSON.stringify(newNetworkOutputs),
dynamodb,
);
for (const removeObject of removalObjects.vpcs || []) {
const removalSgs = removeObject.securityGroups
.map(sg => [
`/${acceleratorPrefix}/network/${removeObject.type}/${removeObject.index}/sg/${sg.index}/name`,
`/${acceleratorPrefix}/network/${removeObject.type}/${removeObject.index}/sg/${sg.index}/id`,
])
.flatMap(s => s);
const removalSns = removeObject.subnets
.map(sn =>
sn.azs.map(snz => [
`/${acceleratorPrefix}/network/${removeObject.type}/${removeObject.index}/net/${sn.index}/az${snz}/name`,
`/${acceleratorPrefix}/network/${removeObject.type}/${removeObject.index}/net/${sn.index}/az${snz}/id`,
`/${acceleratorPrefix}/network/${removeObject.type}/${removeObject.index}/net/${sn.index}/az${snz}/cidr`,
]),
)
.flatMap(azSn => azSn)
.flatMap(sn => sn);
const removalVpc = [
`/${acceleratorPrefix}/network/${removeObject.type}/${removeObject.index}/name`,
`/${acceleratorPrefix}/network/${removeObject.type}/${removeObject.index}/id`,
`/${acceleratorPrefix}/network/${removeObject.type}/${removeObject.index}/cidr`,
`/${acceleratorPrefix}/network/${removeObject.type}/${removeObject.index}/cidr2`,
];
const removeNames = [...removalSgs, ...removalSns, ...removalVpc];
while (removeNames.length > 0) {
await ssm.deleteParameters(removeNames.splice(0, 10));
}
}
}