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?

Lesedauer: 5 Minute
0

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.

  1. 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",
  1. 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.

  1. 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.

  1. 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.

  1. Aktualisieren Sie Ihren Stack.

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.


AWS OFFICIAL
AWS OFFICIALAktualisiert vor 3 Jahren