This product is not supported for your selected Datadog site. ().

Metadata

Id: 2b1d4935-9acf-48a7-8466-10d18bf51a69

Cloud Provider: AWS

Platform: CloudFormation

Severity: Medium

Category: Availability

Learn More

Description

RDS DB instances should be deployed across multiple Availability Zones to ensure high availability and reduce the risk of extended outage or data loss caused by an Availability Zone failure or planned maintenance. In AWS CloudFormation, the AWS::RDS::DBInstance resource must have the MultiAZ property set to true. Resources with MultiAZ set to false or missing the MultiAZ property (which defaults to disabled) will be flagged.

Secure configuration example:

MyDBInstance:
  Type: AWS::RDS::DBInstance
  Properties:
    DBInstanceIdentifier: my-db
    Engine: mysql
    MasterUsername: admin
    MasterUserPassword: !Ref DBPassword
    MultiAZ: true

Compliant Code Examples

AWSTemplateFormatVersion: 2010-09-09
Description: "AWS CloudFormation Sample Template RDS_MySQL_With_Read_Replica:
  Sample template showing how to create a highly-available, RDS DBInstance with
  a read replica. **WARNING** This template creates an Amazon Relational
  Database Service database instance and Amazon CloudWatch alarms. You will be
  billed for the AWS resources used if you create a stack from this template."
Parameters:
  DBName:
    Default: MyDatabase
    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:
    NoEcho: "true"
    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: "1"
    MaxLength: "41"
    AllowedPattern: "[a-zA-Z0-9]+"
    ConstraintDescription: must contain only alphanumeric characters.
  DBAllocatedStorage:
    Default: "5"
    Description: The size of the database (Gb)
    Type: Number
    MinValue: "5"
    MaxValue: "1024"
    ConstraintDescription: must be between 5 and 1024Gb.
  DBInstanceClass:
    Description: The database instance type
    Type: String
    Default: db.t2.small
    AllowedValues:
      - db.t1.micro
      - 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.m4.large
      - db.m4.xlarge
      - db.m4.2xlarge
      - db.m4.4xlarge
      - db.m4.10xlarge
      - 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
      - db.t2.micro
      - db.t2.small
      - db.t2.medium
      - db.t2.large
    ConstraintDescription: must select a valid database instance type.
  EC2SecurityGroup:
    Description: The EC2 security group that contains instances that need access to
      the database
    Default: default
    Type: String
    AllowedPattern: "[a-zA-Z0-9\\-]+"
    ConstraintDescription: must be a valid security group name.
Conditions:
  Is-EC2-VPC:
    Fn::Or:
      - Fn::Equals:
          - Ref: AWS::Region
          - eu-central-1
      - Fn::Equals:
          - Ref: AWS::Region
          - cn-north-1
  Is-EC2-Classic:
    Fn::Not:
      - Condition: Is-EC2-VPC
Resources:
  DBEC2SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Condition: Is-EC2-VPC
    Properties:
      GroupDescription: Open database for access
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 3306
          ToPort: 3306
          SourceSecurityGroupName:
            Ref: EC2SecurityGroup
  DBSecurityGroup:
    Type: AWS::RDS::DBSecurityGroup
    Condition: Is-EC2-Classic
    Properties:
      DBSecurityGroupIngress:
        - EC2SecurityGroupName:
            Ref: EC2SecurityGroup
      GroupDescription: database access
  MasterDB:
    Type: AWS::RDS::DBInstance
    Properties:
      DBName:
        Ref: DBName
      AllocatedStorage:
        Ref: DBAllocatedStorage
      DBInstanceClass:
        Ref: DBInstanceClass
      Engine: MySQL
      MasterUsername:
        Ref: DBUser
      MasterUserPassword:
        Ref: DBPassword
      MultiAZ: true
      Tags:
        - Key: Name
          Value: Master Database
      VPCSecurityGroups:
        Fn::If:
          - Is-EC2-VPC
          - - Fn::GetAtt:
                - DBEC2SecurityGroup
                - GroupId
          - Ref: AWS::NoValue
      DBSecurityGroups:
        Fn::If:
          - Is-EC2-Classic
          - - Ref: DBSecurityGroup
          - Ref: AWS::NoValue
    DeletionPolicy: Snapshot
    UpdateReplacePolicy: Snapshot
  ReplicaDB:
    Type: AWS::RDS::DBInstance
    Properties:
      SourceDBInstanceIdentifier:
        Ref: MasterDB
      DBInstanceClass:
        Ref: DBInstanceClass
      MultiAZ: true
      Tags:
        - Key: Name
          Value: Read Replica Database
