Amazon DLM で簡単！スナップショット世代管理

##概要
2018/08/16から東京リージョンで使えるようになった Amazon Data Lifecycle Manager (Amazon DLM) で、EBSのスナップショットの作成のスケジューリングや世代管理を試してみます。コンソールから設定するだけなので誰でも簡単！ awscli からも操作できます。

##Amazon Data Lifecycle Manager (Amazon DLM)とは
Amazon EBS ボリュームをバックアップするスナップショットの作成、保持、削除を自動化できる機能です。

###参考サイト
[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/snapshot-lifecycle.html)

##制限事項
制限事項となりそうなのは、以下の項目です。

- リージョンごとに最大 100 のライフサイクルポリシーまで
- １つのリソースに最大 50 個のタグまで
- スナップショット作成の間隔は12 時間おきと 24 時間おきから選択
- 設定時刻から1時間以内にスナップショット作成が開始する
- 保持できるスナップショットの世代数は1000個まで


##早速使ってみよう
設定の方法としては、対象としたいEBSにタグをつけて、そのタグに対するライフサイクルポリシーを設定する、という流れです。簡単ですね。
###EBSにタグをつける
まずは、EBSに対象を絞り込むためのタグをつけましょう。
今回は`dlm`というタグに`1`という値を設定しておきます。
![Screenshot_2018-09-04 EC2 Management Console(4).png](https://qiita-image-store.s3.amazonaws.com/0/105824/01877a0d-6cb6-bf99-2411-f84a6878a757.png)


###ライフサイクルポリシーを設定する
EC2 の ELASTIC BLOCK STORE のメニューから Lifecycle Manager を選択し、 Create Snapshot Lifecycle Policy ボタンをクリックして設定画面を開きます。

####設定項目
設定項目は以下の通り。

| Left align                            |概要               |
|:--------------------------------------|:------------------|
| Description                           | ポリシーの説明    |
| Target volumes with tags              | ライフサイクルの対象とするEBSのタグの条件。入力候補が出る |
| Schedule Name                         | このスケジュールの名前 |
| Create snapshots every n Hours        | 実行間隔。12 時間おきと 24 時間おきから選択 |
| Snapshot creation start time hh:mm UTC| 実行時刻。UTCなので日本時間から -9時間 した値を設定する。設定した時刻の 1 時間以内にスナップショット作成が開始される |
| Retention rule                        | スナップショットを保持する世代数。最大値は1000
| Tag created snapshots                 | スナップショットに付けるタグ。DLM がデフォルトで付けるタグもあるので、他に必要であれば設定する |
| IAM role                              | Default roul を選択しておくと、初回に必要な権限を持つRole( AWSDataLifecycleManagerDefaultRole)が自動作成される |
| Policy status after creation          | 作成後すぐにポリシーを有効にするかどうか設定できる|

設定画面はこんな感じです。
![Screenshot_2018-09-04 EC2 Management Console(5).png](https://qiita-image-store.s3.amazonaws.com/0/105824/6e4038b8-5990-7e7c-7777-87460c9d7414.png)

![Screenshot_2018-09-04 EC2 Management Console(6).png](https://qiita-image-store.s3.amazonaws.com/0/105824/4aa69fa3-656d-011f-b0bf-30231a62a554.png)

作成後は、以下のような画面でライフサイクルの内容が確認できます。

<img width="786" alt="Screenshot_2018-09-04 EC2 Management Console(7).png" src="https://qiita-image-store.s3.amazonaws.com/0/105824/80413710-7fdb-24d4-106b-05e408a9e5fa.png">


###スナップショットの作成確認
 設定時刻から1時間以内に、スナップショットの作成が開始されます。
今回は`10:00 UTC`、つまり`19:00 UTC+9`に設定して、`19:37:35`に作成が始まりました。

<img width="770" alt="Screenshot_2018-09-04 EC2 Management Console(8).png" src="https://qiita-image-store.s3.amazonaws.com/0/105824/7d00ac2f-44db-2770-936d-5b32da3a14a1.png">


###タグの設定確認
一番下の一行が、ライフサイクル作成時に自分で追加したタグです。
上の二つはAmazon DLMがデフォルトで付与するタグのようです。
![Screenshot_2018-09-04 EC2 Management Console(9).png](https://qiita-image-store.s3.amazonaws.com/0/105824/f2ad208a-839d-beef-939e-fb0849e90c91.png)
###世代管理
12時間おきに作成する設定にしたので、12時間後に2つ目のスナップショットが作成されました。
保持する世代数を超えると、古い物から削除されていきます。
![Screenshot_2018-09-05 EC2 Management Console.png](https://qiita-image-store.s3.amazonaws.com/0/105824/af717a53-7f9d-44c1-7dbd-bde633512eec.png)

##awscli から操作してみる
awscli のバージョンは 1.15 以上でないと dlm のコマンドが使えないようですので、必要ならアップグレードしてくださいね。

```console
$ sudo pip install --upgrade awscli
$ aws --version
aws-cli/1.16.13 Python/2.7.14 Linux/4.14.51-60.38.amzn1.x86_64 botocore/1.12.3
```

###IAM Role 作成
`create-default-role` のコマンドで、必要な権限を持つ IAM Role が作成できます。

```json
$ aws dlm create-default-role
{
    "Role": {
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Action": "sts:AssumeRole",
                    "Sid": "",
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "dlm.amazonaws.com"
                    }
                }
            ]
        },
        "RoleId": "AROAIVPA53IGD4G2RKVLO",
        "CreateDate": "2018-09-13T01:32:18Z",
        "RoleName": "AWSDataLifecycleManagerDefaultRole",
        "Path": "/",
        "Arn": "arn:aws:iam::XXXXXXXXXX:role/AWSDataLifecycleManagerDefaultRole"
    },
    "RolePolicy": {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Action": [
                    "ec2:CreateSnapshot",
                    "ec2:DeleteSnapshot",
                    "ec2:DescribeVolumes",
                    "ec2:DescribeSnapshots"
                ],
                "Resource": "*",
                "Effect": "Allow"
            },
            {
                "Action": [
                    "ec2:CreateTags"
                ],
                "Resource": "arn:aws:ec2:*::snapshot/*",
                "Effect": "Allow"
            }
        ]
    }
}
```

###ポリシーの作成
`create-lifecycle-policy` のコマンドで、ライフサイクルポリシーの作成を行っていきます。
作成されると、`PolicyId` が返ってきます。

```console

$ aws dlm create-lifecycle-policy \
>     --description "My first policy" \
>     --state ENABLED \
>     --execution-role-arn arn:aws:iam::XXXXXXXXXX:role/AWSDataLifecycleManagerDefaultRole \
>     --policy-details '{
>         "ResourceTypes": ["VOLUME"],
>         "TargetTags": [{"Key": "dlm", "Value": "1"}],
>         "Schedules": [{"Name": "TestSchedule",
>         "TagsToAdd": [{"Key": "dlm-create","Value": "true"}],
>         "CreateRule": {"Interval": 12,"IntervalUnit": "HOURS","Times": ["10:00"]},
>         "RetainRule": {"Count":2}}]}'
{
    "PolicyId": "policy-0fe3b8a0341e3d336"
}
```
###ポリシーの確認
`get-lifecycle-policy` のコマンドで、設定内容の詳細が確認できます。
このコマンドは、`--policy-id` の指定が必須です。

```json
aws dlm get-lifecycle-policy --policy-id policy-0fe3b8a0341e3d336
{
    "Policy": {
        "Description": "My first policy",
        "DateCreated": "2018-09-13T04:49:16+0000",
        "State": "ENABLED",
        "ExecutionRoleArn": "arn:aws:iam::XXXXXXXXXX:role/AWSDataLifecycleManagerDefaultRole",
        "PolicyId": "policy-0fe3b8a0341e3d336",
        "DateModified": "2018-09-13T04:49:16+0000",
        "PolicyDetails": {
            "ResourceTypes": [
                "VOLUME"
            ],
            "TargetTags": [
                {
                    "Value": "1",
                    "Key": "dlm"
                }
            ],
            "Schedules": [
                {
                    "TagsToAdd": [
                        {
                            "Value": "true",
                            "Key": "dlm-create"
                        }
                    ],
                    "RetainRule": {
                        "Count": 2
                    },
                    "CreateRule": {
                        "Interval": 12,
                        "IntervalUnit": "HOURS",
                        "Times": [
                            "10:00"
                        ]
                    },
                    "Name": "TestSchedule"
                }
            ]
        }
    }
}
```

###ポリシーの確認（サマリー）
どんなライフサイクルポリシーがあったっけ？ っていうときは、`get-lifecycle-policies` のコマンドを使います。
（サマリーしか表示されないので、詳細は `get-lifecycle-policy` で確認する必要あり）
以下のパラメータで対象の絞り込みができます。

 - --policy-ids （複数指定可）
 - --state （設定できる値：ENABLED, DISABLED, ERROR）
 - --resource-types （複数指定可だけど、VOLUME しかない…）
 - --target-tags （複数指定可, key=value の形で指定する）
 - --tags-to-add （複数指定可, key=value の形で指定する）



```console
$ aws dlm get-lifecycle-policies --tags-to-add dlm-create=true
{
    "Policies": [
        {
            "State": "DISABLED",
            "PolicyId": "policy-034da8f90216c8692",
            "Description": "DLM test policy2"
        },
        {
            "State": "ENABLED",
            "PolicyId": "policy-004560e6568c92c97",
            "Description": "My first policy"
        }
    ]
}
```

###ポリシーの変更
`update-lifecycle-policy` のコマンドで、設定内容を変更できます。

```console
$ aws dlm update-lifecycle-policy \
>     --policy-id policy-0fe3b8a0341e3d336 \
>     --description 'DLM test policy' \
>     --state DISABLED \
>     --policy-details '{
>          "TargetTags": [{"Key": "dlm", "Value": "2"}],
>          "Schedules": [{"Name": "TestSchedule",
>          "TagsToAdd": [{"Key": "dlm-create","Value": "1"}],
>          "CreateRule": {"Interval": 24,"IntervalUnit": "HOURS","Times": ["10:00"]},
>          "RetainRule": {"Count":3}}]}'
```

`get-lifecycle-policy` のコマンドで変更されたか確認してみましょう。

```console
$ aws dlm get-lifecycle-policy --policy-id policy-0fe3b8a0341e3d336
{
    "Policy": {
        "Description": "DLM test policy",
        "DateCreated": "2018-09-13T04:49:16+0000",
        "State": "DISABLED",
        "ExecutionRoleArn": "arn:aws:iam::XXXXXXXXXX:role/AWSDataLifecycleManagerDefaultRole",
        "PolicyId": "policy-0fe3b8a0341e3d336",
        "DateModified": "2018-09-13T05:17:52+0000",
        "PolicyDetails": {
            "ResourceTypes": [
                "VOLUME"
            ],
            "TargetTags": [
                {
                    "Value": "2",
                    "Key": "dlm"
                }
            ],
            "Schedules": [
                {
                    "TagsToAdd": [
                        {
                            "Value": "1",
                            "Key": "dlm-create"
                        }
                    ],
                    "RetainRule": {
                        "Count": 3
                    },
                    "CreateRule": {
                        "Interval": 24,
                        "IntervalUnit": "HOURS",
                        "Times": [
                            "10:00"
                        ]
                    },
                    "Name": "TestSchedule"
                }
            ]
        }
    }
}
```
次は `TagsToAdd` の値だけを変更してみます。
変更したい部分だけ記述すればいいよね、と思ったら、、エラーになりました。

```
$ aws dlm update-lifecycle-policy \
>     --policy-id policy-034da8f90216c8692 \
>     --policy-details '{"Schedules": [{
            "TagsToAdd": [{"Key": "dlm-create","Value": "true"}]}]}'
An error occurred (InvalidRequestException) when calling the UpdateLifecyclePolicy operation: The following required parameter(s) are missing: {Name}
```
以下なら通りました。"Schedules" の中では、"Name", "CreateRule", "RetainRule" は必須みたいです。

```console
$ aws dlm update-lifecycle-policy \
     --policy-id policy-034da8f90216c8692 \
     --policy-details '{"Schedules": [{
            "Name": "Test Schedule2",
            "TagsToAdd": [{"Key": "dlm-create","Value": "true"}],
            "CreateRule": {"Interval": 12,"IntervalUnit": "HOURS","Times": ["10:00"]},
            "RetainRule": {"Count":7}}]}'
```

###ポリシーの削除
`delete-lifecycle-policy` のコマンドで、ライフサイクルポリシーの削除ができます。

```console
$ aws dlm delete-lifecycle-policy --policy-id policy-0fe3b8a0341e3d336
```

##まとめ
コンソール上や awscli から簡単にスナップショットの作成と世代管理等のルール設定が行えました。cronで設定するよりもずっと楽ですね。制限事項に問題がなければ、十分使えそうです！