in src/deployments/cdk/src/deployments/firewall/cluster/step-2.ts [116:310]
async function createCustomerGateways(props: {
scope: cdk.Construct;
firewallAccountKey: string;
firewallConfig: c.FirewallEC2ConfigType | c.FirewallCGWConfigType;
transitGateway: TransitGatewayOutput;
attachConfig: c.TransitGatewayAttachConfig;
firewallPorts?: FirewallPort[];
}) {
const { scope, firewallAccountKey, firewallConfig, firewallPorts, transitGateway, attachConfig } = props;
// Keep track of the created VPN connection so we can use them in the next steps
const vpnConnections: FirewallVpnConnection[] = [];
const firewallCgwName = firewallConfig['fw-cgw-name'];
const firewallCgwAsn = firewallConfig['fw-cgw-asn'];
const firewallCgwRouting = firewallConfig['fw-cgw-routing'].toLowerCase();
const addTagsDependencies = [];
const addTagsToResources: AddTagsToResource[] = [];
const tgwAttachments: TgwVpnAttachment[] = [];
if (c.FirewallEC2ConfigType.is(firewallConfig)) {
for (const [index, port] of Object.entries(firewallPorts || [])) {
if (port.firewallName !== firewallConfig.name) {
continue;
}
let customerGateway;
let vpnConnection;
let vpnTunnelOptions;
if (port.eipIpAddress && port.createCustomerGateway) {
const prefix = `${firewallCgwName}_${port.subnetName}_az${pascalCase(port.az)}`;
customerGateway = new ec2.CfnCustomerGateway(scope, `${prefix}_cgw`, {
type: 'ipsec.1',
ipAddress: port.eipIpAddress,
bgpAsn: firewallCgwRouting === 'dynamic' ? firewallCgwAsn : 65000,
});
vpnConnection = new ec2.CfnVPNConnection(scope, `${prefix}_vpn`, {
type: 'ipsec.1',
transitGatewayId: transitGateway.tgwId,
customerGatewayId: customerGateway.ref,
staticRoutesOnly: firewallCgwRouting === 'static' ? true : undefined,
});
// Creating VPN connection route table association and propagation
const attachments = new VpnAttachments(scope, `VpnAttachments${index}`, {
vpnConnectionId: vpnConnection.ref,
tgwId: transitGateway.tgwId,
});
// Make sure to add the tags to the VPN attachments
addTagsDependencies.push(attachments);
addTagsToResources.push({
targetAccountIds: [cdk.Aws.ACCOUNT_ID],
resourceId: attachments.getTransitGatewayAttachmentId(0),
resourceType: 'tgw-attachment',
tags: [
{
key: 'Name',
value: `${prefix}_att`,
},
],
region: cdk.Aws.REGION,
});
const associateConfig = attachConfig['tgw-rt-associate'] || [];
const propagateConfig = attachConfig['tgw-rt-propagate'] || [];
const tgwRouteAssociates = associateConfig.map(route => transitGateway.tgwRouteTableNameToIdMap[route]);
const tgwRoutePropagates = propagateConfig.map(route => transitGateway.tgwRouteTableNameToIdMap[route]);
for (const [routeIndex, route] of tgwRouteAssociates?.entries()) {
new ec2.CfnTransitGatewayRouteTableAssociation(scope, `tgw_associate_${prefix}_${routeIndex}`, {
transitGatewayAttachmentId: attachments.getTransitGatewayAttachmentId(0), // one vpn connection should only have one attachment
transitGatewayRouteTableId: route,
});
}
for (const [routeIndex, route] of tgwRoutePropagates?.entries()) {
new ec2.CfnTransitGatewayRouteTablePropagation(scope, `tgw_propagate_${prefix}_${routeIndex}`, {
transitGatewayAttachmentId: attachments.getTransitGatewayAttachmentId(0), // one vpn connection should only have one attachment
transitGatewayRouteTableId: route,
});
}
const options = new VpnTunnelOptions(scope, `VpnTunnelOptions${index}`, {
vpnConnectionId: vpnConnection.ref,
});
vpnTunnelOptions = {
cgwTunnelInsideAddress1: options.getAttString('CgwInsideIpAddress1'),
cgwTunnelOutsideAddress1: options.getAttString('CgwOutsideIpAddress1'),
cgwBgpAsn1: firewallCgwRouting === 'dynamic' ? options.getAttString('CgwBgpAsn1') : undefined,
vpnTunnelInsideAddress1: options.getAttString('VpnInsideIpAddress1'),
vpnTunnelOutsideAddress1: options.getAttString('VpnOutsideIpAddress1'),
vpnBgpAsn1: firewallCgwRouting === 'dynamic' ? options.getAttString('VpnBgpAsn1') : undefined,
preSharedSecret1: options.getAttString('PreSharedKey1'),
cgwTunnelInsideAddress2: options.getAttString('CgwInsideIpAddress2'),
cgwTunnelOutsideAddress2: options.getAttString('CgwOutsideIpAddress2'),
cgwBgpAsn2: firewallCgwRouting === 'dynamic' ? options.getAttString('CgwBgpAsn2') : undefined,
vpnTunnelInsideAddress2: options.getAttString('VpnInsideIpAddress2'),
vpnTunnelOutsideAddress2: options.getAttString('VpnOutsideIpAddress2'),
vpnBgpAsn2: firewallCgwRouting === 'dynamic' ? options.getAttString('VpnBgpAsn2') : undefined,
preSharedSecret2: options.getAttString('PreSharedKey2'),
};
tgwAttachments.push({
subnet: port.subnetName,
az: port.az,
id: attachments.getTransitGatewayAttachmentId(0),
});
}
vpnConnections.push({
...port,
firewallAccountKey,
transitGatewayId: transitGateway.tgwId,
customerGatewayId: customerGateway?.ref,
vpnConnectionId: vpnConnection?.ref,
vpnTunnelOptions,
});
}
} else {
for (const [index, fwIp] of Object.entries(firewallConfig['fw-ips'] || [])) {
const prefix = `${firewallCgwName}_ip${index}`;
const customerGateway = new ec2.CfnCustomerGateway(scope, `${prefix}_cgw`, {
type: 'ipsec.1',
ipAddress: fwIp,
bgpAsn: firewallCgwRouting === 'dynamic' ? firewallCgwAsn : 65000,
});
const vpnConnection = new ec2.CfnVPNConnection(scope, `${prefix}_vpn`, {
type: 'ipsec.1',
transitGatewayId: transitGateway.tgwId,
customerGatewayId: customerGateway.ref,
staticRoutesOnly: firewallCgwRouting === 'static' ? true : undefined,
});
// Creating VPN connection route table association and propagation
const attachments = new VpnAttachments(scope, `VpnAttachments-${prefix}_attach`, {
vpnConnectionId: vpnConnection.ref,
tgwId: transitGateway.tgwId,
});
// Make sure to add the tags to the VPN attachments
addTagsDependencies.push(attachments);
addTagsToResources.push({
targetAccountIds: [cdk.Aws.ACCOUNT_ID],
resourceId: attachments.getTransitGatewayAttachmentId(0),
resourceType: 'tgw-attachment',
tags: [
{
key: 'Name',
value: `${prefix}_att`,
},
],
region: cdk.Aws.REGION,
});
const associateConfig = attachConfig['tgw-rt-associate'] || [];
const propagateConfig = attachConfig['tgw-rt-propagate'] || [];
const tgwRouteAssociates = associateConfig.map(route => transitGateway.tgwRouteTableNameToIdMap[route]);
const tgwRoutePropagates = propagateConfig.map(route => transitGateway.tgwRouteTableNameToIdMap[route]);
for (const [routeIndex, route] of tgwRouteAssociates?.entries()) {
new ec2.CfnTransitGatewayRouteTableAssociation(scope, `tgw_associate_${prefix}_${routeIndex}`, {
transitGatewayAttachmentId: attachments.getTransitGatewayAttachmentId(0), // one vpn connection should only have one attachment
transitGatewayRouteTableId: route,
});
}
for (const [routeIndex, route] of tgwRoutePropagates?.entries()) {
new ec2.CfnTransitGatewayRouteTablePropagation(scope, `tgw_propagate_${prefix}_${routeIndex}`, {
transitGatewayAttachmentId: attachments.getTransitGatewayAttachmentId(0), // one vpn connection should only have one attachment
transitGatewayRouteTableId: route,
});
}
}
}
// Output the tags that need to be added to the VPN attachments
if (addTagsToResources.length > 0) {
new AddTagsToResourcesOutput(scope, `VpnAttachmentsTags${firewallConfig.name}`, {
dependencies: addTagsDependencies,
produceResources: () => addTagsToResources,
});
}
// Store the firewall VPN connections as outputs
new CfnFirewallVpnConnectionOutput(scope, `FirewallVpnConnections${firewallConfig.name}`, vpnConnections);
new CfnTgwVpnAttachmentsOutput(scope, `TgwVpnAttachments${firewallConfig.name}`, {
name: firewallCgwName,
attachments: tgwAttachments,
});
}