Wie aktualisiere ich das CFN-Response-Modul von AWS CloudFormation für AWS Lambda-Funktionen, die auf Python 2.7/3.6/3.7 ausgeführt werden?
Ich möchte das CFN-Response-Modul von AWS CloudFormation für AWS Lambda-Funktionen aktualisieren, die auf Python 2.7/3.6/3.7 ausgeführt werden.
Behebung
**Hinweis:**Die folgenden Schritte gelten nur für Lambda-Funktionen, die auf Python 2.7/3.6/3.7 ausgeführt werden. Die folgenden Befehle gelten für Linux- und macOS-Umgebungen. Die Syntax kann in Windows PowerShell variieren.
**Hinweis:**Wenn Sie beim Ausführen von AWS Command Line Interface (AWS CLI)-Befehlen Fehler erhalten, stellen Sie sicher, dass Sie die neueste AWS CLI-Version verwenden.
- Führen Sie den folgenden Befehl aus, um die Stacks zu finden, die benutzerdefinierte Ressourcen enthalten:
aws cloudformation list-stacks --region us-east-1 | grep -oE 'arn:[^"]+' | while read arn; do aws cloudformation list-stack-resources --stack-name $arn --region us-east-1 | grep -E '(Custom::)|(::CustomResource)' | awk '{print $2}' | while read resource; do if [[ -n $resource ]]; then echo $arn; echo $resource; fi; done; done
Sie sollten eine Ausgabe sehen, die der folgenden Beispielausgabe ähnelt:
arn:aws:cloudformation:us-east-1:123456789012:stack/TestStack/3497b950-55f1-11eb-aad4-124a026c8667 "ResourceType": "AWS::CloudFormation::CustomResource",
- Um die Lambda-Funktion zu finden, die der benutzerdefinierten Ressource zugeordnet ist, führen Sie den folgenden Befehl aus, um die ServiceToken-Eigenschaft der benutzerdefinierten Ressource anhand der Stack-Vorlage zu überprüfen:
aws cloudformation get-template --stack-name TestStack | jq -r .TemplateBody
**Hinweis:**Der Befehl in Schritt 2 zeigt eine Vorschau der Vorlage des Stacks an, indem die Option jq (von der jq-Website) verwendet wird, um die Antwort zu formatieren.
Sie sollten eine Ausgabe sehen, die der folgenden Beispielausgabe ähnelt:
Resources: MyCustomResource: Type: AWS::CloudFormation::CustomResource Properties: ServiceToken: !GetAtt MyFunction.Arn Name: "John" MyFunction: Type: AWS::Lambda::Function Properties: Handler: index.handler Role: !GetAtt MyRole.Arn Runtime: python3.7 Code: ZipFile: | import cfnresponse def handler(event, context): responseData = {'Message': 'Hello {}!'.format(event['ResourceProperties']['Name'])} cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID") MyRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole ManagedPolicyArns: - "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" Outputs: Result: Value: !GetAtt MyCustomResource.Message
**Hinweis:**Die Vorlage, die Sie aus der Ausgabe für Schritt 2 erhalten, ist ein Beispiel für eine Minimalvorlage für eine Lambda-gestützte benutzerdefinierte Ressource. Das ServiceToken:! GetAtt myFunction.arn befindet sich im Abschnitt MyCustomResource. Der von der !GetATT MyFunction .Arn der ServiceToken-Eigenschaft berechnete Wert ist entweder der Amazon-Ressourcenname (ARN) des Amazon Simple Notification Service (Amazon SNS) -Themas oder die Lambda-Funktion.
- Identifizieren Sie in der Vorlage aus Schritt 2, wo Ihre Lambda-Funktion definiert ist.
Wenn sich Ihre Lambda-Funktion im selben Stack wie die benutzerdefinierte Ressource befindet, fahren Sie mit Schritt 4 fort. Die Funktion Fn: :getAtt in Schritt 2 zeigt beispielsweise, dass die Lambda-Funktion in derselben Vorlage wie die benutzerdefinierte Ressource definiert ist.
Wenn die Eigenschaft ServiceToken auf einen fest codierten ARN verweist, könnte sich die Lambda-Funktion in einem anderen Stack befinden. Wenn die ServiceToken-Eigenschaft über Fn: :Import aufgelöst wird, verwenden Sie die List-Exports-API in AWS CloudFormation, um den Wert nachzuschlagen. Zum Beispiel:
aws cloudformation list-exports --region us-east-1 { "Exports": [ { "ExportingStackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/SomeOtherStack/481dc040-b283-11e9-b1bd-12d607a4fd1c", "Value": "arn:aws:lambda:us-east-1:123456789012:function:SomeOtherStack-MyFunction-5ZE2CQO8RAA9", "Name": "MyExport" } ] }
Suchen Sie dann nach Funktions-Tags in einem separaten Stack, indem Sie List-Tags verwenden, um den AWS CloudFormation-Stack-ARN zu finden. Zum Beispiel:
aws lambda list-tags --resource arn:aws:lambda:us-east-1:123456789012:function:TestStack-MyFunction-5ZE2CQO8RAA9 | grep stack-id
Sie erhalten eine Ausgabe, die der folgenden ähnelt:
"aws:cloudformation:stack-id": "arn:aws:cloudformation:us-east-1:123456789012:stack/TestStack/3497b950-55f1-11eb-aad4-124a026c8667"
**Hinweis:**Sie finden Funktions-Tags auch in der AWS Lambda-Konsole.
- Damit AWS CloudFormation das neueste cfn-response-Modul in Ihre Lambda-Funktion laden kann, aktualisieren Sie den Inline-Quellcode Ihrer Lambda-Funktion. Zum Beispiel:
Code: ZipFile: | import cfnresponse def handler(event, context): responseData = {'Message': 'Hello {}!'.format(event['ResourceProperties']['Name'])} cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID")
**Hinweis:**In Schritt 2 finden Sie eine Beispielvorlage, die eine Lambda-Funktion mit integriertem Quellcode enthält.
Jetzt wird das folgende Codebeispiel für das cfn-response-Modul von AWS CloudFormation in Ihre Lambda-Funktion geladen. Zum Beispiel:
from botocore.vendored import requests import json SUCCESS = "SUCCESS" FAILED = "FAILED" def send(event, context, responseStatus, responseData, physicalResourceId=None, noEcho=False): responseUrl = event['ResponseURL'] print(responseUrl) responseBody = {} responseBody['Status'] = responseStatus responseBody['Reason'] = 'See the details in CloudWatch Log Stream: ' + context.log_stream_name responseBody['PhysicalResourceId'] = physicalResourceId or context.log_stream_name responseBody['StackId'] = event['StackId'] responseBody['RequestId'] = event['RequestId'] responseBody['LogicalResourceId'] = event['LogicalResourceId'] responseBody['NoEcho'] = noEcho responseBody['Data'] = responseData
**Hinweis:**Weitere Informationen finden Sie in den Codebeispielen im Abschnitt „Modulquellcode“ des cfn-response-Moduls.
Das Codebeispiel für das Modul cfn-response verwendet botocore.requests im Bereitstellungspaket der Lambda-Funktion.
Um das Modul cfn-response auf die neueste Version zu aktualisieren, die urllib3 verwendet, aktualisieren Sie den Inline-Code der Funktion in der AWS CloudFormation-Vorlage. Fügen Sie dazu einen Kommentar zum Code der Lambda-Inline-Funktion hinzu. Zum Beispiel:
ZipFile: | import cfnresponse def handler(event, context): + # This comment was added to force an update on this function's code responseData = {'Message': 'Hello {}!'.format(event['ResourceProperties']['Name'])} cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID") MyRole:
5.Speichern Sie alle Änderungen an der Vorlage, die Ihre Lambda-Funktion enthält.
Das Modul cfn-response wird geändert, nachdem die Aktualisierung des Stacks abgeschlossen ist.
**Hinweis:**Wenn sich der Code Ihrer Funktion in einem Amazon Simple Storage Service (Amazon S3) -Bucket oder Amazon Elastic Container Registry (Amazon ECR) -Image befindet, müssen Sie das Modul selbst aktualisieren, um die Version mit urllib3 aufzunehmen. Den Quellcode für die neueste Version des cfn-response-Moduls finden Sie unter cfn-response module.
**Hinweis:**Wenn eine neue Python- oder JavaScript-Runtime eine wichtige Änderung einführt, müssen Sie das Modul cfn-response aktualisieren. Anstatt das ZipFile erneut zu aktualisieren, können Sie automatisch die neueste Version des cfn-response-Moduls anhängen, wenn die Runtime-Eigenschaft einer Funktion aktualisiert wird.
Relevanter Inhalt
- AWS OFFICIALAktualisiert vor 3 Jahren
- AWS OFFICIALAktualisiert vor 5 Jahren
- AWS OFFICIALAktualisiert vor einem Jahr
- AWS OFFICIALAktualisiert vor einem Monat