Cloudformation-coverage-roadmap: How to read list of key:values returned by !GetAtt in cloudformation for AWS Network Firewall

Created on 25 Feb 2021  路  1Comment  路  Source: aws-cloudformation/cloudformation-coverage-roadmap

I am trying to access 3 network firewall endpoints that gets created in 3 subnets in different AZs to be added to route tables:

Logical name of network firewall is "NetworkFirewall"

!GetAtt NetworkFirewall.EndpointIds.${AWS::Region}a
!GetAtt NetworkFirewall.EndpointIds.${AWS::Region}b
!GetAtt NetworkFirewall.EndpointIds.${AWS::Region}c

As specified in AWS docs:

Fn::GetAtt
The Fn::GetAtt intrinsic function returns a value for a specified attribute of this type. The following are the available attributes and sample return values.

For more information about using the Fn::GetAtt intrinsic function, see Fn::GetAtt.

EndpointIds
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"].

But this way:
!GetAtt NetworkFirewall.EndpointIds.${AWS::Region}a
of accessing endpoints, seems to be not working.

So I tried
!GetAtt NetworkFirewall.EndpointIds, which would return list of 3 key:value pairs, from which I need to extract networkfirewall endpoints for each AZ's and use them in related route table, using Cloudformation

Any tips will be helpfull

bug? enhancement

Most helpful comment

There isn't a clean solution in CloudFormation (the return values of the resource are annoying to work with), but this works:

"Fn::Select": # "vpce-987654321098"
  - 0
  - "Fn::Split": # ["vpce-987654321098", "..."]
    - '/'
    - "Fn::Select": # 'vpce-987654321098/...
      - 1
      - "Fn::Split":  # ['...', 'vpce-987654321098/...']
        - "a:"
        - "Fn::Sub": # "/.../us-west-2b:vpce-012345678901/"
          - "/${x}/"
          # "us-west-2c:vpce-111122223333/us-west-2a:vpce-987654321098/us-west-2b:vpce-012345678901"
          - x: !Join  ['/', !GetAtt Firewall.EndpointIds]

And here is a full template that I tested

Parameters:
  VpcId:
    Type: AWS::EC2::VPC::Id
  SubnetIdA:
    Type: AWS::EC2::Subnet::Id
  SubnetIdB:
    Type: AWS::EC2::Subnet::Id
  SubnetIdC:
    Type: AWS::EC2::Subnet::Id

Resources:
  Firewall:
    Type: AWS::NetworkFirewall::Firewall
    Properties:
      FirewallName: !Ref AWS::StackName
      FirewallPolicyArn: !Ref FirewallPolicy
      VpcId: !Ref VpcId
      SubnetMappings:
        - SubnetId: !Ref SubnetIdA
        - SubnetId: !Ref SubnetIdB
        - SubnetId: !Ref SubnetIdC
  FirewallPolicy:
    Type: 'AWS::NetworkFirewall::FirewallPolicy'
    Properties:
      FirewallPolicyName: !Ref AWS::StackName
      FirewallPolicy:
        StatelessDefaultActions:
          - 'aws:pass'
        StatelessFragmentDefaultActions:
          - 'aws:drop'

Outputs:
  AllEndpoints:
    Value: !Join ['/', !GetAtt Firewall.EndpointIds]
  SubnetAEndpoint:
    Value:
      "Fn::Select": # "vpce-987654321098"
        - 0
        - "Fn::Split": # ["vpce-987654321098", "..."]
          - '/'
          - "Fn::Select": # 'vpce-987654321098/...
            - 1
            - "Fn::Split":  # ['...', 'vpce-987654321098/...']
              - "a:"
              - "Fn::Sub": # "/.../us-west-2b:vpce-012345678901/"
                - "/${x}/"
                # "us-west-2c:vpce-111122223333/us-west-2a:vpce-987654321098/us-west-2b:vpce-012345678901"
                - x: !Join  ['/', !GetAtt Firewall.EndpointIds]
  SubnetBEndpoint:
    Value:
      "Fn::Select":
        - 0
        - "Fn::Split":
          - '/'
          - "Fn::Select":
            - 1
            - "Fn::Split":
              - "b:"
              - "Fn::Sub":
                - "/${x}/"
                - x: !Join  ['/', !GetAtt Firewall.EndpointIds]
  SubnetCEndpoint:
    Value:
      "Fn::Select":
        - 0
        - "Fn::Split":
          - '/'
          - "Fn::Select":
            - 1
            - "Fn::Split":
              - "c:"
              - "Fn::Sub":
                - "/${x}/"
                - x: !Join  ['/', !GetAtt Firewall.EndpointIds]