Outputs:
  EC2Platform:
    Description: Platform in which this stack is deployed
    Value:
      Fn::If:
        - Is-EC2-VPC
        - EC2-VPC
        - EC2-Classic
  MasterJDBCConnectionString:
    Description: JDBC connection string for the master database
    Value:
      Fn::Join:
        - ""
        - - jdbc:mysql://
          - Fn::GetAtt:
              - MasterDB
              - Endpoint.Address
          - ":"
          - Fn::GetAtt:
              - MasterDB
              - Endpoint.Port
          - /
          - Ref: DBName
  ReplicaJDBCConnectionString:
    Description: JDBC connection string for the replica database
    Value:
      Fn::Join:
        - ""
        - - jdbc:mysql://
          - Fn::GetAtt:
              - ReplicaDB
              - Endpoint.Address
          - ":"
          - Fn::GetAtt:
              - ReplicaDB
              - Endpoint.Port
          - /
          - Ref: DBName
{
  "Resources": {
    "DBEC2SecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Condition": "Is-EC2-VPC",
      "Properties": {
        "GroupDescription": "Open database for access",
        "SecurityGroupIngress": [
          {
            "IpProtocol": "tcp",
            "FromPort": 3306,
            "ToPort": 3306,
            "SourceSecurityGroupName": {
              "Ref": "EC2SecurityGroup"
            }
          }
        ]
      }
    },
    "DBSecurityGroup": {
      "Type": "AWS::RDS::DBSecurityGroup",
      "Condition": "Is-EC2-Classic",
      "Properties": {
        "DBSecurityGroupIngress": [
          {
            "EC2SecurityGroupName": {
              "Ref": "EC2SecurityGroup"
            }
          }
        ],
        "GroupDescription": "database access"
      }
    },
    "MasterDB": {
      "Type": "AWS::RDS::DBInstance",
      "Properties": {
        "VPCSecurityGroups": {
          "Fn::If": [
            "Is-EC2-VPC",
            [
              {
                "Fn::GetAtt": [
                  "DBEC2SecurityGroup",
                  "GroupId"
                ]
              }
            ],
            {
              "Ref": "AWS::NoValue"
            }
          ]
        },
        "DBSecurityGroups": {
          "Fn::If": [
            "Is-EC2-Classic",
            [
              {
                "Ref": "DBSecurityGroup"
              }
            ],
            {
              "Ref": "AWS::NoValue"
            }
          ]
        },
        "DBName": {
          "Ref": "DBName"
        },
        "AllocatedStorage": {
          "Ref": "DBAllocatedStorage"
        },
        "DBInstanceClass": {
          "Ref": "DBInstanceClass"
        },
        "MasterUserPassword": {
          "Ref": "DBPassword"
        },
        "MultiAZ": true,
        "Engine": "MySQL",
        "MasterUsername": {
          "Ref": "DBUser"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": "Master Database"
          }
        ]
      },
      "DeletionPolicy": "Snapshot",
      "UpdateReplacePolicy": "Snapshot"
    },
    "ReplicaDB": {
      "Type": "AWS::RDS::DBInstance",
      "Properties": {
        "SourceDBInstanceIdentifier": {
          "Ref": "MasterDB"
        },
        "DBInstanceClass": {
          "Ref": "DBInstanceClass"
        },
        "MultiAZ": true,
        "Tags": [
          {
            "Key": "Name",
            "Value": "Read Replica Database"
          }
        ]
      }
    }
  },
  "Outputs": {
    "EC2Platform": {
      "Description": "Platform in which this stack is deployed",
      "Value": {
        "Fn::If": [
          "Is-EC2-VPC",
          "EC2-VPC",
          "EC2-Classic"
        ]
      }
    },
    "MasterJDBCConnectionString": {
      "Description": "JDBC connection string for the master database",
      "Value": {
        "Fn::Join": [
          "",
          [
            "jdbc:mysql://",
            {
              "Fn::GetAtt": [
                "MasterDB",
                "Endpoint.Address"
              ]
            },
            ":",
            {
              "Fn::GetAtt": [
                "MasterDB",
                "Endpoint.Port"
              ]
            },
            "/",
            {
              "Ref": "DBName"
            }
          ]
        ]
      }
    },
    "ReplicaJDBCConnectionString": {
      "Description": "JDBC connection string for the replica database",
      "Value": {
        "Fn::Join": [
          "",
          [
            "jdbc:mysql://",
            {
              "Fn::GetAtt": [
                "ReplicaDB",
                "Endpoint.Address"
              ]
            },
            ":",
            {
              "Fn::GetAtt": [
                "ReplicaDB",
                "Endpoint.Port"
              ]
            },
            "/",
            {
              "Ref": "DBName"
            }
          ]
        ]
      }
    }
  },
  "AWSTemplateFormatVersion": "2010-09-09T00:00:00Z",
  "Description": "AWS CloudFormation Sample Template RDS_MySQL_With_Read_Replica: Sample template showing how to create a highly-available, RDS DBInstance with a read replica. **WARNING** This template creates an Amazon Relational Database Service database instance and Amazon CloudWatch alarms. You will be billed for the AWS resources used if you create a stack from this template.",
  "Parameters": {
    "DBName": {
      "MaxLength": "64",
      "AllowedPattern": "[a-zA-Z][a-zA-Z0-9]*",
      "ConstraintDescription": "must begin with a letter and contain only alphanumeric characters.",
      "Default": "MyDatabase",
      "Description": "The database name",
      "Type": "String",
      "MinLength": "1"
    },
    "DBUser": {
      "NoEcho": "true",
      "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": "1",
      "MaxLength": "41",
      "AllowedPattern": "[a-zA-Z0-9]+",
      "ConstraintDescription": "must contain only alphanumeric characters."
    },
    "DBAllocatedStorage": {
      "Default": "5",
      "Description": "The size of the database (Gb)",
      "Type": "Number",
      "MinValue": "5",
      "MaxValue": "1024",
      "ConstraintDescription": "must be between 5 and 1024Gb."
    },
    "DBInstanceClass": {
      "Type": "String",
      "Default": "db.t2.small",
      "AllowedValues": [
        "db.t1.micro",
        "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.m4.large",
        "db.m4.xlarge",
        "db.m4.2xlarge",
        "db.m4.4xlarge",
        "db.m4.10xlarge",
        "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",
        "db.t2.micro",
        "db.t2.small",
        "db.t2.medium",
        "db.t2.large"
      ],
      "ConstraintDescription": "must select a valid database instance type.",
      "Description": "The database instance type"
    },
    "EC2SecurityGroup": {
      "Default": "default",
      "Type": "String",
      "AllowedPattern": "[a-zA-Z0-9\\-]+",
      "ConstraintDescription": "must be a valid security group name.",
      "Description": "The EC2 security group that contains instances that need access to the database"
    }
  },
  "Conditions": {
    "Is-EC2-VPC": {
      "Fn::Or": [
        {
          "Fn::Equals": [
            {
              "Ref": "AWS::Region"
            },
            "eu-central-1"
          ]
        },
        {
          "Fn::Equals": [
            {
              "Ref": "AWS::Region"
            },
            "cn-north-1"
          ]
        }
      ]
    },
    "Is-EC2-Classic": {
      "Fn::Not": [
        {
          "Condition": "Is-EC2-VPC"
        }
      ]
    }
  }
}

