Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A basic CloudFormation template for an RDS Aurora cluster.
---
AWSTemplateFormatVersion: 2010-09-09
Description: >
A basic CloudFormation template for an RDS Aurora cluster.
Parameters:
DatabaseUsername:
AllowedPattern: "[a-zA-Z0-9]+"
ConstraintDescription: must be between 1 to 16 alphanumeric characters.
Description: The database admin account user name, between 1 to 16 alphanumeric characters.
MaxLength: '16'
MinLength: '1'
Type: String
DatabasePassword:
AllowedPattern: "[a-zA-Z0-9]+"
ConstraintDescription: must be between 8 to 41 alphanumeric characters.
Description: The database admin account password, between 8 to 41 alphanumeric characters.
MaxLength: '41'
MinLength: '8'
NoEcho: 'true'
Type: String
Mappings:
'000000000000':
us-east-1:
Subnets:
- subnet-00000000
- subnet-11111111
- subnet-22222222
SecurityGroups:
- sg-00000000
InstanceType: db.r4.large
BackupRetentionPeriod: 7
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: Database Configuration
Parameters:
- DatabaseUsername
- DatabasePassword
ParameterLabels:
DatabaseUsername:
default: Database Username
DatabasePassword:
default: Database Password
Resources:
StackAlarmTopic:
Type: AWS::SNS::Topic
Properties:
DisplayName: Stack Alarm Topic
DatabaseSubnetGroup:
Type: AWS::RDS::DBSubnetGroup
Properties:
DBSubnetGroupDescription: CloudFormation managed DB subnet group.
SubnetIds: !FindInMap [!Ref "AWS::AccountId", !Ref "AWS::Region", "Subnets"]
DatabaseCluster:
Type: AWS::RDS::DBCluster
Properties:
Engine: aurora
MasterUsername: !Ref "DatabaseUsername"
MasterUserPassword: !Ref "DatabasePassword"
BackupRetentionPeriod: !FindInMap [!Ref "AWS::AccountId", !Ref "AWS::Region", "BackupRetentionPeriod"]
PreferredBackupWindow: 01:00-02:00
PreferredMaintenanceWindow: mon:03:00-mon:04:00
DBSubnetGroupName: !Ref "DatabaseSubnetGroup"
VpcSecurityGroupIds: !FindInMap [!Ref "AWS::AccountId", !Ref "AWS::Region", "SecurityGroups"]
DatabasePrimaryInstance:
Type: AWS::RDS::DBInstance
Properties:
Engine: aurora
DBClusterIdentifier: !Ref "DatabaseCluster"
DBInstanceClass: !FindInMap [!Ref "AWS::AccountId", !Ref "AWS::Region", "InstanceType"]
DBSubnetGroupName: !Ref "DatabaseSubnetGroup"
DatabasePrimaryCPUAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmDescription: Primary database CPU utilization is over 80%.
Namespace: AWS/RDS
MetricName: CPUUtilization
Unit: Percent
Statistic: Average
Period: 300
EvaluationPeriods: 2
Threshold: 80
ComparisonOperator: GreaterThanOrEqualToThreshold
Dimensions:
- Name: DBInstanceIdentifier
Value: !Ref "DatabasePrimaryInstance"
AlarmActions:
- Ref: StackAlarmTopic
InsufficientDataActions:
- Ref: StackAlarmTopic
DatabasePrimaryMemoryAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmDescription: Primary database freeable memory is under 700MB.
Namespace: AWS/RDS
MetricName: FreeableMemory
Unit: Bytes
Statistic: Average
Period: 300
EvaluationPeriods: 2
Threshold: 700000000
ComparisonOperator: LessThanOrEqualToThreshold
Dimensions:
- Name: DBInstanceIdentifier
Value: !Ref "DatabasePrimaryInstance"
AlarmActions:
- Ref: StackAlarmTopic
InsufficientDataActions:
- Ref: StackAlarmTopic
DatabasePrimaryReplicationAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmDescription: Database replication latency is over 200ms.
Namespace: AWS/RDS
MetricName: AuroraReplicaLag
Unit: Milliseconds
Statistic: Average
Period: 300
EvaluationPeriods: 2
Threshold: 200
ComparisonOperator: GreaterThanOrEqualToThreshold
Dimensions:
- Name: DBInstanceIdentifier
Value: !Ref "DatabaseReplicaInstance"
AlarmActions:
- Ref: StackAlarmTopic
DatabaseReplicaInstance:
Type: AWS::RDS::DBInstance
Properties:
Engine: aurora
DBClusterIdentifier: !Ref "DatabaseCluster"
DBInstanceClass: !FindInMap [!Ref "AWS::AccountId", !Ref "AWS::Region", "InstanceType"]
DBSubnetGroupName: !Ref "DatabaseSubnetGroup"
DatabaseReplicaCPUAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmDescription: Replica database CPU utilization is over 80%.
Namespace: AWS/RDS
MetricName: CPUUtilization
Unit: Percent
Statistic: Average
Period: 300
EvaluationPeriods: 2
Threshold: 80
ComparisonOperator: GreaterThanOrEqualToThreshold
Dimensions:
- Name: DBInstanceIdentifier
Value: !Ref "DatabaseReplicaInstance"
AlarmActions:
- Ref: StackAlarmTopic
InsufficientDataActions:
- Ref: StackAlarmTopic
DatabaseReplicaMemoryAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmDescription: Replica database freeable memory is under 700MB.
Namespace: AWS/RDS
MetricName: FreeableMemory
Unit: Bytes
Statistic: Average
Period: 300
EvaluationPeriods: 2
Threshold: 700000000
ComparisonOperator: LessThanOrEqualToThreshold
Dimensions:
- Name: DBInstanceIdentifier
Value: !Ref "DatabaseReplicaInstance"
AlarmActions:
- Ref: StackAlarmTopic
InsufficientDataActions:
- Ref: StackAlarmTopic
DatabaseReplicaReplicationAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmDescription: Database replication latency is over 200ms.
Namespace: AWS/RDS
MetricName: AuroraReplicaLag
Unit: Milliseconds
Statistic: Average
Period: 300
EvaluationPeriods: 2
Threshold: 200
ComparisonOperator: GreaterThanOrEqualToThreshold
Dimensions:
- Name: DBInstanceIdentifier
Value: !Ref "DatabaseReplicaInstance"
AlarmActions:
- Ref: StackAlarmTopic
@larriebee

