Is there a way for cloudformation to query available zones for subnet creation?
Asked Answered
I

4

26

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?

Industrial answered 27/1, 2014 at 19:58 Comment(0)
N
9

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

Nicosia answered 3/6, 2015 at 8:40 Comment(2)
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.Headward
@Naveen I think in your snippet you meant : List<AWS::EC2::AvailabilityZone::Name> instead of AWS::EC2::AvailabilityZone::NameConch
C
6

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.

Cognition answered 29/1, 2014 at 20:32 Comment(10)
Can't leave them blank because we are creating a VPC with subnets in each AZ - the problem is not every AZ that is returned allows subnets!Industrial
So if one zone does not allow VPC subnets, what is the point of using it it you are hosting in VPC? Simply ignore that zone and deal with the 3 zones that support it.Cognition
That is a manual process - If I create subnets based on Fn::Select with index 0, 1 and 2 it will sometimes fail because there are actually 4 AZs, but not every one of them allows subnetsIndustrial
You can supply it with the list of AZs instead of using Fn::GetAZs. If you want to make 3 different subnets, then define 3 distinct stack resources each referencing specific zone.Cognition
I actually tried that, but moving between accounts can cause it to fail - for example, we have a test account that has shown 1b, 1c and 1d, and when I run it in prod we have 1a, 1b and 1d. It's frustrating.Industrial
agreed. I have the same problem. I maintain 3 copies, 1 for each account, for these kinds of things. I made the recommendation to CloudFormation team during a call, hopefully at some point they will implement it, but until then, I don't see another option for doing this with cfn.Cognition
The "solution" I have implemented is to use a Mapping for each of the accounts, with the truly available AZs as one of the values in the mapping.Stopping
I have done something pretty similar to the above comment also. You could always do some logic prior to stack launch and inject params into the template. That seems a little bit bulky though.Marquand
You can also pick a previously automatically selected AZs with { "Fn::GetAtt" : [ "subnetPublicSubnetDefinition", "AvailabilityZone" ] } ( official documentation)Conjoined
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.Headward
H
5

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.

Headward answered 17/11, 2016 at 15:7 Comment(5)
I have seen Fn::GetAZs return unusable zones.Amphioxus
then you don't have default subnetsHeadward
This is a really interesting "feature". Has this been documented anywhere on AWS Docs?Mcbroom
If you're missing a default subnet for an AZ (either because AWS added an AZ or because you deleted an existing default subnet) you can add it back with aws ec2 create-default-subnet --availability-zone <zone_name>. DocsCabalist
You literally saved me from losing my mind, thank you!Vow
C
-3

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.

Cattle answered 29/12, 2016 at 21:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.