in src/core/runtime/src/get-baseline-step.ts [127:384]
async function assignDynamicCidrs(input: AssignCidrInput) {
const {
cidrPoolsTable,
configCommitId,
configFilePath,
configRepositoryName,
subnetCidrPoolAssignedTable,
vpcCidrPoolAssignedTable,
} = input;
const config = await loadAcceleratorConfig({
repositoryName: configRepositoryName,
filePath: configFilePath,
commitId: configCommitId,
});
const assignedSubnetCidrPools = await loadAssignedSubnetCidrPool(subnetCidrPoolAssignedTable);
const cidrPools = await loadCidrPools(cidrPoolsTable);
if (cidrPools.length === 0 && config['global-options']['cidr-pools'].length > 0) {
// load cidrs from config to ddb
for (const [index, configCidrPool] of Object.entries(config['global-options']['cidr-pools'])) {
const updateExpression = getUpdateValueInput([
{
key: 'c',
name: 'cidr',
type: 'S',
value: configCidrPool.cidr.toCidrString(),
},
{
key: 'r',
name: 'region',
type: 'S',
value: configCidrPool.region,
},
{
key: 'p',
name: 'pool',
type: 'S',
value: configCidrPool.pool,
},
]);
await dynamoDB.updateItem({
TableName: cidrPoolsTable,
Key: {
id: { S: `${parseInt(index, 10) + 1}` },
},
...updateExpression,
});
}
cidrPools.push(...(await loadCidrPools(cidrPoolsTable)));
}
const lookupCidrs = async (
accountKey: string,
vpcConfig: VpcConfig,
assignedVpcCidrPools: AssignedVpcCidrPool[],
ouKey?: string,
) => {
let existingCidrs = assignedVpcCidrPools.filter(
vp =>
vp.region === vpcConfig.region &&
vp['vpc-name'] === vpcConfig.name &&
((vp['account-Key'] && vp['account-Key'] === accountKey) || vp['account-ou-key'] === `account/${accountKey}`),
);
if (existingCidrs.length === 0) {
existingCidrs = assignedVpcCidrPools.filter(
vp =>
vp.region === vpcConfig.region &&
vp['vpc-name'] === vpcConfig.name &&
vp['account-ou-key'] === `organizational-unit/${ouKey}`,
);
}
if (existingCidrs.length === 0) {
throw new Error(`VPC "${vpcConfig.region}/${vpcConfig.name}" Cidr-Src is lookup and didn't find entry in DDB`);
}
for (const existingCidr of existingCidrs) {
if (existingCidr['account-ou-key'] === `organizational-unit/${ouKey}`) {
await updateVpcCidr(vpcCidrPoolAssignedTable, uuidv4(), {
accountOuKey: `account/${accountKey}`,
cidr: existingCidr.cidr,
pool: existingCidr.pool,
region: vpcConfig.region,
vpc: vpcConfig.name,
accountKey,
vpcAssignedId: `${existingCidr['vpc-assigned-id']}`,
});
}
}
for (const subnetConfig of vpcConfig.subnets || []) {
for (const subnetDef of subnetConfig.definitions) {
let existingSubnet = assignedSubnetCidrPools.find(
sp =>
sp['subnet-name'] === subnetConfig.name &&
sp.az === subnetDef.az &&
sp['vpc-name'] === vpcConfig.name &&
sp.region === vpcConfig.region &&
((sp['account-Key'] && sp['account-Key'] === accountKey) ||
sp['account-ou-key'] === `account/${accountKey}`),
);
if (!existingSubnet) {
existingSubnet = assignedSubnetCidrPools.find(
sp =>
sp['subnet-name'] === subnetConfig.name &&
sp.az === subnetDef.az &&
sp['vpc-name'] === vpcConfig.name &&
sp.region === vpcConfig.region &&
sp['account-ou-key'] === `organizational-unit/${ouKey}`,
);
}
if (!existingSubnet) {
throw new Error(
`Subnet "${vpcConfig.region}/${vpcConfig.name}/${subnetConfig.name}/${subnetDef.az}" Cidr-Src is lookup and didn't find entry in DDB`,
);
}
if (existingSubnet['account-ou-key'] === `organizational-unit/${ouKey}`) {
await updateSubnetCidr(subnetCidrPoolAssignedTable, uuidv4(), {
accountOuKey: `account/${accountKey}`,
cidr: existingSubnet.cidr,
pool: existingSubnet['sub-pool'],
region: vpcConfig.region,
vpc: vpcConfig.name,
subnet: subnetConfig.name,
az: subnetDef.az,
accountKey,
});
}
}
}
};
const dynamicCidrs = async (
accountKey: string,
vpcConfig: VpcConfig,
assignedVpcCidrPools: AssignedVpcCidrPool[],
) => {
const vpcCidr: { [key: string]: string } = {};
for (const vpcCidrObj of vpcConfig.cidr) {
const currentPool = cidrPools.find(cp => cp.region === vpcConfig.region && cp.pool === vpcCidrObj.pool);
if (!currentPool) {
throw new Error(`Didn't find entry for "${vpcCidrObj.pool}" in cidr-pools DDB table`);
}
const existingCidr = assignedVpcCidrPools.find(
vp =>
vp.region === vpcConfig.region &&
vp['vpc-name'] === vpcConfig.name &&
vp.pool === vpcCidrObj.pool &&
((vp['account-Key'] && vp['account-Key'] === accountKey) || vp['account-ou-key'] === `account/${accountKey}`),
);
if (!existingCidr) {
const usedCidrs = assignedVpcCidrPools
.filter(
vp => vp.region === vpcConfig.region && vp.pool === vpcCidrObj.pool,
// ((vp['account-Key'] && vp['account-Key'] === accountKey) ||
// vp['account-ou-key'] === `account/${accountKey}` ||
// (ouKey && vp['account-ou-key'] === `organizational-unit/${ouKey}`)),
)
.map(vp => vp.cidr);
const pool = poolFromCidr(currentPool.cidr);
const currentPoolCidrRange = pool.getCidrRange(IPv4Prefix.fromNumber(vpcCidrObj.size!));
vpcCidr[vpcCidrObj.pool] = getAvailableCidr(usedCidrs, currentPoolCidrRange);
if (
IPv4CidrRange.fromCidr(currentPool.cidr)
.getLast()
.isLessThan(IPv4CidrRange.fromCidr(vpcCidr[vpcCidrObj.pool]).getFirst())
) {
throw new Error(
`Cidr Pool : "${currentPool.cidr} ran out of space while assigning for VPC: "${vpcConfig.region}/${vpcConfig.name}"`,
);
}
await updateVpcCidr(vpcCidrPoolAssignedTable, uuidv4(), {
accountOuKey: `account/${accountKey}`,
cidr: vpcCidr[vpcCidrObj.pool],
pool: vpcCidrObj.pool,
region: vpcConfig.region,
vpc: vpcConfig.name,
accountKey,
});
} else {
vpcCidr[vpcCidrObj.pool] = existingCidr.cidr;
}
}
const usedSubnetCidrs = assignedSubnetCidrPools
.filter(
sp => sp.region === vpcConfig.region && sp['vpc-name'] === vpcConfig.name,
// ((vp['account-Key'] && vp['account-Key'] === accountKey) ||
// vp['account-ou-key'] === `account/${accountKey}` ||
// (ouKey && vp['account-ou-key'] === `organizational-unit/${ouKey}`)),
)
.map(sp => sp.cidr);
for (const subnetConfig of vpcConfig.subnets || []) {
for (const subnetDef of subnetConfig.definitions) {
if (!subnetDef.cidr) {
throw new Error(
`Didn't find Cidr in Configuration for Subnet "${accountKey}/${vpcConfig.name}/${subnetConfig.name}"`,
);
}
console.log(
`Creating Dynamic CIDR for "${subnetConfig.name}.${subnetDef.az}" of pool ${
subnetDef.cidr.pool
} with VPC Cidr ${vpcCidr[subnetDef.cidr.pool]}`,
);
const subnetPool = Pool.fromCidrRanges([IPv4CidrRange.fromCidr(vpcCidr[subnetDef.cidr.pool])]);
let subnetCidr = '';
const existingSubnet = assignedSubnetCidrPools.find(
sp =>
sp['subnet-name'] === subnetConfig.name &&
sp.az === subnetDef.az &&
sp['vpc-name'] === vpcConfig.name &&
sp.region === vpcConfig.region &&
((sp['account-Key'] && sp['account-Key'] === accountKey) ||
sp['account-ou-key'] === `account/${accountKey}`),
);
if (!existingSubnet) {
const currentSubnetCidrRange = subnetPool.getCidrRange(IPv4Prefix.fromNumber(subnetDef.cidr.size!));
subnetCidr = getAvailableCidr(usedSubnetCidrs, currentSubnetCidrRange);
if (
IPv4CidrRange.fromCidr(vpcCidr[subnetDef.cidr.pool])
.getLast()
.isLessThan(IPv4CidrRange.fromCidr(subnetCidr).getFirst())
) {
throw new Error(
`Error while creating dynamic CIDR for Subnets in VPC: "${vpcConfig.region}/${vpcConfig.name}"`,
);
}
console.log(`Dynamic CIDR for "${subnetConfig.name}.${subnetDef.az}" is "${subnetCidr}"`);
await updateSubnetCidr(subnetCidrPoolAssignedTable, uuidv4(), {
accountOuKey: `account/${accountKey}`,
cidr: subnetCidr,
pool: subnetDef.cidr.pool,
region: vpcConfig.region,
vpc: vpcConfig.name,
subnet: subnetConfig.name,
az: subnetDef.az,
accountKey,
});
} else {
subnetCidr = existingSubnet.cidr;
}
}
}
};
// creating an IPv4 range from CIDR notation
for (const { accountKey, vpcConfig, ouKey } of config.getVpcConfigs()) {
if (vpcConfig['cidr-src'] === 'provided') {
continue;
}
const assignedVpcCidrPools = await loadAssignedVpcCidrPool(vpcCidrPoolAssignedTable);
if (vpcConfig['cidr-src'] === 'lookup') {
await lookupCidrs(accountKey, vpcConfig, assignedVpcCidrPools, ouKey);
} else if (vpcConfig['cidr-src'] === 'dynamic') {
await dynamicCidrs(accountKey, vpcConfig, assignedVpcCidrPools);
}
}
}