in src/deployments/cdk/src/deployments/firewall/cluster/step-3.ts [61:186]
export async function step3(props: FirewallStep3Props) {
const { accountBuckets, accountStacks, centralBucket, config, outputs, vpcs, defaultRegion, accounts } = props;
const vpcConfigs = config.getVpcConfigs();
const replacementsConfig = config.replacements;
const replacements = additionalReplacements(replacementsConfig);
for (const [accountKey, accountConfig] of config.getAccountConfigs()) {
const firewallConfigs = accountConfig.deployments?.firewalls;
if (!firewallConfigs || firewallConfigs.length === 0) {
continue;
}
const accountWarming = checkAccountWarming(accountKey, outputs);
const accountWarmingStatus =
accountConfig['account-warming-required'] &&
!(accountWarming.accountWarmed || (accountWarming.timeLeft && accountWarming.timeLeft > 0));
if (accountWarmingStatus) {
console.log(`Skipping firewall deployment: account "${accountKey}" is not warmed`);
continue;
}
const accountBucket = accountBuckets[accountKey];
if (!accountBucket) {
throw new Error(`Cannot find default account bucket for account ${accountKey}`);
}
const subscriptionOutputs = getStackJsonOutput(outputs, {
outputType: 'AmiSubscriptionStatus',
accountKey,
});
for (const firewallConfig of firewallConfigs.filter(firewall => c.FirewallEC2ConfigType.is(firewall))) {
if (!firewallConfig.deploy) {
console.log(`Deploy set to false for "${firewallConfig.name}"`);
continue;
}
if (!c.FirewallEC2ConfigType.is(firewallConfig)) {
continue;
}
const attachConfig = firewallConfig['tgw-attach'];
if (!c.TransitGatewayAttachConfigType.is(attachConfig)) {
continue;
}
const subscriptionStatus = subscriptionOutputs.find(sub => sub.imageId === firewallConfig['image-id']);
if (subscriptionStatus && subscriptionStatus.status === OUTPUT_SUBSCRIPTION_REQUIRED) {
console.log(`AMI Marketplace subscription required for ImageId: ${firewallConfig['image-id']}`);
continue;
}
// TODO add region check also if vpc name is not unique accross Account
const vpcConfig = vpcConfigs.find(v => v.vpcConfig.name === firewallConfig.vpc)?.vpcConfig;
if (!vpcConfig) {
console.log(`Skipping firewall deployment because of missing VPC config "${firewallConfig.vpc}"`);
continue;
}
const vpc = vpcs.find(v => v.name === firewallConfig.vpc);
if (!vpc) {
console.log(`Skipping firewall deployment because of missing VPC "${firewallConfig.vpc}"`);
continue;
}
// Find the firewall VPN connections in the TGW account
const firewallVpnConnectionOutputs = FirewallVpnConnectionOutputFinder.findAll({
outputs,
accountKey: attachConfig.account,
region: firewallConfig.region,
});
const firewallVpnConnections = firewallVpnConnectionOutputs
.flatMap(array => array)
.filter(conn => conn.firewallAccountKey === accountKey && conn.firewallName === firewallConfig.name);
if (firewallVpnConnections.length === 0) {
console.warn(`Cannot find firewall VPN connection outputs`);
continue;
}
const accountStack = accountStacks.tryGetOrCreateAccountStack(accountKey, firewallConfig.region);
if (!accountStack) {
console.warn(`Cannot find account stack ${accountStack}`);
continue;
}
let sleep: CfnSleep | undefined;
if (
accountConfig['account-warming-required'] &&
!accountWarming.accountWarmed &&
accountWarming.timeLeft &&
accountWarming.timeLeft > 0
) {
const existing = accountStack.node.tryFindChild('ClusterSleep');
if (existing) {
sleep = existing as CfnSleep;
} else {
sleep = new CfnSleep(accountStack, 'ClusterSleep', {
// Setting 5 minutes sleep and performing firewall cluster creation.
sleep: 5 * 60 * 1000,
});
}
}
await createFirewallCluster({
accountBucket,
accountStack,
centralBucket,
firewallConfig,
firewallVpnConnections,
vpc,
vpcConfig,
replacements,
sleep,
userData: firewallConfig['user-data']
? await addReplacementsToUserData({
userData: firewallConfig['user-data']!,
accountKey,
accountStack,
config,
defaultRegion,
outputs,
accounts,
})
: undefined,
});
}
}
}