如何使用 CDK 将子网及其路由表映射到同一可用区中的防火墙端点?

问题描述 投票:0回答:1

我正在尝试使用 CDK 更新我的子网路由表以指向同一可用区中的防火墙端点。

我使用

CfnFirewall
创建了防火墙,我可以使用
attrEndpointIds
属性获取所有防火墙端点。
attrEndpointIds
返回列表编码的令牌并包含所有可用区的端点。

https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-networkfirewall.CfnFirewall.html#attrendpointids

The unique IDs of the firewall endpoints for all of the subnets that you attached to the firewall.

The subnets are not listed in any particular order. For example: ["us-west-2c:vpce-111122223333", "us-west-2a:vpce-987654321098", "us-west-2b:vpce-012345678901"] .

我目前有以下代码

        // for each firewall subnet, update its route table to firewall endpoint in the same AZ
        for (let i = 0; i < this.vpc.availabilityZones.length; i++) {
            const azWithFirewallVpcEndpointId = cdk.Fn.split(':', cdk.Fn.select(i, firewall.attrEndpointIds), 2);
            const az = azWithFirewallVpcEndpointId[0];
            const firewallVpcEndpointId = azWithFirewallVpcEndpointId[1];

            const firewallSubnetInAz = this.vpc.selectSubnets({
                subnetGroupName: FIREWALL_SUBNET_GROUP_NAME,
                availabilityZones: [az],
                onePerAz: true, // there should be 1 and only 1 subnet with the group name in each AZ
            }).subnets[0];
            (firewallSubnetInAz as ec2.Subnet).addRoute('firewall-route-' + i, {
                routerId: firewallVpcEndpointId,
                routerType: ec2.RouterType.VPC_ENDPOINT,
            });
            
            // const firewallSubnets = this.vpc.selectSubnets({
            //     subnetGroupName: FIREWALL_SUBNET_GROUP_NAME,
            // }).subnets;
            // for (let k = 0; k < firewallSubnets.length; k++) {
            //     if (cdk.Token.compareStrings(az, firewallSubnets[i].availabilityZone)) {
            //         (firewallSubnets[i] as ec2.Subnet).addRoute('firewall-route-' + i, {
            //             routerId: firewallVpcEndpointId,
            //             routerType: ec2.RouterType.VPC_ENDPOINT,
            //         });
            //     }
            // }
        }

我正在努力更新每个子网的路由表及其位于同一可用区中的相应防火墙端点。

firewallSubnetInAz
来自
vpc.selectSubnets()
undefined
。我收到以下错误。
Cannot read property 'addRoute' of undefined

如何使用 CDK 将子网映射到同一可用区中的防火墙端点?

aws-cloudformation aws-cdk amazon-vpc
1个回答
0
投票

很晚才回答我的问题,但我用一些巫术魔法解决了这个问题。感谢这篇博客文章帮助我按顺序对 AZ 进行排序。

/** this is actually some voodoo magic here...
 * we select firewall subnet from vpc, assuming (hoping...) vpc.availabilityZones are in order of AZs
 * this means we require `firewall.attrEndpointIds` to be in order.
 * however, `firewall.attrEndpointIds` is not in order for some inexplicable reasons.
 * https://github.com/aws-cloudformation/aws-cloudformation-resource-providers-networkfirewall/issues/15
 * `firewall.attrEndpointIds` is a List-encoded tokens - https://docs.aws.amazon.com/cdk/v2/guide/tokens.html#tokens_list
 * in order to sort `firewall.attrEndpointIds` in order of AZs, we need to use a combination of splits and joins.
 * AWS AZs are ordered lexicographically starting at `a`, and "assuming" vpc.availabilityZones are returned in order of AZs
 * to sort `firewall.attrEndpointIds` as a List-encoded tokens, the following steps are taken:
 * 1. join `firewall.attrEndpointIds` as a string token with `,` as delimiter.
 *   -> "us-west-2c:vpce-111122223333,us-west-2a:vpce-987654321098,us-west-2b:vpce-012345678901"
 * 2. split the resulting string token `azWithFirewallVpcEndpointIds` with `a:` for the first AZ (`b:` and `c:` subsequently).
 *   -> [ "us-west-2c:vpce-111122223333,us-west-2", "vpce-987654321098,us-west-2b:vpce-012345678901" ]
 * 3. select 2nd element as it contains the endpoint ID, along with some extra garbage and store it into var `temp`
 *   -> "vpce-987654321098,us-west-2b:vpce-012345678901"
 * 4. split `temp` by `,` as that was the joined list delimiter
 *   -> [ "vpce-987654321098", "us-west-2b:vpce-012345678901" ]
 * 5. select 1st element as it contains the endpoint ID without any extra garbage now
 *   -> "vpce-987654321098"
 * https://carriagereturn.nl/aws/cloudformation/firewall/endpoint/routing/2022/05/22/firewall-endpoints.html
 */
getFirewallEndpointsInOrder(firewall: fw.CfnFirewall): string[] {
    const firewallVpcEndpointIds: string[] = [];
    const azWithFirewallVpcEndpointIds = cdk.Fn.join(',', firewall.attrEndpointIds);
    const aZs = ['a', 'b', 'c', 'd', 'e', 'f']; // max amount of AZs in AWS (us-east-1)
    for (let i = 0; i < this.vpc.availabilityZones.length; i++) {
        const temp = cdk.Fn.split(`${aZs[i]}:`, azWithFirewallVpcEndpointIds, 2)[1];
        const firewallVpcEndpointId = cdk.Fn.split(',', temp, 2)[0];
        firewallVpcEndpointIds.push(firewallVpcEndpointId);
    }
    return firewallVpcEndpointIds;
}

一旦firewallVpcEndpointIds按可用区排序,我们就可以使用以下代码将子网与其对应的VPC终端节点映射到同一可用区中。

updateFirewallSubnetRouteTableWithFirewallVpcEndpoint(sortedVpcEndpointIds) {
  for (let i = 0; i < this.vpc.availabilityZones.length; i++) {
      const firewallSubnetInAz = this.vpc.selectSubnets({
          subnetGroupName: FIREWALL_SUBNET_GROUP_NAME,
          availabilityZones: [this.vpc.availabilityZones[i]], // assuming availabilityZones are in order?
          onePerAz: true, // there should be 1 and only 1 subnet with the group name in each AZ
      }).subnets[0];

      (firewallSubnetInAz as ec2.Subnet).addRoute('firewall-route-' + i, {
          routerId: sortedVpcEndpointIds[i],
          routerType: ec2.RouterType.VPC_ENDPOINT,
      });
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.