async function createCustomerGateways()

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,
  });
}