It seems AWS CloudFormation does not readily support creating EBS Volume Snapshots via BlockDeviceMappings‘s EBS property. Luckily there is an alternative approach that allows you to setup a DLM LifeCycle Policy which scans for EC2 Instance Tags (apparently there is also no support to really tag the Volumes directly via CloudFormation that I am aware of).
As a result, here is how you can use the LifeCyclePolicy to achieve EBS Volume Snapshots. I recommended not using CronExpression
when defining the Schedule, since it seems to not work. Also, be mindful, it seems some configurations here can not be easily changed via Stack updates. I had to physically delete the LifeCyclePolicy from the template –> Update –> add the policy back –> then update once more with my changes at a couple of points. One such example:
The following parameter(s) cannot be updated: ResourceTypes (Service: AmazonDLM; Status Code: 400; Error Code: InvalidRequestException; Request ID: 4ba58c20-329a-4abf-b44b-6d2ab5db201b; Proxy: null)
Without further ado, here are the important parts of the CloudFormation template which includes both daily and hourly backups.
{
"DlmServiceRole": {
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": [
"sts:AssumeRole"
],
"Effect": "Allow",
"Principal": {
"Service": [
"dlm.amazonaws.com"
]
}
}
]
},
"ManagedPolicyArns": [
"arn:aws:iam::aws:policy/service-role/AWSDataLifecycleManagerServiceRole"
],
"Path": "/service-role/"
},
"Type": "AWS::IAM::Role"
},
"DlmLifecyclePolicy": {
"Type": "AWS::DLM::LifecyclePolicy",
"Properties": {
"Description": {
"Fn::Join": [
"",
[
"DLM Lifecycle Policy for ",
{
"Ref": "Neo4JServerName"
},
" - ",
{
"Ref": "AWS::StackName"
}
]
]
},
"State": "ENABLED",
"ExecutionRoleArn": {
"Fn::GetAtt": [
"DlmServiceRole",
"Arn"
]
},
"PolicyDetails": {
"ResourceTypes": ["INSTANCE"],
"TargetTags": [
{
"Key": "Name",
"Value": {
"Fn::Join": [
"",
[
{
"Ref": "Neo4JServerName"
},
" (",
{
"Ref": "AWS::StackName"
},
")"
]
]
}
}
],
"Schedules": [
{
"Name": {
"Fn::Join": [
"",
[
"Hourly Database Backup Snapshots - ",
{
"Ref": "Neo4JServerName"
},
" - ",
{
"Ref": "AWS::StackName"
}
]
]
},
"TagsToAdd": [
{
"Key": "type",
"Value": "HourlySnapshot"
}
],
"CreateRule": {
"Interval": "1",
"IntervalUnit": "HOURS",
"Times": ["16:00"]
},
"RetainRule": {
"Count": "72"
},
"CopyTags": "true",
"VariableTags": [{"Key":"instance-id", "Value":"$(instance-id)"}, {"Key":"timestamp", "Value":"$(timestamp)"}]
},
{
"Name": {
"Fn::Join": [
"",
[
"Daily Database Backup Snapshots - ",
{
"Ref": "Neo4JServerName"
},
" - ",
{
"Ref": "AWS::StackName"
}
]
]
},
"TagsToAdd": [
{
"Key": "type",
"Value": "HourlySnapshot"
}
],
"CreateRule": {
"Interval": "24",
"IntervalUnit": "HOURS",
"Times": ["16:00"]
},
"RetainRule": {
"Count": "7"
},
"CopyTags": "true",
"VariableTags": [{"Key":"instance-id", "Value":"$(instance-id)"}, {"Key":"timestamp", "Value":"$(timestamp)"}]
}
]
}
}
}
}
Glad to be one of many visitors on this awesome web site : D.
You made some first rate points there. I seemed on the web for the difficulty and found most individuals will go along with with your website.
I really like your writing style, wonderful info , thankyou for posting : D.
I’d have to examine with you here. Which is not one thing I usually do! I take pleasure in reading a post that may make folks think. Additionally, thanks for permitting me to comment!
You really make it appear really easy along with your presentation but I in finding this matter to be really one thing which I think I would by no means understand. It kind of feels too complicated and extremely vast for me. I’m having a look forward for your subsequent post, I¦ll attempt to get the hang of it!
Saved as a favorite, I really like your blog!