examples/RDS_MySQL_With_Read_Replica-annotated.ps1
#ipmo -Force AwsCfn <# Adapted from: https://s3.amazonaws.com/cloudformation-templates-us-east-1/RDS_MySQL_With_Read_Replica.template Listed on: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/sample-templates-services-us-east-1.html #> $templateDescription = "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." $dbInstanceClasses = "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" <#(ORIG) { "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.", ... } #> Template -Description $templateDescription -JSON -Compress { ## If left unspecified, the default Template Format Version is "2010-09-09" <#(ORIG) "Parameters": { ... } #> #region -- Parameters -- <#(ORIG) "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." } #> Parameter DBName String -Default "MyDatabase" ` -MinLength 1 -MaxLength 64 -AllowedPattern "[a-zA-Z][a-zA-Z0-9]*" ` -Description "The database name" ` -ConstraintDescription "must begin with a letter and contain only alphanumeric characters." <#(ORIG) "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." } #> Parameter DBUser String -NoEcho ` -MinLength 1 -MaxLength 16 -AllowedPattern "[a-zA-Z][a-zA-Z0-9]*" ` -Description "The database admin account username" ` -ConstraintDescription "must begin with a letter and contain only alphanumeric characters." <#(ORIG) "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." } #> Parameter DBPassword String -NoEcho ` -MinLength 1 -MaxLength 41 -AllowedPattern "[a-zA-Z0-9]+" ` -Description "The database admin account password" ` -ConstraintDescription "must contain only alphanumeric characters." <#(ORIG) "DBAllocatedStorage": { "Default": "5", "Description" : "The size of the database (Gb)", "Type": "Number", "MinValue": "5", "MaxValue": "1024", "ConstraintDescription" : "must be between 5 and 1024Gb." } #> Parameter DBAllocatedStorage Number -Default 5 ` -MinValue 5 -MaxValue 1024 ` -Description "The size of the database (Gb)" ` -ConstraintDescription "must be between 5 and 1024Gb." <#(ORIG) "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." } #> Parameter DBInstanceClass String -Default "db.t2.small" ` -AllowedValues $dbInstanceClasses ` -Description "The database instance type" ` -ConstraintDescription "must select a valid database instance type." <#(ORIG) "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." } #> Parameter EC2SecurityGroup String -Default "default" ` -AllowedPattern "[a-zA-Z0-9\-]+" ` -Description "The EC2 security group that contains instances that need access to the database" ` -ConstraintDescription "must be a valid security group name." <#(ORIG) "MultiAZ" : { "Description" : "Multi-AZ master database", "Type" : "String", "Default" : "false", "AllowedValues" : [ "true", "false" ], "ConstraintDescription" : "must be true or false." } #> Parameter MultiAZ String -Default false ` -AllowedValues true,false ` -Description "Multi-AZ master database" ` -ConstraintDescription "must be true or false." #endregion -- Parameters -- #region -- Conditions -- <#(ORIG) "Is-EC2-VPC" : { "Fn::Or" : [ {"Fn::Equals" : [{"Ref" : "AWS::Region"}, "eu-central-1" ]}, {"Fn::Equals" : [{"Ref" : "AWS::Region"}, "cn-north-1" ]}]} #> Condition "Is-EC2-VPC" (Fn-Or @( (Fn-Equals (Pseudo Region) "eu-central-1") (Fn-Equals (Pseudo Region) "cn-north-1") )) <#(ORIG) "Is-EC2-Classic" : { "Fn::Not" : [{ "Condition" : "Is-EC2-VPC"}]} #> Condition "Is-EC2-Classic" (Fn-Not (Fn-Condition "Is-EC2-VPC")) #endregion -- Conditions -- #region -- Resources -- <#(ORIG) "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" } }] } } #> Res-EC2-SecurityGroup DBEC2SecurityGroup -Condition "Is-EC2-VPC" ` -GroupDescription "Open database for access" ` -SecurityGroupIngress @{ ## Notice this property takes an array of objects, but ## we only specify a single object definition and POSH ## will automagically wrap it in a single-element array IpProtocol = "tcp" FromPort = "3306" ToPort = "3306" SourceSecurityGroupName = (Fn-Ref EC2SecurityGroup) } <#(ORIG) "DBSecurityGroup": { "Type": "AWS::RDS::DBSecurityGroup", "Condition" : "Is-EC2-Classic", "Properties": { "DBSecurityGroupIngress": { "EC2SecurityGroupName": { "Ref": "EC2SecurityGroup" } }, "GroupDescription": "database access" } } #> Res-RDS-DBSecurityGroup DBSecurityGroup -Condition Is-EC2-Classic ` -DBSecurityGroupIngress @{ EC2SecurityGroupName = (Fn-Ref EC2SecurityGroup) } ` -GroupDescription "database access" <#(ORIG) "MasterDB" : { "Type" : "AWS::RDS::DBInstance", "Properties" : { "DBName" : { "Ref" : "DBName" }, "AllocatedStorage" : { "Ref" : "DBAllocatedStorage" }, "DBInstanceClass" : { "Ref" : "DBInstanceClass" }, "Engine" : "MySQL", "MasterUsername" : { "Ref" : "DBUser" }, "MasterUserPassword" : { "Ref" : "DBPassword" }, "MultiAZ" : { "Ref" : "MultiAZ" }, "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" } #> Res-RDS-DBInstance MasterDB -DeletionPolicy Snapshot ` -Engine MySQL -Tags @{ Name = "Master Database" } { Property DBName (Fn-Ref DBName) Property AllocatedStorage (Fn-Ref DBAllocatedStorage) Property DBInstanceClass (Fn-Ref DBInstanceClass) Property MasterUsername (Fn-Ref DBUser) Property MasterUserPassword (Fn-Ref DBPassword) Property MultiAZ (Fn-Ref MultiAZ) Property VPCSecurityGroups (Fn-If Is-EC2-VPC ` (Fn-GetAtt DBEC2SecurityGroup GroupId) ` (Pseudo NoValue)) Property DBSecurityGroups (Fn-If Is-EC2-Classic ` (Fn-Ref DBSecurityGroup) ` (Pseudo NoValue)) } <#(ORIG) "ReplicaDB" : { "Type" : "AWS::RDS::DBInstance", "Properties" : { "SourceDBInstanceIdentifier" : { "Ref" : "MasterDB" }, "DBInstanceClass" : { "Ref" : "DBInstanceClass" }, "Tags" : [{ "Key" : "Name", "Value" : "Read Replica Database" }] } } #> Res-RDS-DBInstance ReplicaDB -Tags @{ Name = "Read Replica Database" } { Property SourceDBInstanceIdentifier (Fn-Ref MasterDB) Property DBInstanceClass (Fn-Ref DBInstanceClass) } #endregion -- Resources -- #region -- Outputs -- <#(ORIG) "EC2Platform" : { "Description" : "Platform in which this stack is deployed", "Value" : { "Fn::If" : [ "Is-EC2-VPC", "EC2-VPC", "EC2-Classic" ]} } #> Output EC2Platform ` -Description "Platform in which this stack is deployed" ` -Value (Fn-If Is-EC2-VPC "EC2-VPC" "EC2-Classic") <#(ORIG) "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" }]]} } #> Output MasterJDBCConnectionString ` -Description "JDBC connection string for the master database" ` -Value (Fn-Join "" @( "jdbc:mysql://" (Fn-GetAtt MasterDB "Endpoint.Address") ":" (Fn-GetAtt MasterDB "Endpoint.Port") "/" (Fn-Ref DBName) )) <#(ORIG) "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" }]]} } #> Output ReplicaJDBCConnectionString ` -Description "JDBC connection string for the replica database" ` -Value (Fn-Join "" @( "jdbc:mysql://" (Fn-GetAtt ReplicaDB "Endpoint.Address") ":" (Fn-GetAtt ReplicaDB "Endpoint.Port") "/" (Fn-Ref DBName) )) #endregion -- Outputs -- } |