Amazon Elasticsearch Serviceの構成要素を確認し、AWS CLIでクラスタを一発構築する

2016.07.28

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

弊社秋葉原佐久間町オフィス周辺では『ポケモン GO』に於いてコイキングがエラい多い割合で捕獲出来ています。川沿いに場所を構えているという側面もあるかと思いますが、社内では専ら、生魚好きの某有力者の(魚類を)引き寄せる力によるものなのでは、と専らの噂になっています。

という訳で本題です。Amazon Elasticsearch Serviceについては弊社でも利用ケース・頻度が増えており度々ブログでも採り上げる機会が増えていますが、私もちょろっと触ってみようかなと思いました。その中で、AWS CLIによる構築手順、内容に言及しているものがあまり無さそうだったので、どんな構成要素・設定で作られているものなんだろう?という部分を理解する為に一度管理コンソールでクラスタを作成し、その上でAWS CLIでの作成を試してみようと思いました。当エントリではその内容紹介となります。

もくじ

Amazon Elasticsearch Serviceクラスタを管理コンソール経由で起動する

まずは基本の形、管理コンソール経由でクラスタを立ち上げてみる事でElasticsearchクラスタを構成する為の要素の確認を行って見たいと思います。管理コンソールにログイン後、[Get Started]を押下。

ecc-create-by-console_01

ドメイン名(Domain Name)&APIバージョン(API Version)

Elasticsearchクラスタのドメイン名を定めます。ドメイン名はエンドポイントの一部として利用されます。

また、このエントリを書いている最中に下記リリースが為された模様で、APIバージョンの選択も行える様になりました。既存バージョンは1.5となりますので、とりあえずこの部分については1.5を選択します。

ess-create-by-console_09

クラスタ設定

次いでElasticsearchドメインにおけるクラスタの設定について見て行きたいと思います。

ノード設定:インスタンス数(Instance count)

Elasticsearchドメインを構成するクラスタのインスタンス数を整数値で設定します。動作確認用なのでここはデフォルト値の1でも構わないかな...と思いましたが、後述の"Enable dedicated master"の指摘事項に倣い、ここは3を設定してみたいと思います。

ノード設定:インスタンスタイプ(Instance type)

Elasticsearchドメインを構成するクラスタのインスタンスタイプを所定の一覧から選択します。デフォルト値はm3.medium.elasticsearchですが、そこまで良い性能で無くても(動作確認用のため)構わないのでここは一番安いt2.micro.elasticsearchを選択しました。

次のチェックボックス2つ、『Enable dedicated master』と『Enable zone awareness』については以下の様な意味を持つものとなります。本番環境であれば共にチェックを入れておいた方が良さそうです。

Enable dedicated masterのチェックを入れると、Amazon ESはクラスタ管理用に独立したmasterノードを構築します。masterノードはドキュメントデータを保持せず、クラスタの管理に専念します。クラスタのスタビリティを高めるため、最低3つのmasterノードを指定することを推奨しています。また、スプリットブレインのシナリオを避けるために、masterノード数には常に奇数の値を設定しましょう。Enable zone awarenessのチェックを入れると、Amazon ESは可用性の向上のため、リージョン内の複数のアベイラビリティゾーンにノードを分散します。こちらを選択する場合、ElasticsearchのIndex APIでレプリカのセットアップをする必要があります。また、新しいインデックスを構築する際は同じAPIを用いることが可能です(詳細はこちら)。

で、共にチェックを入れると以下の様に新たな選択項目が増えて来ます。条件を満たすように値を調整し、結果以下の様な設定となりました。インスタンス数は結果として増えてしまいましたが、ここではインスタンスタイプを最小性能のt2.micro.elasticsearchとしています。

ess-create-by-console_03

ストレージ設定(Storage Configuration)

次いでストレージタイプの設定です。選択肢としては『Instance』と『EBS』が選べる様ですが、上記選択内容だとEBS一択となるようです。なのでここはEBSを選択。併せてボリュームタイプ、サイズも設定を行います。(ここはデフォルト値としました)

ess-create-by-console_06

スナップショット設定(Snapshot Configuration)

スナップショットは日に1回、システムの方で取得を行う形となります。クラスタの活動が忙しくない時に設定を行うのが良い、と記述されていますね。ここも任意の値を選択します。ここではデフォルト値の『00:00 UTC』から少し遅らせて03:00 UTCとしました。

ess-create-by-console_04

詳細設定(Advanced Options)

詳細設定については以下ブログエントリ及びElasticの公式ヘルプをご参照ください。値はデフォルト設定のままとしました。

ess-create-by-console_05

アクセスポリシー設定

次に、アクセスポリシーに関する設定を行います。ここは色々な制御が出来る形となりますが、ひとまずは下記エントリに倣い『所定IPからのアクセスのみ許可する』ポリシーをテンプレートから作成し、活用する形としました。

