LoginSignup
4

More than 3 years have passed since last update.

posted at

updated at

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

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は忘れず止めておく😇

参考リンク

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
What you can do with signing up
4