CloudFormation VPC GetAtt Parameter Internal Failure

amazon-cloudformationamazon-vpcnetworking

I have two Cloudformation files being used to make two different stacks containing a VPC each. One is an admin VPC that will be used to access the other VPC via ssh and all that, typical bastiony use case.

I spin up the admin VPC and then pass its ID into the second CF file as a parameter specifically with the VPC Id type:

"AdminVPC": {
  "Description": "ID of the admin VPC",
  "Type": "AWS::EC2::VPC::Id"
}

But then when I am trying to set up the network ACL of the VPC, I am doing

"Type": "AWS::EC2::NetworkAclEntry",
  "Properties": {
    "CidrBlock": {
      "Fn::GetAtt": [
        {
          "Ref": "AdminVPC"
        },
        "CidrBlock"
      ]
    },

Which, when I run a ecs cf validate, yields only the message

An error occurred (ValidationError) when calling the ValidateTemplate operation: Internal Failure

It works fine if I just hardcode in a CIDR block like

"CidrBlock": "0.0.0.0/0",

But the docs claim that:

  1. Using a GetAtt to get the CIDR block off the vpc ID should work
  2. For the Fn::GetAtt attribute name, you can use the Ref function.

So I'm not sure what is wrong with this usage…

Best Answer

the first argument to Fn::GetAtt must be the name of logical resource defined in your template, so the string must be one of the Resources created within the template.

When using AWS Parameter types all that gets passed to the template is the id of that resource, therefore the only value contained in {"Ref": "AdminVPC"} would be some like vpc-abc123 . You don't pass the VPC to the template, just its id.

The solution to your problem would be to accept the CIDR as a parameter into the template, the template creating the VPC should have an Output that Uses {"Fn::GetAtt": ["AdminVPC", "CidrBlock"]}