Amazon Elasticsearch Serviceで取得したS3上の手動スナップショットをEC2上のElasticsearchに復元する

概要
-

Amazon Elasticsearch Serviceで取得したS3上の手動スナップショットを、とある検証のためEC2上に作成したElasticsearchに復元した際の記録です。

Amazon Elasticsearch Serviceに対しての手動スナップショット操作方法は以下が参考になりました。
https://dev.classmethod.jp/cloud/restore-from-amazon-es-manual-snapshot-ja/

環境については、
ap-northeast-1（東京リージョン）
Amazon Elasticsearch Service 5.5
Amazon Linux 2（ami-0d7ed3ddb85b521a6）
Elasticsearch 5.5.2
を使いました。
スナップショットを保管するS3バケットは本記事では es-example-snapshot という名前にしています。（実際に検証する場合は別名で読み替えてください）

Amazon Elasticsearch Serviceでの手動スナップショット
-

基本的には上記参考先の手順通り進めていく感じですが、１点だけ補足としてS3アクセスのためのIAMポリシーはElasticsearchドキュメントにあった推奨の内容にしてみました。
https://www.elastic.co/guide/en/elasticsearch/plugins/current/repository-s3-repository.html#repository-s3-permissions
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/mpuAndPermissions.html

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "s3:ListBucket",
        "s3:GetBucketLocation",
        "s3:ListBucketMultipartUploads",
        "s3:ListBucketVersions"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::es-example-snapshot"
      ]
    },
    {
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject",
        "s3:AbortMultipartUpload",
        "s3:ListMultipartUploadParts"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::es-example-snapshot/*"
      ]
    }
  ]
}
```

手動スナップショットが以下のように取れているとします。（上記、手動スナップショット操作方法リンク先を参考に）

```shell
$ curl -sS "https://example.ap-northeast-1.es.amazonaws.com/_snapshot/es-example-snapshot/_all?pretty"
{
  "snapshots" : [ {
    "snapshot" : "my-snapshot-20190206-1",
    "uuid" : "kQAztH78pqRyz9J363Ayz5",
    "version_id" : 6060211,
    "version" : "5.5.2",
    "indices" : [ ".kibana", "sample_20190205" ],
    "state" : "SUCCESS",
    "start_time" : "2019-02-06T05:41:12.401Z",
    "start_time_in_millis" : 1549431672401,
    "end_time" : "2019-02-06T06:04:12.065Z",
    "end_time_in_millis" : 1549433052065,
    "duration_in_millis" : 1379664,
    "failures" : [ ],
    "shards" : {
      "total" : 8,
      "failed" : 0,
      "successful" : 8
    }
  } ]
}
```

EC2のElasticsearch準備
-

Elasticsearchのインストールは公式から該当バージョンのrpmパッケージをダウンロードしてインストール、起動させています。
https://www.elastic.co/downloads/past-releases

またEC2には上記IAMポリシーを付与したRoleをくっ付けておきます。

```shell
$ curl -sS "http://localhost:9200/"
{
  "name" : "4sICf-8",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "WxG9lFAcRpOYrSeVkMhi0Q",
  "version" : {
    "number" : "5.5.2",
    "build_hash" : "b2f0c09",
    "build_date" : "2017-08-14T12:33:14.154Z",
    "build_snapshot" : false,
    "lucene_version" : "6.6.0"
  },
  "tagline" : "You Know, for Search"
}
```

S3 Repository Pluginの準備
-

これも公式の以下ドキュメントを元にS3のスナップショットにアクセスするためのプラグインをインストールします。
https://www.elastic.co/guide/en/elasticsearch/plugins/current/repository-s3.html

その他、スナップショット元で使っていた必要なプラグインがあったら合わせてインストールしておきます。
https://www.elastic.co/guide/en/elasticsearch/plugins/current/analysis-kuromoji.html

```shell
$ sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install repository-s3
$ sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install analysis-kuromoji
# プラグイン読み込ませ
$ sudo systemctl restart elasticsearch.service
```

スナップショットS3バケットと連携登録をする。 

```shell
$ curl -sS -H 'Content-Type: application/json' -X PUT "http://localhost:9200/_snapshot/es-example-snapshot"  -d '
{
  "type": "s3",
  "settings": {
    "bucket": "es-example-snapshot"
  }
}'
```

対象スナップショットを確認すると、Amazon Elasticsearch Serviceに対して取得していたスナップショットが見えます。

```shell
$ curl -sS "http://localhost:9200/_snapshot/es-example-snapshot/_all?pretty"
{
  "snapshots" : [
    {
      "snapshot" : "my-snapshot-20190206-1",
      "uuid" : "kQAztH78pqRyz9J363Ayz5",
      "version_id" : 6060211,
      "version" : "5.5.2",
      "indices" : [
        ".kibana",
        "sample_20190205"
      ],
      "state" : "SUCCESS",
      "start_time" : "2019-02-06T05:41:12.401Z",
      "start_time_in_millis" : 1549431672401,
      "end_time" : "2019-02-06T06:04:12.065Z",
      "end_time_in_millis" : 1549433052065,
      "duration_in_millis" : 1379664,
      "failures" : [ ],
      "shards" : {
        "total" : 8,
        "failed" : 0,
        "successful" : 8
      }
    }
  ]
}
```

リカバリー実行
-

EC2にS3と通信するためのIAM Roleが関連付いているので、そのままcurlでリクエストを送り込めます。

```shell
$ curl -sS -H 'Content-Type: application/json' -X POST "http://localhost:9200/_snapshot/es-example-snapshot/my-snapshot-20190206-1/_restore" -d '
{
  "indices": "sample_20190205"
}'
```

進捗見たい場合は以下などでshards情報を見ると復元状況分かります。

```shell
$ curl -sS "http://localhost:9200/_cat/shards?v"
```

補足: S3バケットとの登録を解除する方法
-

S3バケットとの連携を解除するのは、どうすればいいのか公式情報はどこだろうと思って探してみたところ以下にありました。
https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html#_snapshot

```plaintext
A repository can be unregistered using the following command:

DELETE /_snapshot/my_backup

When a repository is unregistered, Elasticsearch only removes the reference to
the location where the repository is storing the snapshots.
The snapshots themselves are left untouched and in place.
```

このようなコマンドになるかと思います。

```shell
$ curl -sS -X DELETE "http://localhost:9200/_snapshot/es-example-snapshot"
```