ess-create-by-console_08

Elasticsearchクラスタの作成

内容を確認し、[Confirm and Create]をクリック。

ess-create-by-console_10

作成が始まりました。作成には10分程時間が掛かるとの事なので軽く休憩。

ess-create-by-console_11

暫くの後、以下の様な形でElasticsearchクラスタが起動しました。

ess-create-by-console_12_2

Amazon Elasticsearch ServiceクラスタをAWS CLI経由で起動する

ここからが当エントリの本題。上記作業をAWS CLIを使い、一発で構築するための手順を整えていきたいと思います。まずはAWS CLIを最新バージョンにアップデート。

$ sudo pip install --upgrade awscli
$ aws --version
aws-cli/1.10.50 Python/2.7.10 Darwin/14.5.0 botocore/1.4.40

Elasticsearch Serviceについてはaws esというコマンドで各種操作を行う事が出来ます。

$ aws es help
NAME
       es -

DESCRIPTION
       Use  the  Amazon  Elasticsearch configuration API to create, configure,
       and manage Elasticsearch domains.

       The endpoint for configuration  service  requests  is  region-specific:
       es.*region*  .amazonaws.com.  For  example, es.us-east-1.amazonaws.com.
       For a current list of supported regions and endpoints, see Regions  and
       Endpoints .

AVAILABLE COMMANDS
       o add-tags
       o create-elasticsearch-domain
       o delete-elasticsearch-domain
       o describe-elasticsearch-domain
       o describe-elasticsearch-domain-config
       o describe-elasticsearch-domains
       o help
       o list-domain-names
       o list-tags
       o remove-tags
       o update-elasticsearch-domain-config

                                                                          ES()

クラスタの作成はcreate-elasticsearch-domainというコマンドで実施する形となります。今回このコマンドで処理を行う為のパラメータファイル(json)を作り、そのパラメータファイルに値を設定、実行時にそのファイルを指定する...という形で行ってみます。まずは雛形ファイルを--generate-cli-skeletonオプションを付けて生成します。

$ aws es create-elasticsearch-domain --generate-cli-skeleton > create-es-domain.json
$ cat ./create-es-domain.json 
{
    "DomainName": "", 
    "ElasticsearchClusterConfig": {
        "InstanceType": "", 
        "InstanceCount": 0, 
        "DedicatedMasterEnabled": true, 
        "ZoneAwarenessEnabled": true, 
        "DedicatedMasterType": "", 
        "DedicatedMasterCount": 0
    }, 
    "EBSOptions": {
        "EBSEnabled": true, 
        "VolumeType": "", 
        "VolumeSize": 0, 
        "Iops": 0
    }, 
    "AccessPolicies": "", 
    "SnapshotOptions": {
        "AutomatedSnapshotStartHour": 0
    }, 
    "AdvancedOptions": {
        "KeyName": ""
    }
}

設定内容を参照する為に、describe-elasticsearch-domainコマンドで上記手順にて作成したクラスタを参照してみます。

$ aws es describe-elasticsearch-domain --domain-name cm-ess
{
    "DomainStatus": {
        "ElasticsearchClusterConfig": {
            "DedicatedMasterEnabled": true, 
            "InstanceCount": 4, 
            "ZoneAwarenessEnabled": true, 
            "DedicatedMasterType": "t2.micro.elasticsearch", 
            "InstanceType": "t2.micro.elasticsearch", 
            "DedicatedMasterCount": 3
        }, 
        "Endpoint": "search-cm-ess-xxxxxxxxxxxxxxxxxxxxxxxxxx.us-east-1.es.amazonaws.com", 
        "Created": true, 
        "Deleted": false, 
        "DomainName": "cm-ess", 
        "EBSOptions": {
            "Iops": 0, 
            "VolumeSize": 10, 
            "VolumeType": "gp2", 
            "EBSEnabled": true
        }, 
        "SnapshotOptions": {
            "AutomatedSnapshotStartHour": 3
        }, 
        "DomainId": "XXXXXXXXXXXX/cm-ess", 
        "AccessPolicies": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"*\"},\"Action\":\"es:*\",\"Resource\":\"arn:aws:es:us-east-1:XXXXXXXXXXXX:domain/cm-ess/*\",\"Condition\":{\"IpAddress\":{\"aws:SourceIp\":\"YYY.YY.YYY.YY\"}}}]}", 
        "Processing": false, 
        "AdvancedOptions": {
            "rest.action.multi.allow_explicit_index": "true", 
            "indices.fielddata.cache.size": ""
        }, 
        "ARN": "arn:aws:es:us-east-1:XXXXXXXXXXXX:domain/cm-ess"
    }
}

