AWS::EC2::Route CloudFormation resource does not verify the gateway type

0

I was playing with CloudFormation trying to create a private subnet that uses a NAT gateway. When declaring routes, I made a typo in the template and used GatewayId property instead of NatGatewayId when defining a AWS::EC2::Route pointing to the NAT gateway:

PrivateSubnetRoute:
  Type: AWS::EC2::Route
  Properties:
    DestinationCidrBlock: 0.0.0.0/0
    GatewayId: !Ref NatGateway 
    RouteTableId: !Ref PrivateSubnetRouteTable

When I tried to create a CloudFormation stack with this template, CloudFormation did not report any errors about an invalid gateway. Instead, the PrivateSubnetRoute resource remained in CREATE_IN_PROGRESS state for about 20 minutes, and then creation failed with the following error:

Resource handler returned message: "Exceeded attempts to wait" (RequestToken: bcf33526-b64a-9781-7e22-f4330a941fa2, HandlerErrorCode: NotStabilized)

I'd prefer CloudFormation to check the type of the specified gateway and return a meaningful error if it's not correct.

Here's the full CloudFormation stack to reproduce the error:

Resources:
  Vpc: 
    Type: AWS::EC2::VPC
    Properties: 
      CidrBlock: 10.0.0.0/24
      EnableDnsHostnames: True
      EnableDnsSupport: True
      Tags: 
        - Key: Name
          Value: NatVpc  

  PublicSubnet:
    Type: AWS::EC2::Subnet   
    Properties: 
      AvailabilityZone: !Select [0, !GetAZs "" ]
      CidrBlock: 10.0.0.0/25     
      VpcId: !Ref Vpc
      
  InternetGateway:
    Type: AWS::EC2::InternetGateway
  
  InternetGatewayAttachment:  
    Type: AWS::EC2::VPCGatewayAttachment
    Properties: 
      InternetGatewayId: !Ref InternetGateway
      VpcId: !Ref Vpc 
      
  ElasticIp:
    Type: AWS::EC2::EIP 
    DependsOn:
      - InternetGatewayAttachment
    Properties:
      Domain: vpc

  NatGateway:
    Type: AWS::EC2::NatGateway
    Properties: 
      AllocationId: !GetAtt ElasticIp.AllocationId
      SubnetId: !Ref PublicSubnet     

  PublicSubnetRouteTable:
    Type: AWS::EC2::RouteTable
    Properties: 
      VpcId: !Ref Vpc 

  PublicSubnetIpv4Route:
    Type: AWS::EC2::Route
    Properties:
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway
      RouteTableId: !Ref PublicSubnetRouteTable
      
  PublicSubnetRouteTableAssociation:    
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties: 
      RouteTableId: !Ref PublicSubnetRouteTable
      SubnetId: !Ref PublicSubnet 

  PrivateSubnet:
    Type: AWS::EC2::Subnet   
    Properties: 
      AvailabilityZone: !Select [0, !GetAZs "" ]
      CidrBlock: 10.0.0.128/25
      VpcId: !Ref Vpc  
      
  PrivateSubnetRouteTable:
    Type: AWS::EC2::RouteTable
    Properties: 
      VpcId: !Ref Vpc  
      
  PrivateSubnetRoute:
    Type: AWS::EC2::Route
    Properties:
      DestinationCidrBlock: 0.0.0.0/0
      # Here's the typo, the property should be NatGatewayId
      GatewayId: !Ref NatGateway 
      RouteTableId: !Ref PrivateSubnetRouteTable
    
  PrivateSubnetRouteTableAssociation:    
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties: 
      RouteTableId: !Ref PrivateSubnetRouteTable
      SubnetId: !Ref PrivateSubnet
2 Answers
0
Accepted Answer

Hi, you are right. Yes, an additional validation could probably be done by CFN when launching this stack to make sure that the id of the proper kind of object is provided

But, re:Post is not the right place for such bug report / feature report: it is usually not monitored by service teams like the one for CFN. So, you should open a Support case via the console of your AWS account to have this case worked on.

Best,

Didier

profile pictureAWS
EXPERT
answered 8 months ago
0

AWS::EC2::Route is used to specify a route in a route table.

With this, you can have local gateway, internet gateway, NAT gateway, virtual private gateway added to route. I understand you wanted to create PrivateSubnetRoute, so you will need to have NATFatewayId specified there but cloudformation doesn't know by your resource name that you want to create private subnet.

Enter image description here

Cloudfromation tried to add route for Internet Gateway with NATGW id, which failed after a while as GatewayId is used to specify Internetgateway.

Please refer AWS::EC2::Route.

Hope this explanation helps.

Comment here if you have additional questions, happy to help.

Abhishek

profile pictureAWS
EXPERT
answered 8 months ago
  • Do you have any further questions, happy to assist if you have any.

  • Thank you for the answer secondabhi_aws, but I was not asking how to declare a private network. I was trying to report the CloudFormation behavior that I perceive as a bug. Sorry for not specifying that more clearly.

    I'm OK with the fact that CloudFormation refused to create a route for an internet gateway with the id of a NAT gateway, it's exactly what it's supposed to do in this situation. What is not OK is that CloudFormation did not fail right away with an error like this: "The id that you've put into GatewayId field is not actually an internet gateway, try something else".

  • The error that CloudFormation reports now does not help with troubleshooting. It does not even say that the problem is with AWS::EC2::Route resource. And hanging for 20 minutes before finally failing does not speed up troubleshooting either.

  • I understand your point at first place but since GatewayId is one of the acceptable properties for AWS:EC2:Route, so when you tried to create the stack with the template, it was trying to create the IGW with Natgateway id and that would happen during runtime which is why it took time to reflect and finally errored out. All the syntactic and semantic error are spontaneous to appear but this type of situation(not specific this one, but there are so many other situations as well) takes time where things are not correct logically.

  • What I see here is an example of missing input validation. When I put the id of a totally different resource into GatewayId, e.g. "GatewayId: !Ref PublicSubnet" then CloudFormation does not wait for 20 minutes. It fails after one second with a message like this: "The gateway ID 'subnet-12345678' does not exist". It looks like CloudFormation (or whatever AWS API it calls behind the scene) only checks that the id that was put into GatewayId belongs to a gateway. It does not check the type of the gateway though.

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions