[PYTHON] Envoyer une demande d'AWS Lambda à Amazon Elasticsearch Service

Amazon Elasticsearch Service est Elasticsearch. Vous pouvez utiliser normalement le point de terminaison comme recherche élastique et choisir l'une des stratégies d'accès suivantes.

Au fait, j'ai pensé à une demande de Lambda basée sur IAM pour analyser légèrement le fichier placé dans S3 pour un peu de commodité et le placer dans Elasticsearch, mais pour le moment, il semble que je fasse ma propre demande de signature et la jette.

résultat. Je l'ai essayé, mais il semble maintenant plus facile de le diffuser dans le flux CloudWatch Logs, puis d'utiliser les fonctions prédéfinies. Si la ressource boto3 est implémentée pour ES, il semble qu'il n'y aura aucun problème.

Cela a fonctionné pour le moment, alors prenez note du code.

Politique côté domaine d'Elasticsearch

--Autoriser les rôles appliqués à Lambda dans le modèle IAM --ʻEs: * , ʻes: ESHttpGet, etc.

Fonction Lambda

Mis à part EventSource, envoyez simplement un GET à l'ES / pour le moment. Les documents suivants ont été utiles.

Principalement le code pour créer l'en-tête. .. ..

function.py


import urllib2, datetime, os, sys
import hashlib, hmac

endpoint = 'search-sandbox01-xxxxxxxxxxxxxxxxxxxx.ap-northeast-1.es.amazonaws.com'
url = "https://" + endpoint
region = 'ap-northeast-1'
service = 'es'
method = 'GET'

access_key = os.environ.get('AWS_ACCESS_KEY_ID')
secret_key = os.environ.get('AWS_SECRET_ACCESS_KEY')
if access_key is None or secret_key is None:
    print 'No access key is available.'
    sys.exit()

def sign(key, msg):
    return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest()

def getSignatureKey(key, dateStamp, regionName, serviceName):
    kDate = sign(('AWS4' + key).encode('utf-8'), dateStamp)
    kRegion = sign(kDate, regionName)
    kService = sign(kRegion, serviceName)
    kSigning = sign(kService, 'aws4_request')
    return kSigning


def lambda_handler(event, context):
    t = datetime.datetime.utcnow()
    amzdate = t.strftime('%Y%m%dT%H%M%SZ')
    datestamp = t.strftime('%Y%m%d') # Date w/o time, used in credential scope
    
    canonical_uri = '/'
    canonical_querystring = ""
    canonical_headers = 'host:' + endpoint + '\n' + 'x-amz-date:' + amzdate + '\n'
    signed_headers = 'host;x-amz-date'
    payload_hash = hashlib.sha256('').hexdigest()
    canonical_request = method + '\n' + canonical_uri + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + signed_headers + '\n' + payload_hash
    
    algorithm = 'AWS4-HMAC-SHA256'
    credential_scope = datestamp + '/' + region + '/' + service + '/' + 'aws4_request'
    string_to_sign = algorithm + '\n' +  amzdate + '\n' +  credential_scope + '\n' +  hashlib.sha256(canonical_request).hexdigest()
    
    signing_key = getSignatureKey(secret_key, datestamp, region, service)
    signature = hmac.new(signing_key, (string_to_sign).encode('utf-8'), hashlib.sha256).hexdigest()
    
    authorization_header = algorithm + ' ' + 'Credential=' + access_key + '/' + credential_scope + ', ' +  'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + signature
    
    headers = {
          'Content-Type': 'application/json',
                'Host': endpoint,
                'X-Amz-Security-Token': os.environ.get('AWS_SESSION_TOKEN'),
                'X-Amz-Date': amzdate,
                'Authorization': authorization_header
    }
    
    req = urllib2.Request(url, None, headers)
    
    try:
        print urllib2.urlopen(req).read()
    except urllib2.URLError, e:
        print e.read()

Est-il possible de créer cet en-tête rapidement en utilisant le module botocore? En réfléchissant.

Addendum: Cliquez ici pour un exemple de "Faites-le rapidement en utilisant le module botocore". [Small story] Utilisez uniquement le processus de signature de la demande d'API AWS de botocore | Developers.IO

