Cloudformation Templates for RDS

I've mainly been creating RDS instances using the AWS console GUI, or restoring from snapshots. But lately I have been using Amazon's cloudformation templates to build out RDS (MySQL) instances as a faster way to build out complete environments. These CFN templates are written in JSON (JavaScript Object Notation) - not a language I'm familiar with, but not hard to pick-up.

To create your RDS instances using Cloudformation templates, use the example below by and your own details. The code is best edited/validated using Visual Studio. There isn't a way to comment the JSON file apart from add a description, but this template will:

  • Create a New Security Group and assign it to the DB to allow port 3306
  • Create a New RDS Subnet Group to be part of the VPC specified

{
  "AWSTemplateFormatVersion" : "2010-09-09",

  "Description" : "AWS CloudFormation RDS Template for MySQL",

  "Parameters": {
    "EndPointName" : {
     "Description" : "The RDS Endpoint Name",
      "Type"       : "String",
      "MinLength"  : "1",
      "MaxLength"  : "16"
    },
    "VpcId" : {
       "Type"        : "AWS::EC2::VPC::Id",
       "Default"     : "vpc-555555555",
       "Description" : "Existing VPC's available in RDS"
     },	
    "EC2SubnetAZa"    : {
       "Description"  : "Select the subnet for Availability Zone A",
       "Type"         : "AWS::EC2::Subnet::Id",
       "Default"      : "subnet-555555555a"
    },
    "EC2SubnetAZb"    : {
     "Description"    : "Select the subnet for Availability Zone B",
     "Type"           : "AWS::EC2::Subnet::Id",
     "Default"        : "subnet-555555555b"
    },
    "EC2SubnetAZc"    : {
       "Description"  : "Select the subnet for Availability Zone C",
       "Type"         : "AWS::EC2::Subnet::Id",
       "Default"      : "subnet-555555555c"
    },
    "DBName": {
      "Description"      : "The database name",
      "Type"             : "String",
      "MinLength"        : "1",
      "MaxLength"        : "64",
      "AllowedPattern"   : "[a-zA-Z][a-zA-Z0-9]*",
      "ConstraintDescription" : "Must begin with a letter and contain only alphanumeric characters."
    },
    "DBUser": {
      "Description"      : "The database admin account username",
      "Type"             : "String",
      "MinLength"        : "1",
      "MaxLength"        : "16",
      "AllowedPattern"   : "[a-zA-Z][a-zA-Z0-9]*",
      "ConstraintDescription" : "Must begin with a letter and contain only alphanumeric characters."
    },
    "DBPassword": {
      "NoEcho"         : "true",
      "Description"    : "The database admin account password",
      "Type"           : "String",
      "MinLength"      : "8",
      "MaxLength"      : "41",
      "AllowedPattern" : "[a-zA-Z0-9]*",
      "ConstraintDescription" : "Must contain only alphanumeric characters."
    },
    "DBAllocatedStorage" : {
      "Description"      : "The size of the database (Gb)",
      "Type"             : "Number",
      "MinValue"         : "5",
      "MaxValue"         : "1024",
      "ConstraintDescription" : "Must be between 5 and 1024Gb."
    },
    "DBPort"        : {
      "Description"  : "DB listening port",
      "Type"         : "Number",
      "MinValue"     : "1150",
      "MaxValue"     : "65535",
      "Default"      : "3306",
      "ConstraintDescription" : "Must be between 3300 and 3400"
    },
   "DBBackupRetention"   : {
      "Description"       : "The No. of Days to keep backup",
      "Type"              : "Number",
      "MinValue"          : "0",
      "MaxValue"          : "7",
      "Default"           : "1",
      "ConstraintDescription" : "Must be between 0 and 7"
    },
    "DBInstanceClass" : {
      "Description"   : "The database instance type",
      "Type"          : "String",
      "AllowedValues" : [ "db.t1.micro", "db.t2.micro", "db.t2.small", "db.t2.medium", 
                          "db.m1.small", "db.m1.medium", "db.m1.large", "db.m1.xlarge", 
                          "db.m2.xlarge", "db.m2.2xlarge", "db.m2.4xlarge", 
                          "db.m3.medium", "db.m3.large", "db.m3.xlarge", "db.m3.2xlarge", 
                          "db.r3.large", "db.r3.xlarge", "db.r3.2xlarge", "db.r3.4xlarge", "db.r3.8xlarge", 
                          "db.m2.xlarge", "db.m2.2xlarge", "db.m2.4xlarge", 
                          "db.cr1.8xlarge"],
      "ConstraintDescription" : "Must select a valid database instance type."
    },
    "PubliclyAccessible" : {
      "Description"      : "Create a Publically Accessible RDS database instance",
      "Type"             : "String",
      "AllowedValues"    : [ "true", "false" ],
      "ConstraintDescription" : "Must be either true or false."
    },
    "MultiAZ"         : {
      "Description"   : "Create a multi-AZ RDS database instance",
      "Type"          : "String",
      "AllowedValues" : [ "true", "false" ],
      "ConstraintDescription" : "Must be either true or false."
    },
    "MinorUpgrade"    : {
      "Default"       : "true",
      "Description"   : "Minor upgrade engines applied",
      "Type"          : "String",
      "AllowedValues" : [ "true", "false" ],
      "ConstraintDescription" : "Must be either true or false."
    },
    "TagDescription" : {
      "Description"  : "A tag description of the RDS instance.",
      "Type"         : "String"
    },
   "RDSDeletionPolicy" : {
      "Description"    : "Decides whether to delete or snapshot the DB instance on environment termination",
      "Type"           : "String",
      "Default"        : "Snapshot",
      "AllowedValues"  : [ "Delete", "Snapshot" ]
    },
    "RDSDBEngine"   : {
      "Description" : "The name of the database engine to use for this instance",
      "Type"        : "String",
      "Default"     : "mysql"
    },
    "RDSDBEngineVer" : {
      "Description"  : "The version number of the database engine",
      "Type"         : "String",
      "Default"      : "5.6.22"
    }
},


"Resources" : {
  
    "AWSDBEC2SecurityGroup" : {
            "Type"       : "AWS::EC2::SecurityGroup",
            "Properties" : {
                "GroupDescription"     : "VPC Security Group for MySQL",
                "SecurityGroupIngress" : [
                    {
                        "IpProtocol" : "tcp",
                        "FromPort"   : { "Ref" : "DBPort" },
                        "ToPort"     : { "Ref" : "DBPort" },
                        "CidrIp"     : "0.0.0.0/0"
                    }
                ],
                "VpcId"              : { "Ref" : "VpcId" }
            }
     },

    "AWSRDSDBSubnetGroup":{  
       "Type"       :"AWS::RDS::DBSubnetGroup",
       "Properties" :{  
            "DBSubnetGroupDescription":"RDS DB Subnet Group",
			  "SubnetIds" : [ { "Ref" : "EC2SubnetAZa" },  
			                  { "Ref" : "EC2SubnetAZb" }, 
                                          { "Ref" : "EC2SubnetAZc"} ]
		}
    },

    "AWSRDSDBSecurityGroup" : {
       "Type"       : "AWS::RDS::DBSecurityGroup",
       "Properties" : {
                "EC2VpcId"               : { "Ref" : "VpcId" },
                "GroupDescription"       : "RDS DB VPC Security Group",
                "DBSecurityGroupIngress" : [ {  "EC2SecurityGroupId" : { "Ref" : "AWSDBEC2SecurityGroup"  }  }  ]
            }
     },

   "MyDB" : {
       "Type"       : "AWS::RDS::DBInstance",
       "Properties" : {
        "Engine"                   : { "Ref" : "RDSDBEngine" },
        "EngineVersion"            : { "Ref" : "RDSDBEngineVer" },
        "DBInstanceClass"          : { "Ref" : "DBInstanceClass" },
        "MultiAZ"                  : { "Ref" : "MultiAZ" },
        "AllocatedStorage"         : { "Ref" : "DBAllocatedStorage" },
        "DBInstanceIdentifier"     : { "Ref" : "EndPointName" },
        "DBName"                   : { "Ref" : "DBName" },
        "Port"                     : { "Ref" : "DBPort" },
        "MasterUsername"           : { "Ref" : "DBUser" },
        "MasterUserPassword"       : { "Ref" : "DBPassword" },
        "DBSecurityGroups"         : [ { "Ref" : "AWSRDSDBSecurityGroup"  } ],
        "DBSubnetGroupName"        : { "Ref"  : "AWSRDSDBSubnetGroup" },
        "PubliclyAccessible"       : { "Ref" : "PubliclyAccessible" },
        "BackupRetentionPeriod"    : { "Ref" : "DBBackupRetention"},
        "AutoMinorVersionUpgrade"  : { "Ref" : "MinorUpgrade"},
        "Tags"                     : [ { "Key" : "Name", "Value" : { "Ref" : "TagDescription"  } } ]
      },
      "DeletionPolicy" : { "Ref" : "RDSDeletionPolicy" }
    }
   },

  "Outputs" : {
    "JDBCConnectionString": {
      "Description" : "JDBC connection string for database",
      "Value" : { "Fn::Join": [ "", [ "jdbc:mysql://",
                                      { "Fn::GetAtt": [ "MyDB", "Endpoint.Address" ] },
                                      ":",
                                      { "Fn::GetAtt": [ "MyDB", "Endpoint.Port" ] },
                                      "/",
                                      { "Ref": "DBName" }]]}
    },
    "DBAddress" : {
      "Description" : "Address of database endpoint",
      "Value" : { "Fn::GetAtt": [ "MyDB", "Endpoint.Address" ] }
    },
    "DBPort" : {
      "Description" : "Database endpoint port number",
      "Value" : { "Fn::GetAtt": [ "MyDB", "Endpoint.Port" ] }
    }
  }
}