26
votes

I have a cloudformation script that attempts to create a VPC, with one subnet per AZ.

When I run:

aws ec2 describe-availablity-zones

I get 4 zones returned:

"AvailabilityZones": [
    {
        "State": "available", 
        "RegionName": "us-east-1", 
        "Messages": [], 
        "ZoneName": "us-east-1a"
    }, 
    {
        "State": "available", 
        "RegionName": "us-east-1", 
        "Messages": [], 
        "ZoneName": "us-east-1b"
    }, 
    {
        "State": "available", 
        "RegionName": "us-east-1", 
        "Messages": [], 
        "ZoneName": "us-east-1c"
    }, 
    {
        "State": "available", 
        "RegionName": "us-east-1", 
        "Messages": [], 
        "ZoneName": "us-east-1d"
    }
 ]

However, when I try to create my stack, I get an error:

  "ResourceStatusReason": "Value (us-east-1a) for parameter availabilityZone
   is invalid. Subnets can currently only be created in the following 
   availability zones: us-east-1c, us-east-1b, us-east-1d.", 

I am specifying the AZ with

      "AvailabilityZone" : {
        "Fn::Select" : [ "0", { "Fn::GetAZs" : "" } ]
      },

Is there a way to check to see if the AZ is really available for the creation of a subnet?

4

4 Answers

9
votes

This may not be helpful for the CLI Approach or your exact scenario - but with AWS Management Console this works smooth.

With the recent updates with the CloudFormation Parameters, you would be able pin-point the AZs pertaining to the specified AZs.

This would be much convenient during the DR / DR Drills and making the CFN template Region Independent.

enter image description here

"Parameters": {
    "SubnetAZ": {
      "Description": "Availability Zone of the Subnet",
      "Type": "AWS::EC2::AvailabilityZone::Name"
    }
}

More Information About the CloudFormation Parameters

6
votes

Unfortunately I had the same problem. There is no method in CloudFormation to do this and the zones can be different per AWS account. This is a limitation of VPC infrastructure and it is likely not going to change. Your only option will be to hardcode the zones that you have found in your CloudFOrmation template instead of Fn::Select, for example:

"AvailabilityZone" : "us-east-1b"

Alternatively if you leave AvailabilityZone blank, the default behavior would be AWS will automatically pick one for you.

5
votes

Fn::GetAZs will provide the available and usable availability zones as long as you have a default vpc with a subnet in each AZ! which by the way all new aws accounts have as long as you don't delete them manually.

-3
votes

I get around the limitation by avoiding json as the medium of expression. I use troposphere to compose my cloudformation templates.(https://github.com/cloudtools/troposphere)

You would however would have to deploy some sort of tooling around the deployment of cloudformation templates to individual regions.