[PYTHON] Senden Sie eine Anfrage von AWS Lambda an Amazon Elasticsearch Service

Amazon Elasticsearch Service ist Elasticsearch. Sie können den Endpunkt normalerweise als elastische Suche verwenden und eine der folgenden Zugriffsrichtlinien auswählen.

Übrigens habe ich über eine Anfrage von Lambda nachgedacht, die auf IAM basiert, die in S3 platzierte Datei für ein wenig Bequemlichkeit leicht zu analysieren und in Elasticsearch zu verschieben, aber derzeit scheint es, dass ich meine eigene Signaturanfrage stelle und sie einwerfe.

Ergebnis. Ich habe es versucht, aber jetzt scheint es einfacher zu sein, es in den CloudWatch Logs-Stream zu streamen und dann die voreingestellten Funktionen zu verwenden. Wenn die boto3-Ressource für ES implementiert ist, scheint es keine Probleme zu geben.

Es hat vorerst funktioniert, notieren Sie sich also den Code.

Domain-seitige Elasticsearch-Richtlinie

Lambda-Funktion

Abgesehen von EventSource senden Sie vorerst einfach ein GET an das ES /. Die folgenden Materialien waren hilfreich.

Meistens der Code, um den Header zu erstellen. .. ..

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()

Ist es möglich, diesen Header mithilfe des Botocore-Moduls schnell zu erstellen? Beim Denken.

Nachtrag: Klicken Sie hier, um ein Beispiel für "Machen Sie es schnell mit dem Botocore-Modul". [Kleine Geschichte] Verwenden Sie nur den Signaturprozess der AWS-API-Anforderung von Botocore | Developers.IO

You Know, for Search

Wenn ich versuche, von meiner Hand zu ES zu gelangen, wird es ordnungsgemäß blockiert.

$ 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/"}

Öffnen Sie Lambda, speichern und testen Sie den obigen Code, und Sie erhalten eine erfolgreiche Antwort von 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

Senden Sie eine Anfrage von AWS Lambda an Amazon Elasticsearch Service
Terraform konfiguriert, um AWS Lambda von Amazon SQS aus zu starten
AWS Lambda Layers Eine kurze Erklärung von der Erstellung bis zur Verknüpfung
Eine Geschichte, die ich süchtig danach war, Lambda von AWS Lambda anzurufen.
Senden Sie eine Nachricht von Slack an einen Python-Server
Massenbereitstellung mit CFn, um manuelle Schnappschüsse des Elastic Search Service mit Lambda zu erstellen
Tweet von AWS Lambda
Amazon SNS → AWS Lambda → Slack → Führen Sie AWS-Befehle in AWS Chatbot aus
Geben Sie Zaim-Daten mit Logstash in den Amazon Elasticsearch Service ein
So starten Sie AWS Batch über die Python-Client-App
Senden Sie ein Signal an den Unterprozess
Ich möchte eine Nachricht von Python an LINE Bot senden
Senden Sie mit ESP32-WROOM-32 aufgenommene Bilder an AWS (API Gateway → Lambda → S3).
Stellen Sie eine Anfrage von der Gerätefarm (Appium Python) an das API-Gateway
Führen Sie Systems Manager von Lambda aus, um ein Backup von EC2 zu erhalten
So senden Sie eine Anfrage mit Python an die DMM (FANZA) -API
So erstellen Sie mit AWS Lambda eine serverlose API für maschinelles Lernen
Von der Installation von Elasticsearch bis zur Dateneingabe
[Lambda] [Python] Von Lambda auf Twitter posten!
Senden Sie Befehle von Atom an Maya
Bis Sie einen Schnappschuss des Amazon Elasticsearch-Dienstes erhalten und wiederherstellen
So erhalten Sie den Wert aus dem Parameterspeicher in Lambda (mit Python)
Ich habe versucht, mit django eine E-Mail zum Abschluss der Registrierung von Google Mail zu senden.
Laden Sie das, was Sie angefordert haben, mit AWS Lambda Python in S3 hoch
Ich habe versucht, einen URL-Verkürzungsdienst mit AWS CDK serverlos zu machen
Ändern Sie die AWS EC2-Instanz von t2 in t3
So erstellen Sie einen Klon aus Github
Führen Sie ein Skript von Jupyter aus, um es zu verarbeiten
Zugriff auf RDS von Lambda (Python)
So erstellen Sie ein Repository aus Medien
Stellen Sie mit AWS Lambda Python eine Verbindung zu s3 her
[Amazon Linux] Wechsel von der Python 2-Serie zur Python 3-Serie
Zusammenfassung des Schreibens von AWS Lambda
[LINE Messaging API] Ich möchte eine Nachricht vom Programm an alle LINE senden
Ich habe eine Bibliothek zum Betreiben des AWS CloudFormation-Stacks über CUI (Python Fabric) erstellt.
[AWS; Einführung in Lambda] 2. Extrahieren Sie Sätze aus der JSON-Datei und speichern Sie S3 ♬