AWS DLM LifeCycle Policy for Creating Snapshots for EBS Volumes on an EC2 Instance

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)"}]
               }
            ]
          }
      }
    }
}

2 Comments:

  1. Glad to be one of many visitors on this awesome web site : D.

  2. 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.

Leave a Reply

Your email address will not be published. Required fields are marked *