Amazon DLMの挙動

[Amazon Data Lifecycle Manager (Amazon DLM) を（自分でも）やってみた。](https://qiita.com/bee3/items/aac79410de48eb5f118f) の方の記事を見て、
~~そういえば本番でバックアップ取ってないサービスあったっけと思って、~~実際に触ってみた。
その際にどんな流れで動くのか気になってCloudTrailを覗いてみたのでメモ。

~~※記事主さんリンクだめであればぼかしますので後ほどご連絡ください。~~
OK出ました。@bee3 さんありがとうございます。

## CloudTrail

https://aws.amazon.com/jp/cloudtrail/
AWSのAPIベースでのアクティビティを記録するサービス。
証跡管理とかが主な使い方の気がするが、今回はこれを用いてどういう手順で処理されているのかを追ってみた。
なお、DLMによる自動バックアップの操作は user = `DataLifecycleManager` で検索追跡できる。


## Lifecycle Manager

詳細は他記事にお任せしますが、EBSのスナップショット作成の自動化 + 世代管理の自動化をしてくれるサービス。
処理対象のEBSに管理タグ貼ってタグベースで操作するらしい。

今回使用のポリシーは以下の通り
※見せられない部分はぼかします

| 項目 | 設定値 | |
| ---- | ---- | ---- |
| Schedule name | Default Schedule | スケジュール名 |
| Target voilumes with tags | auto-backup : dlm | 処理対象とするEBSに付与したタグを指定、複数可能(ここでは仮にしてます) |
| Create snapshots every | 24 | 1日単位でスナップショットを作成 |
| Snapshot creation start time | 17:00 | UTCで起点の時刻を設定(午前2時) |
| Retension rule | 3 | 3回分スナップショットを保存、これと Create snapshots every の間隔で何日分かが決まる |
| Tag created snapshots | ss-lifecycle : true | 後でスナップショットに細工したかったのでフラグになるタグを用意 |
| IAM role | Default role |  |

Default role は初回指定時に `AWSDataLifecycleManagerDefaultRole` という必要な権限を持つロールを作成する。


## 自動バックアップの動作

以下がアクティビティとそれに対する私見で。
イベント情報は必要な情報の抜粋です。
※ツッコミ大歓迎です。

というかサーバーレスのマネージドサービスって既存のAPIゴニョゴニョで実現するんですね(ちょっと感動)

### DescribeVolumes(filter - tag)

まずは対象のタグがついたボリューム一覧をまるっと拾っています。

```json
{
  "eventName": "DescribeVolumes",
  "requestParameters": {
    "maxResults": 100,
    "volumeSet": {},
    "filterSet": {
      "items": [
        {
          "name": "auto-backup",
          "valueSet": {
            "items": [
              {
                "value": "dlm"
              }
            ]
          }
        }
      ]
    }
  }
}
```

### CreateSnapshot(volumeId指定)

取得したボリュームに対してスナップショットを作成しています。
その際にタグに設定時に追加指定したタグと以下のタグを追加しています。

```json
{
  "eventName": "DescribeSnapshots",
  "requestParameters": {
    "volumeId": "vol-******",
    "description": "Created for policy: policy-******* schedule: Default Schedule",
    "tagSpecificationSet": {
      "items": [
        {
          "resourceType": "snapshot",
          "tags": [
            {
              "key": "ss-lifecycle",
              "value": "true"
            },
            {
              "key": "aws:dlm:lifecycle-policy-id",
              "value": "policy-*******"
            },
            {
              "key": "aws:dlm:lifecycle-schedule-name",
              "value": "Default Schedule"
            }
          ]
        }
      ]
    }
  },
  "responseElements": {
    "snapshotId": "snap-*******",
    "volumeId": "vol-*******",
    "status": "pending",
    "volumeSize": "100",
    "encrypted": false,
    "description": "Created for policy: policy--******* schedule: Default Schedule",
    "tagSet": {
      "items": [
        {
          "key": "aws:dlm:lifecycle-schedule-name",
          "value": "Default Schedule"
        },
        {
          "key": "ss-lifecycle",
          "value": "true"
        },
        {
          "key": "aws:dlm:lifecycle-policy-id",
          "value": "policy--*******"
        }
      ]
    }
  },
  "eventType": "AwsApiCall"
}
```

| タグ名 | タグ値 |
| ---- | ---- |
| `aws:dlm:lifecycle-policy-id` | DLMのポリシーのID |
| `aws:dlm:lifecycle-schedule-name` | DLMのポリシーに設定したスケジュール名 |


### DescribeSnapshots(snapshotId指定)

`CreateSnapshot` の直後(1秒後)と15秒後、25秒後、その後は40秒～1分間隔でこれが実行されている。
おそらく `status = completed` になるのを待っているのかなと思われる。

```json
{
  "eventVersion": "1.05",
  "eventName": "DescribeSnapshots",
  "requestParameters": {
    "snapshotSet": {
      "items": [
        {
          "snapshotId": "snap-09a3b37a478159c0f"
        }
      ]
    },
    "ownersSet": {},
    "sharedUsersSet": {},
    "filterSet": {}
  }
}
```


### DescribeSnapshots(filter - tags)

一個前の `DescribeSnapshots` の最後とほぼ同時刻で叩かれている。
ボリュームIDとポリシーID指定の `status = completed` のスナップショット全件、削除対象を検索していると思われる。
※条件が何やら不穏な気がするが後でコメントします。

```json
{
  "eventVersion": "1.05",
  "eventName": "DescribeSnapshots",
  "requestParameters": {
    "snapshotSet": {},
    "ownersSet": {},
    "sharedUsersSet": {},
    "filterSet": {
      "items": [
        {
          "name": "volume-id",
          "valueSet": {
            "items": [
              {
                "value": "vol-*******"
              }
            ]
          }
        },
        {
          "name": "description",
          "valueSet": {
            "items": [
              {
                "value": "Created for policy: policy-******* schedule: Default Schedule"
              }
            ]
          }
        },
        {
          "name": "status",
          "valueSet": {
            "items": [
              {
                "value": "completed"
              }
            ]
          }
        }
      ]
    }
  },
}
```

### DeleteSnapshot(snapshotId)

一つ前の検索で既定件数からあふれたスナップショットの削除。

```json
{
  "eventName": "DeleteSnapshot",
  "requestParameters": {
    "snapshotId": "snap-*******",
    "force": false
  },
  "responseElements": {
    "requestId": "*******",
    "_return": true
  },
}
```

## 気になったところ

### 削除対象スナップショットの検索条件

`DescribeSnapshots` のフィルターに以下の内容が含まれている。

```json
"filterSet": {
  "items": [
    {
      "name": "description",
      "valueSet": {
        "items": [
          {
            "value": "Created for policy: policy-******* schedule: Default Schedule"
          }
        ]
      }
    }
  }
}
```

このdescriptionは `CreateSnapshot` で記述しているが、スケジュール名を含むものになっているので、
途中でスケジュール名を変更すると多分ローテーション対象外になる。
`aws:dlm:lifecycle-policy-id` で検索したほうが素直な気がしたのだけど、スケジュール名変えることで
恒久的にバックアップを残したいケースが出てくるということ？(それなら手動で取った方が早いような。。。)
この辺も詳しい方いたらコメントくださいm(_ _)m


## 最後に

さらっと設定できてさらっと安全にスナップショットを管理できるDLM便利でした(*´艸｀*)