RDS with Cloud Formation and AZ issues

Gleeb picture Gleeb · Nov 15, 2015 · Viewed 8.7k times · Source

I am using cloud formation to create a setup containing an RDS instance.

I am having some difficulties creating the RDS Instance on the account of the following error:

DB Subnet Group doesn't meet availability zone coverage requirement. Please add subnets to cover at least 2 availability zones. Current coverage: 1

The problem is that the entire setup is on a single AZ... what am i supposed to do? just create an extra subnet in a different AZ that has nothing in it just for the RDS?

Maybe there is some way AWS can create that subnet automatically and leave me out of that mess. I don't want that extra subnet and I don't want to burden my users with selecting another AZ just for this.

Answer

wjordan picture wjordan · Dec 22, 2016

Yes, even for a deployment entirely contained within a single Availability Zone [AZ], you must create an extra subnet in a different AZ and include it in your DB Subnet Group. The rationale for this requirement is to support high-availability Multi-AZ deployments, as noted in the Working with a DB Instance in a VPC section of the RDS User Guide:

For Multi-AZ deployments, defining a subnet for two or more Availability Zones in a region allows Amazon RDS to create a new standby in another Availability Zone should the need arise. You need to do this even for Single-AZ deployments, just in case you want to convert them to Multi-AZ deployments at some point.

As for not burdening your users with selecting another AZ just for this, there are ways to accomplish this. For example, you could select a secondary AZ automatically using the Fn::GetAZs and Fn::Select intrinsic functions. If you allow the user to select the primary AZ, you'll also need a Condition to ensure the secondary AZ doesn't equal the primary AZ selected.

Here's an example template snippet:

Parameters:
  PrimaryAZ:
    Type: AWS::EC2::AvailabilityZone::Name
    Description: Primary AZ
Conditions:
  IsFirstPrimaryAZ:
    Fn::Equals:
    - !Ref PrimaryAZ
    - Fn::Select [0, {Fn::GetAZs: ""}]
Resources:
  Subnet1:
    Type: "AWS::EC2::Subnet"
    Properties:
      AvailabilityZone: !Ref PrimaryAZ
      # ...
  Subnet2:
    Type: "AWS::EC2::Subnet"
    Properties:
      AvailabilityZone:
        Fn::If:
        - IsFirstPrimaryAZ
        - Fn::Select [1, {Fn::GetAZs: ""}]
        - Fn::Select [0, {Fn::GetAZs: ""}]
      # ...