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 コマンドラインインターフェイス (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-backed カスタムリソースの最小テンプレートの例です。プロパティ ServiceToken: !GetAtt MyFunction.Arn は、MyCustomResource セクションにあります。ServiceToken プロパティの GetAtt MyFunction**.Arn** によって解決される値は、Amazon Simple Notification Service (Amazon SNS) トピックの Amazon リソースネーム (ARN) または Lambda 関数のいずれかです。
3. ステップ 2 のテンプレートで、Lambda 関数が定義されている場所を特定します。
Lambda 関数がカスタムリソースと同じスタックにある場合は、ステップ 4 に進みます。例えば、ステップ 2 の Fn::GetAtt 関数は、Lambda 関数がカスタムリソースと同じテンプレートで定義されていることを示しています。
ServiceToken プロパティがハードコードされた ARN をポイントしている場合、Lambda 関数は別のスタックにある可能性があります。ServiceToken プロパティが Fn::Import によって解決される場合は、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 コンソールでも関数タグを見つけることができます。
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 を参照してください。
これで、次の cfn-response モジュールコードサンプルが AWS CloudFormation によって 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 モジュールの最新バージョンを自動的にアタッチできます。
関連するコンテンツ
- 質問済み 1ヶ月前lg...
- 質問済み 1年前lg...
- AWS公式更新しました 2年前