LoginSignup
3
4

More than 3 years have passed since last update.

Amazon Elasticsearch Service とlambda(Python3) を一瞬で疎通するメモ

Last updated at Posted at 2017-11-28

Amazon Elasticsearch Serviceと Lambda(Python3)を一瞬で疎通するメモ

要件

  • AWS Lambdaと AWS Elasticsearch Serviceの連携ができること
  • ローカルPCで下記が出来ること
    • curlで Elasticsearch Serviceに接続可能
    • kibanaを利用可能
    • python-lambda-localで Lambdaを実行し、Elasticsearch Serviceに接続可能

Elasticsearch Serviceアクセスポリシー設定

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "es:*",
      "Resource": "arn:aws:es:ap-northeast-1:[アカウントID]:domain/[ESドメイン]/*",
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": [
            "[アクセス元IPアドレス]"
          ]
        }
      }
    },
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::[アカウントID]:user/[ユーザ]"
      },
      "Action": "es:ESHttpGet",
      "Resource": "arn:aws:es:ap-northeast-1:[アカウントID]:domain/[ESドメイン]/*"
    }
  ]
}
  • Elasticsearch Serviceのドメインを最小構成で起動しておく
  • 下記ポリシーを持った IAMユーザを作成
    • AWSLambdaFullAccess
    • AmazonESFullAccess

Elasticsearch Service動作確認

  • ローカルPCから curlでの接続
$ curl -XGET https://xxxx.ap-northeast-1.es.amazonaws.com/_aliases
# {".kibana":{"aliases":{}}}
  • kibanaはブラウザでいい感じに動くことを確認する

Lambda実装サンプル

※botocoreを使用したサンプルは、EC2バージョンアップなどにより動かなくなる(なった)ため修正

pip3 install requests -t./

requestパッケージを AmazonLinuxの EC2でダウンロード

pip3 install requests-aws4auth -t./
# 依存関係で python-request 他もダウンロードされる

※requests_aws4auth, requests, bin, certifi, chardet, idna, requests, urllib3 を scpなどで手元に持ってくるか、任意の S3バケットにアップロードする

import boto3
import json
import requests
from requests_aws4auth import AWS4Auth

def handler(event, context):
    url = "https://****-****.ap-northeast-1.es.amazonaws.com/_search"
    credentials = boto3.Session().get_credentials()
    awsauth = AWS4Auth(credentials.access_key, credentials.secret_key, 'ap-northeast-1', 'es', session_token=credentials.token)

    query = {"size": 1}
    response = requests.get(url, auth=awsauth, headers={"Content-Type": "application/json"}, data=json.dumps(query))

    return json.loads(response.text)

※初回は「アクション->関数のエクスポート->デプロイパッケージのダウンロード」で lambda_function.pyファイルをダウンロードし、先程ダウンロードした requestsパッケージにコピーしてzipファイルに圧縮、「コード エントリ タイプ->.zipファイルをアップロード」で展開すると楽

  • 下記ポリシーを持った IAMロールを作成
    • AmazonESFullAccess
  • Lambda環境変数に設定
    • ES_ENDPOINT_URL
    • AWS_ACCESS_KEY_ID
    • AWS_SECRET_ACCESS_KEY
    • AWS_SESSION_TOKEN
  • Python以外だと署名バージョン4 の実装が若干面倒かも

Lambda動作確認

  • AWSデベロッパーコンソールに Lambdaソースを貼り付けてテスト
{
  ".kibana": {
    "aliases": {}
  }
}
  • ローカルPCから python-lambda-localで実行
$ export ES_ENDPOINT_URL=https://xxxx.ap-northeast-1.es.amazonaws.com
$ echo "{}" > event.json
$ python-lambda-local -f handler index.py event.json
# [root - INFO - 2017-11-xx xx:xx:xx,xxx] Event: {}
# [root - INFO - 2017-11-xx xx:xx:xx,xxx] START RequestId: xxxx
# [botocore.vendored.requests.packages.urllib3.connectionpool - INFO - 2017-11-xx xx:xx:xx,xxx] Starting new HTTPS connection (1): xxxx.ap-northeast-1.es.amazonaws.com
# [root - INFO - 2017-11-xx xx:xx:xx,xxx] END RequestId: xxxx
# [root - INFO - 2017-11-xx xx:xx:xx,xxx] RESULT:
# {'.kibana': {'aliases': {}}}
# [root - INFO - 2017-11-xx xx:xx:xx,xxx] REPORT RequestId: xxxx    Duration: 383.92 ms
  • ここまでやったら Lambda関数をエクスポートして 以後は CloudFormationでデプロイするとあとあとよい
  • ElasticSearchは忘れず止めておく😇

参考リンク

3
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4