This comment has been minimized.

Copy link

larriebee commented Aug 15, 2017

👍 Yep, I had to take one of them out as well to get the template to work.

@zerokelvin-27315

This comment has been minimized.

Copy link

zerokelvin-27315 commented Sep 19, 2017

DatabasePrimaryMemoryAlarm is defined twice - it looks like the second instance should be: DatabaseReplicaMemoryAlarm

@phette

This comment has been minimized.

Copy link

phette commented Oct 4, 2017

The primary and replica instances will come up in parallel where the replica might complete first and therefore become the primary of the cluster. It's fairly inconsequential, but it happened to me as I was explicitly specifying the name of each instance with "primary" and "replica" append to the name of each. You can remedy that by adding a DependsOn where the replica can't come up until the primary is complete. However, that will drastically increase the initial deployment time. Otherwise, you could change the logic ids to be agnostic about which one is the primary/replica.

@sjparkinson

This comment has been minimized.

Copy link
Owner Author

sjparkinson commented Jan 26, 2018

Thanks for all the comments. I've gone ahead and made some changes, and fixed the copy pasta issue.

We've learnt a few things at the FT since I first wrote this template, one of the major things was to make more use of mappings instead of parameters.

Found it tricky to find a good name for the instance resources @phette, so left them as they are.

At the time of writing, we're also currently looking for a Cloud Platform Engineer for anyone interested, see https://aboutus.ft.com/en-gb/careers/current-openings.

@ernievd

This comment has been minimized.

Copy link

ernievd commented Jan 28, 2019

I am just starting to write CloudFormation templates and I am trying to get this to run. First off I notice that I need to replace the '000000000000' in mappings with my user id correct? Next, is this referencing default subnets and security groups? Should I just add a VPC to this template and create my own subnets and security groups? Anything else for a newbie to know to try and get this going? Also, any good resources for me to learn all the basics of cloudformation with? I am also looking into using troposhere and/or terraform after i get a solid foundation with purring together cloudformation templates on there own. Any suggestions on these?

Thanks for any advice!!!

Ernie

@sjparkinson

This comment has been minimized.

Copy link
Owner Author

sjparkinson commented Jun 21, 2019

My goodness, sorry @ernievd, I've only just got the notification about your comment!

I am also looking into using troposhere and/or terraform after i get a solid foundation with purring together cloudformation templates on there own. Any suggestions on these?

If you're only working with AWS resources, I'd say stick with CloudFormation. The others shine best only when you are building infrastructure across a number of providers, but have to deal with more yourself such as state file management.

First off I notice that I need to replace the '000000000000' in mappings with my user id correct?

That needs to be replaced with your AWS account ID.

Next, is this referencing default subnets and security groups?

Nope, they also need to be looked up and replaced. The defaults for every AWS account will have different IDs. You may want to define your own security group as part of this template too rather than use the default ones.

Anything else for a newbie to know to try and get this going?

Hard for me to know. But if you did find out some things please do post them, I'd be interested to hear!

Again, sorry it's taken so many months to reply 😬

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.