AWS Builder Center: Learn, Build and Connect with builders in the AWS community
AWS Builder Center is the official home for builders on AWS. Share and read what others are working on, follow people who inspire you, explore training and workshops, and find tools to support what you're building.
如何更新在 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 ** 模組。
- 語言
- 中文 (繁體)

相關內容
已提問 3 年前
AWS 官方已更新 4 年前