概ね値はそのまま転記する形でベースは作成出来そうです。ただ1点、AccessPoliciesについては設定が面倒臭そう。ここについては、管理コンソールでポリシーを確認しておき、その内容を一旦ファイルに保存。保存したファイルをjqコマンド等を用いて内容を加工し(下記23行目)、得られた値(下記24行目)をコピペしてJSONファイルの該当箇所に設定するのが一番楽そうです。

$ vi cm-ess-access-policy.json
$ cat cm-ess-access-policy.json 
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "es:*",
      "Resource": "arn:aws:es:us-east-1:XXXXXXXXXXXX:domain/cm-ess/*",
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": "YY.YYY.YY.YYY"
        }
      }
    }
  ]
}

$ cat cm-ess-access-policy.json | jq --raw-input --slurp '.' | sed -e 's/\\n//g' | sed -e 's/ //g'
"{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"*\"},\"Action\":\"es:*\",\"Resource\":\"arn:aws:es:us-east-1:XXXXXXXXXXXX:domain/cm-ess/*\",\"Condition\":{\"IpAddress\":{\"aws:SourceIp\":\"YY.YYY.YY.YYY\"}}}]}"

上記内容を踏まえて作成したパラメータjsonファイルが以下となります。AWSアカウントIDの部分は該当する情報を、またその後ろにあるドメイン名はDomainName属性の値が入る形となりますのでご注意ください。

create-es-domain-by-awscli.json

{
    "DomainName": "cm-ess-by-awscli", 
    "ElasticsearchClusterConfig": {
        "InstanceType": "t2.micro.elasticsearch", 
        "InstanceCount": 4, 
        "DedicatedMasterEnabled": true, 
        "ZoneAwarenessEnabled": true, 
        "DedicatedMasterType": "t2.micro.elasticsearch", 
        "DedicatedMasterCount": 3
    }, 
    "EBSOptions": {
        "EBSEnabled": true, 
        "VolumeType": "gp2", 
        "VolumeSize": 10, 
        "Iops": 0
    }, 
    "AccessPolicies": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"*\"},\"Action\":\"es:*\",\"Resource\":\"arn:aws:es:us-east-1:XXXXXXXXXXXX:domain/cm-ess-by-awscli/*\",\"Condition\":{\"IpAddress\":{\"aws:SourceIp\":\"YY.YYY.YY.YYY\"}}}]}", 
    "SnapshotOptions": {
        "AutomatedSnapshotStartHour": 3
    }, 
    "AdvancedOptions": {
        "rest.action.multi.allow_explicit_index": "true", 
        "indices.fielddata.cache.size": ""
    }
}

AWS CLIコマンドによる作成処理実行。パラメータファイルは--cli-input-jsonオプションで指定します。

$ aws es create-elasticsearch-domain --cli-input-json file:///xxx/xxx/xxx/create-es-domain-by-awscli.json
{
    "DomainStatus": {
        "ElasticsearchClusterConfig": {
            "DedicatedMasterEnabled": true, 
            "InstanceCount": 4, 
            "ZoneAwarenessEnabled": true, 
            "DedicatedMasterType": "t2.micro.elasticsearch", 
            "InstanceType": "t2.micro.elasticsearch", 
            "DedicatedMasterCount": 3
        }, 
        "DomainId": "XXXXXXXXXXXX/cm-ess-by-awscli", 
        "Created": true, 
        "Deleted": false, 
        "EBSOptions": {
            "Iops": 0, 
            "VolumeSize": 10, 
            "VolumeType": "gp2", 
            "EBSEnabled": true
        }, 
        "Processing": true, 
        "DomainName": "cm-ess-by-awscli", 
        "SnapshotOptions": {
            "AutomatedSnapshotStartHour": 3
        }, 
        "AccessPolicies": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"*\"},\"Action\":\"es:*\",\"Resource\":\"arn:aws:es:us-east-1:XXXXXXXXXXXX:domain/cm-ess-by-awscli/*\",\"Condition\":{\"IpAddress\":{\"aws:SourceIp\":\"YYY.YY.YYY.YY\"}}}]}", 
        "AdvancedOptions": {
            "rest.action.multi.allow_explicit_index": "true", 
            "indices.fielddata.cache.size": ""
        }, 
        "ARN": "arn:aws:es:us-east-1:XXXXXXXXXXXX:domain/cm-ess-by-awscli"
    }
}

そして暫く時間を置いた後、Elasticsearchクラスタが作成されている事を確認出来ました。

ess-create-by-awscli_01

まとめ

Elasticsearch Serviceに関するクラスタ作成方法、管理コンソール経由とAWS CLI経由による手順についてご紹介した内容となりましたが、殊の外AWS CLIでもそんなに複雑な指定をする事無く作成出来ました。AWS CLI同様にCloudFormationでも作成の為のテンプレートが用意されていますので、用途状況に応じて使い分けてみてはいかがでしょうか。こちらからは以上です。