Non-Compliant Code Examples

{
  "Conditions": {
    "Is-EC2-VPC": {
      "Fn::Or": [
        {
          "Fn::Equals": [
            {
              "Ref": "AWS::Region"
            },
            "eu-central-1"
          ]
        },
        {
          "Fn::Equals": [
            {
              "Ref": "AWS::Region"
            },
            "cn-north-1"
          ]
        }
      ]
    },
    "Is-EC2-Classic": {
      "Fn::Not": [
        {
          "Condition": "Is-EC2-VPC"
        }
      ]
    }
  },
  "Resources": {
    "DBEC2SecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Condition": "Is-EC2-VPC",
      "Properties": {
        "GroupDescription": "Open database for access",
        "SecurityGroupIngress": [
          {
            "IpProtocol": "tcp",
            "FromPort": 3306,
            "ToPort": 3306,
            "SourceSecurityGroupName": {
              "Ref": "EC2SecurityGroup"
            }
          }
        ]
      }
    },
    "DBSecurityGroup": {
      "Type": "AWS::RDS::DBSecurityGroup",
      "Condition": "Is-EC2-Classic",
      "Properties": {
        "GroupDescription": "database access",
        "DBSecurityGroupIngress": [
          {
            "EC2SecurityGroupName": {
              "Ref": "EC2SecurityGroup"
            }
          }
        ]
      }
    },
    "MasterDB": {
      "Type": "AWS::RDS::DBInstance",
      "Properties": {
        "DBSecurityGroups": {
          "Fn::If": [
            "Is-EC2-Classic",
            [
              {
                "Ref": "DBSecurityGroup"
              }
            ],
            {
              "Ref": "AWS::NoValue"
            }
          ]
        },
        "DBName": {
          "Ref": "DBName"
        },
        "DBInstanceClass": {
          "Ref": "DBInstanceClass"
        },
        "Engine": "MySQL",
        "MasterUserPassword": {
          "Ref": "DBPassword"
        },
        "MultiAZ": false,
        "AllocatedStorage": {
          "Ref": "DBAllocatedStorage"
        },
        "MasterUsername": {
          "Ref": "DBUser"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": "Master Database"
          }
        ],
        "VPCSecurityGroups": {
          "Fn::If": [
            "Is-EC2-VPC",
            [
              {
                "Fn::GetAtt": [
                  "DBEC2SecurityGroup",
                  "GroupId"
                ]
              }
            ],
            {
              "Ref": "AWS::NoValue"
            }
          ]
        }
      },
      "DeletionPolicy": "Snapshot",
      "UpdateReplacePolicy": "Snapshot"
    },
    "ReplicaDB": {
      "Type": "AWS::RDS::DBInstance",
      "Properties": {
        "SourceDBInstanceIdentifier": {
          "Ref": "MasterDB"
        },
        "DBInstanceClass": {
          "Ref": "DBInstanceClass"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": "Read Replica Database"
          }
        ]
      }
    }
  },
  "Outputs": {
    "ReplicaJDBCConnectionString": {
      "Description": "JDBC connection string for the replica database",
      "Value": {
        "Fn::Join": [
          "",
          [
            "jdbc:mysql://",
            {
              "Fn::GetAtt": [
                "ReplicaDB",
                "Endpoint.Address"
              ]
            },
            ":",
            {
              "Fn::GetAtt": [
                "ReplicaDB",
                "Endpoint.Port"
              ]
            },
            "/",
            {
              "Ref": "DBName"
            }
          ]
        ]
      }
    },
    "EC2Platform": {
      "Description": "Platform in which this stack is deployed",
      "Value": {
        "Fn::If": [
          "Is-EC2-VPC",
          "EC2-VPC",
          "EC2-Classic"
        ]
      }
    },
    "MasterJDBCConnectionString": {
      "Description": "JDBC connection string for the master database",
      "Value": {
        "Fn::Join": [
          "",
          [
            "jdbc:mysql://",
            {
              "Fn::GetAtt": [
                "MasterDB",
                "Endpoint.Address"
              ]
            },
            ":",
            {
              "Fn::GetAtt": [
                "MasterDB",
                "Endpoint.Port"
              ]
            },
            "/",
            {
              "Ref": "DBName"
            }
          ]
        ]
      }
    }
  },
  "AWSTemplateFormatVersion": "2010-09-09T00:00:00Z",
  "Description": "AWS CloudFormation Sample Template RDS_MySQL_With_Read_Replica: Sample template showing how to create a highly-available, RDS DBInstance with a read replica. **WARNING** This template creates an Amazon Relational Database Service database instance and Amazon CloudWatch alarms. You will be billed for the AWS resources used if you create a stack from this template.",
  "Parameters": {
    "DBAllocatedStorage": {
      "MaxValue": "1024",
      "ConstraintDescription": "must be between 5 and 1024Gb.",
      "Default": "5",
      "Description": "The size of the database (Gb)",
      "Type": "Number",
      "MinValue": "5"
    },
    "DBInstanceClass": {
      "AllowedValues": [
        "db.t1.micro",
        "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.m4.large",
        "db.m4.xlarge",
        "db.m4.2xlarge",
        "db.m4.4xlarge",
        "db.m4.10xlarge",
        "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",
        "db.t2.micro",
        "db.t2.small",
        "db.t2.medium",
        "db.t2.large"
      ],
      "ConstraintDescription": "must select a valid database instance type.",
      "Description": "The database instance type",
      "Type": "String",
      "Default": "db.t2.small"
    },
    "EC2SecurityGroup": {
      "AllowedPattern": "[a-zA-Z0-9\\-]+",
      "ConstraintDescription": "must be a valid security group name.",
      "Description": "The EC2 security group that contains instances that need access to the database",
      "Default": "default",
      "Type": "String"
    },
    "DBName": {
      "Default": "MyDatabase",
      "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": {
      "NoEcho": "true",
      "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": "1",
      "MaxLength": "41",
      "AllowedPattern": "[a-zA-Z0-9]+",
      "ConstraintDescription": "must contain only alphanumeric characters."
    }
  }
}
AWSTemplateFormatVersion: 2010-09-09
Description: "AWS CloudFormation Sample Template RDS_MySQL_With_Read_Replica:
  Sample template showing how to create a highly-available, RDS DBInstance with
  a read replica. **WARNING** This template creates an Amazon Relational
  Database Service database instance and Amazon CloudWatch alarms. You will be
  billed for the AWS resources used if you create a stack from this template."
