Python 2.7/3.6/3.7 で実行される AWS Lambda 関数の AWS CloudFormation の cfn-response モジュールを更新するにはどうすればよいですか?

所要時間3分
0

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 モジュールの最新バージョンを自動的にアタッチできます。


AWS公式
AWS公式更新しました 3年前
コメントはありません

関連するコンテンツ