You Know, for Search

Lorsque j'essaye de boucler vers ES depuis ma main, il est correctement bloqué.

$ curl search-sandbox01-xxxxxxxxxx.ap-northeast-1.es.amazonaws.com
{"Message":"User: anonymous is not authorized to perform: es:ESHttpGet on resource: arn:aws:es:ap-northeast-1:xxxxxxxxx:domain/sandbox01/"}

Ouvrez Lambda, `Enregistrez et testez 'le code ci-dessus, et vous aurez une réponse réussie de ES.

START RequestId: b6ce7399-85eb-11e5-b2c3-99a74c2c1765 Version: $LATEST
{
  "status" : 200,
  "name" : "Chief Examiner",
  "cluster_name" : "xxxxxxxxxxx:sandbox01",
  "version" : {
    "number" : "1.5.2",
    "build_hash" : "62ff9868b4c8a0c45860bebb259e21980778ab1c",
    "build_timestamp" : "2015-04-27T09:21:06Z",
    "build_snapshot" : false,
    "lucene_version" : "4.10.4"
  },
  "tagline" : "You Know, for Search"
}

END RequestId: b6ce7399-85eb-11e5-b2c3-99a74c2c1765
REPORT RequestId: b6ce7399-85eb-11e5-b2c3-99a74c2c1765	Duration: 64.87 ms	Billed Duration: 100 ms 	Memory Size: 128 MB	Max Memory Used: 16 MB

Recommended Posts

Envoyer une demande d'AWS Lambda à Amazon Elasticsearch Service
Terraform configuré pour lancer AWS Lambda à partir d'Amazon SQS
Couches AWS Lambda Une explication rapide de la création à la liaison
Une histoire à laquelle j'étais accro à appeler Lambda depuis AWS Lambda.
Envoyer un message de Slack à un serveur Python
Déploiement groupé avec CFn pour prendre des instantanés manuels d'Elastic Search Service avec Lambda
Tweet d'AWS Lambda
Amazon SNS → AWS Lambda → Slack → Exécuter des commandes AWS sur AWS Chatbot
Entrez les données Zaim dans Amazon Elasticsearch Service avec Logstash
Comment lancer AWS Batch à partir de l'application cliente Python
Envoyer un signal au sous-processus
Je souhaite envoyer un message de Python à LINE Bot
Envoyer les images prises avec ESP32-WROOM-32 vers AWS (API Gateway → Lambda → S3)
Faire une demande de Device Farm (appium python) à API Gateway
Exécutez Systems Manager à partir de Lambda pour obtenir une sauvegarde d'EC2
Comment envoyer une requête à l'API DMM (FANZA) avec python
Comment créer une API de machine learning sans serveur avec AWS Lambda
De l'installation d'Elasticsearch à la saisie des données
[Lambda] [Python] Publier sur Twitter depuis Lambda!
Envoyer des commandes d'Atom à Maya
Jusqu'à ce que vous obteniez un instantané du service Amazon Elasticsearch et que vous le restauriez
Comment obtenir la valeur du magasin de paramètres dans lambda (en utilisant python)
J'ai essayé d'envoyer un e-mail de fin d'inscription depuis Gmail avec django.
Téléchargez ce que vous avez dans la demande vers S3 avec AWS Lambda Python
J'ai essayé de créer un service de raccourcissement d'url sans serveur avec AWS CDK
Changer l'instance AWS EC2 de t2 à t3
Comment créer un clone depuis Github
Exécuter un script depuis Jupyter pour traiter
Comment accéder à RDS depuis Lambda (python)
Comment créer un référentiel à partir d'un média
Connectez-vous à s3 avec AWS Lambda Python
[Amazon Linux] Passage de la série Python 2 à la série Python 3
Résumé de l'écriture d'AWS Lambda
[LINE Messaging API] Je souhaite envoyer un message du programme à tout le monde LINE
J'ai créé une bibliothèque pour faire fonctionner la pile AWS CloudFormation à partir de CUI (Python Fabric)
[AWS; Introduction à Lambda] 2ème; Extraire des phrases du fichier json et enregistrer S3 ♬