Generating subnet CIDR blocks programmatically in CloudFormation templates (or adding integers together)

amazon-vpc, amazon-web-services, aws-cloudformation, cidr

Solution

My solution for these kinds of issues was to use a legitimate programming language to compile a template into a CloudFormation JSON document. I used PHP 5.4, Twig and Symfony Console, but YMMV.

Essentially, you do the math ahead of time in the programming language, then use that data as you write-out your JSON document.

Problem

We are adapting our applications CloudFormation template to make use of VPC. Within this template we need to programmatically generate the CIDR blocks used for our VPC subnets, in order to ensure they do not conflict between CloudFormation stacks. My initial plan had been to generate the CIDRs by concatenating strings together, for example: ``` "ProxyLoadBalancerSubnetA" : { "Type" : "AWS::EC2::Subnet", "Properties" : { "VpcId" : { "Ref" : "Vpc" }, "AvailabilityZone" : "eu-west-1a", "CidrBlock" : { "Fn::Join" : [ ".", [ { "Ref" : "VpcCidrPrefix" }, "0.0/24" ] ] } } }, ``` Upon further consideration however, we need to use a single VPC rather than having a VPC for each of our stacks. AWS restrict VPCs to using a maximum of a `/16` CIDR block (we have asked for this limit to be raised, but it is apparently not possible). This means it is no longer possible for us to use this concatenation method as each of our stacks require subnets that span more than 255 addresses in total. I'd like to generate the CIDR blocks on-the-fly rather than having to define them as parameters to the CloudFormation template, One idea I had was each stack having a "base integer" and adding to that for each subnet's CIDR block. For example: ``` "CidrBlock" : { "Fn::Join" : [ ".", [ { "Ref" : "VpcCidrPrefix" }, { "Fn::Sum", [ { "Ref" : "VpcCidrStart" }, 3 ] }, "0/24 ] ] } ``` Where `VpcCidrStart` is an integer that sets the value that the third CIDR octet should start from within the script, and `3` is the subnet number. Obviously the `Fn::Sum` intrinsic function doesn't exist though, so I wanted to know if anyone had a solution to adding integers in VPC (it seems like something that shouldn't be possible, as CloudFormation is string oriented), or a better solution to this conundrum in general.

Original source