Parameters:
  DBName:
    Default: MyDatabase
    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:
    NoEcho: "true"
    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: "1"
    MaxLength: "41"
    AllowedPattern: "[a-zA-Z0-9]+"
    ConstraintDescription: must contain only alphanumeric characters.
  DBAllocatedStorage:
    Default: "5"
    Description: The size of the database (Gb)
    Type: Number
    MinValue: "5"
    MaxValue: "1024"
    ConstraintDescription: must be between 5 and 1024Gb.
  DBInstanceClass:
    Description: The database instance type
    Type: String
    Default: db.t2.small
    AllowedValues:
      - db.t1.micro
      - 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.m4.large
      - db.m4.xlarge
      - db.m4.2xlarge
      - db.m4.4xlarge
      - db.m4.10xlarge
      - 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
      - db.t2.micro
      - db.t2.small
      - db.t2.medium
      - db.t2.large
    ConstraintDescription: must select a valid database instance type.
  EC2SecurityGroup:
    Description: The EC2 security group that contains instances that need access to
      the database
    Default: default
    Type: String
    AllowedPattern: "[a-zA-Z0-9\\-]+"
    ConstraintDescription: must be a valid security group name.
Conditions:
  Is-EC2-VPC:
    Fn::Or:
      - Fn::Equals:
          - Ref: AWS::Region
          - eu-central-1
      - Fn::Equals:
          - Ref: AWS::Region
          - cn-north-1
  Is-EC2-Classic:
    Fn::Not:
      - Condition: Is-EC2-VPC