>All comments

There isn't a clean solution in CloudFormation (the return values of the resource are annoying to work with), but this works:

"Fn::Select": # "vpce-987654321098"
  - 0
  - "Fn::Split": # ["vpce-987654321098", "..."]
    - '/'
    - "Fn::Select": # 'vpce-987654321098/...
      - 1
      - "Fn::Split":  # ['...', 'vpce-987654321098/...']
        - "a:"
        - "Fn::Sub": # "/.../us-west-2b:vpce-012345678901/"
          - "/${x}/"
          # "us-west-2c:vpce-111122223333/us-west-2a:vpce-987654321098/us-west-2b:vpce-012345678901"
          - x: !Join  ['/', !GetAtt Firewall.EndpointIds]

And here is a full template that I tested

Parameters:
  VpcId:
    Type: AWS::EC2::VPC::Id
  SubnetIdA:
    Type: AWS::EC2::Subnet::Id
  SubnetIdB:
    Type: AWS::EC2::Subnet::Id
  SubnetIdC:
    Type: AWS::EC2::Subnet::Id

Resources:
  Firewall:
    Type: AWS::NetworkFirewall::Firewall
    Properties:
      FirewallName: !Ref AWS::StackName
      FirewallPolicyArn: !Ref FirewallPolicy
      VpcId: !Ref VpcId
      SubnetMappings:
        - SubnetId: !Ref SubnetIdA
        - SubnetId: !Ref SubnetIdB
        - SubnetId: !Ref SubnetIdC
  FirewallPolicy:
    Type: 'AWS::NetworkFirewall::FirewallPolicy'
    Properties:
      FirewallPolicyName: !Ref AWS::StackName
      FirewallPolicy:
        StatelessDefaultActions:
          - 'aws:pass'
        StatelessFragmentDefaultActions:
          - 'aws:drop'

Outputs:
  AllEndpoints:
    Value: !Join ['/', !GetAtt Firewall.EndpointIds]
  SubnetAEndpoint:
    Value:
      "Fn::Select": # "vpce-987654321098"
        - 0
        - "Fn::Split": # ["vpce-987654321098", "..."]
          - '/'
          - "Fn::Select": # 'vpce-987654321098/...
            - 1
            - "Fn::Split":  # ['...', 'vpce-987654321098/...']
              - "a:"
              - "Fn::Sub": # "/.../us-west-2b:vpce-012345678901/"
                - "/${x}/"
                # "us-west-2c:vpce-111122223333/us-west-2a:vpce-987654321098/us-west-2b:vpce-012345678901"
                - x: !Join  ['/', !GetAtt Firewall.EndpointIds]
  SubnetBEndpoint:
    Value:
      "Fn::Select":
        - 0
        - "Fn::Split":
          - '/'
          - "Fn::Select":
            - 1
            - "Fn::Split":
              - "b:"
              - "Fn::Sub":
                - "/${x}/"
                - x: !Join  ['/', !GetAtt Firewall.EndpointIds]
  SubnetCEndpoint:
    Value:
      "Fn::Select":
        - 0
        - "Fn::Split":
          - '/'
          - "Fn::Select":
            - 1
            - "Fn::Split":
              - "c:"
              - "Fn::Sub":
                - "/${x}/"
                - x: !Join  ['/', !GetAtt Firewall.EndpointIds]
Was this page helpful?
0 / 5 - 0 ratings

Related issues

luiseduardocolon picture luiseduardocolon  路  4Comments

hoegertn picture hoegertn  路  4Comments

grauj-aws picture grauj-aws  路  3Comments

rjpereira picture rjpereira  路  4Comments

msaggar picture msaggar  路  3Comments