Project: KICS (Provisioning / Security & Compliance)
File: 2b1d4935-9acf-48a7-8466-10d18bf51a69.md

title: RDS Multi-AZ Deployment Disabled hide: toc: true navigation: true <style> .highlight .hll { background-color: #ff171742; } .md-content { max-width: 1100px; margin: 0 auto; } </style> Query id: 2b1d4935-9acf-48a7-8466-10d18bf51a69 Query name: RDS Multi-AZ Deployment Disabled Platform: CloudFormation Severity: <span style="color:#ff7213">Medium</span> Category: Availability URL: AWS RDS Instance should have a multi-az deployment<br> ```yaml title="Positive test num. 1 - yaml file" hl_lines="128 148" AWSTemplateFormatVersion: 2010-09-09 Description: "AWS CloudFormation Sample Template RDSMySQLWithReadReplica: 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: "*" 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: "*" 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 ``` ```json title="Positive test

2 - json file" hl_lines="89 124" { "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 RDSMySQLWithReadReplica: 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": "*", "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": "*", "ConstraintDescription": "must begin with a letter and contain only alphanumeric

}, "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." } } } ``` ```yaml title="Negative test num. 1 - yaml file" AWSTemplateFormatVersion: 2010-09-09 Description: "AWS CloudFormation Sample Template RDSMySQLWithReadReplica: 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: "*" 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: "*" 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 ``` ```json title="Negative test

2 - json file" { "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 RDSMySQLWithReadReplica: 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": "*", "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": "*", "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" } ] } } } ```