如何更新在 Python 2.7/3.6/3.7 上執行的 AWS Lambda 函數的 AWS CloudFormation cfn-response 模組?
我想要更新在 Python 2.7/3.6/3.7 上執行的 AWS Lambda 函數的 AWS CloudFormation cfn-response 模組。
解決方案
**注意事項:**下列步驟僅適用於在 Python 2.7/3.6/3.7 上執行的 Lambda 函數。下列命令適用於 Linux 和 macOS 環境。Windows PowerShell 上的語法可能會有所不同。
**注意事項:**如果您在執行 AWS Command Line Interface (AWS CLI) 命令時收到錯誤訊息,請確認您使用的是最新的 AWS CLI 版本。
1. 如需尋找包含自訂資源的堆疊,請執行以下命令:
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
您應該會看到類似於下列範例的輸出:
arn:aws:cloudformation:us-east-1:123456789012:stack/TestStack/3497b950-55f1-11eb-aad4-124a026c8667 "ResourceType": "AWS::CloudFormation::CustomResource",
2. 若要尋找與自訂資源相關聯的 Lambda 函數,請執行下列命令,從堆疊的範本檢查自訂資源的 ServiceToken 屬性:
aws cloudformation get-template --stack-name TestStack | jq -r .TemplateBody
**注意事項:**步驟 2 中的命令會使用 jq 選項 (來自 jq 網站) 預覽堆疊的範本以格式化回應。
您應該會看到類似於下列範例的輸出:
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
注意事項:您從步驟 2 的輸出中取得的範本是 Lambda 支援的自訂資源的最小範本範例。該ServiceToken: !GetAtt MyFunction.Arn 屬性在 MyCustomResource 區段中。由 ServiceToken 屬性的 !GetAtt MyFunction**.Arn** 解析的值不是 Amazon Simple Notification Service (Amazon SNS) 主題的 Amazon Resource Name (ARN) 就是 Lambda 函數。
3. 在步驟 2 的範本中,識別 Lambda 函數的定義位置。
如果您的 Lambda 函數與自訂資源位於相同的堆疊中,請跳至步驟 4。例如,步驟 2 中的 Fn::GetAtt 函數會顯示 Lambda 函數定義在與自訂資源相同的範本中。
如果 ServiceToken 屬性指向寫在程式中的 ARN,則 Lambda 函數可能在另一個堆疊中。如果已透過 Fn::Import 解析 ServiceToken 屬性,則請使用 AWS CloudFormation 中的 list-exports API 來查詢值。例如:
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" } ] }
然後,使用 list-tags 檢查位於個別堆疊中的函數標籤,以尋找 AWS CloudFormation 堆疊 ARN。例如:
aws lambda list-tags --resource arn:aws:lambda:us-east-1:123456789012:function:TestStack-MyFunction-5ZE2CQO8RAA9 | grep stack-id
您會收到類似於下列內容的輸出:
"aws:cloudformation:stack-id": "arn:aws:cloudformation:us-east-1:123456789012:stack/TestStack/3497b950-55f1-11eb-aad4-124a026c8667"
**注意事項:**您還可以在 AWS Lambda 主控台中找到](https://docs.aws.amazon.com/lambda/latest/dg/configuration-tags.html)標籤[函數。
4. 若要允許 AWS CloudFormation 在 Lambda 函數中載入最新的 cfn-response 模組,請更新 Lambda 函數的內嵌原始碼。例如:
Code: ZipFile: | import cfnresponse def handler(event, context): responseData = {'Message': 'Hello {}!'.format(event['ResourceProperties']['Name'])} cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID")
**注意事項:**如需具有內嵌原始碼的 Lambda 函數的範例範本,請參閱步驟 2。
現在,AWS CloudFormation 會將下列 cfn-response 模組代碼範例載入至您的 Lambda 函數。例如:
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
**注意事項:**如需相關資訊,請參閱 cfn-response 模組的「模組原始碼」區段中的代碼範例。
cfn-response 模組代碼範例會在 Lambda 函數的部署套件中使用 botocore.requests。
若要將 cfn-response 模組更新為使用 urllib3 的最新版本,請在 AWS CloudFormation 範本中更新函數的內嵌代碼。透過將備註新增至內嵌 Lambda 函數代碼來執行此動作。例如:
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. 將任何變更儲存至包含 Lambda 函數的範本。
6. 更新您的堆疊。
在堆疊完成更新後,即會修改 cfn-response 模組。
**注意事項:**如果您的函數代碼位於Amazon Simple Storage Service (Amazon S3) 儲存貯體或 Amazon Elastic Container Registry (Amazon ECR) 映像檔中,您必須自行更新模組,以包含 urllib3 的版本。若要取得最新版本的 cfn-response 模組的原始碼,請參閱 cfn-response 模組。
**注意事項:**如果新的 Python 或 JavaScript 執行時引入了重大變更,則您必須更新 cfn-response 模組。無需再次更新 ZipFile,無論何時更新函數的 Runtime 屬性,您都可以自動連接最新版本的 ** cfn-response ** 模組。
相關內容
- 已提問 2 年前lg...
- 已提問 1 個月前lg...
- AWS 官方已更新 1 年前
- AWS 官方已更新 3 年前