Resources:
  DBEC2SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Condition: Is-EC2-VPC
    Properties:
      GroupDescription: Open database for access
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 3306
          ToPort: 3306
          SourceSecurityGroupName:
            Ref: EC2SecurityGroup
  DBSecurityGroup:
    Type: AWS::RDS::DBSecurityGroup
    Condition: Is-EC2-Classic
    Properties:
      DBSecurityGroupIngress:
        - EC2SecurityGroupName:
            Ref: EC2SecurityGroup
      GroupDescription: database access
  MasterDB:
    Type: AWS::RDS::DBInstance
    Properties:
      DBName:
        Ref: DBName
      AllocatedStorage:
        Ref: DBAllocatedStorage
      DBInstanceClass:
        Ref: DBInstanceClass
      Engine: MySQL
      MasterUsername:
        Ref: DBUser
      MasterUserPassword:
        Ref: DBPassword
      MultiAZ: false
      Tags:
        - Key: Name
          Value: Master Database
      VPCSecurityGroups:
        Fn::If:
          - Is-EC2-VPC
          - - Fn::GetAtt:
                - DBEC2SecurityGroup
                - GroupId
          - Ref: AWS::NoValue
      DBSecurityGroups:
        Fn::If:
          - Is-EC2-Classic
          - - Ref: DBSecurityGroup
          - Ref: AWS::NoValue
    DeletionPolicy: Snapshot
    UpdateReplacePolicy: Snapshot
  ReplicaDB:
    Type: AWS::RDS::DBInstance
    Properties:
      SourceDBInstanceIdentifier:
        Ref: MasterDB
      DBInstanceClass:
        Ref: DBInstanceClass
      Tags:
        - Key: Name
          Value: Read Replica Database
Outputs:
  EC2Platform:
    Description: Platform in which this stack is deployed
    Value:
      Fn::If:
        - Is-EC2-VPC
        - EC2-VPC
        - EC2-Classic
  MasterJDBCConnectionString:
    Description: JDBC connection string for the master database
    Value:
      Fn::Join:
        - ""
        - - jdbc:mysql://
          - Fn::GetAtt:
              - MasterDB
              - Endpoint.Address
          - ":"
          - Fn::GetAtt:
              - MasterDB
              - Endpoint.Port
          - /
          - Ref: DBName
  ReplicaJDBCConnectionString:
    Description: JDBC connection string for the replica database
    Value:
      Fn::Join:
        - ""
        - - jdbc:mysql://
          - Fn::GetAtt:
              - ReplicaDB
              - Endpoint.Address
          - ":"
          - Fn::GetAtt:
              - ReplicaDB
              - Endpoint.Port
          - /
          - Ref: DBName