Python 2.7/3.6/3.7에서 실행되는 AWS Lambda 함수에 대한 AWS CloudFormation cfn-response 모듈을 업데이트하려면 어떻게 해야 하나요?

4분 분량
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 지원 사용자 지정 리소스에 대한 최소 템플릿의 예입니다. 속성 ServiceToken: !GetAtt MyFunction.ArnMyCustomResource 섹션에 있습니다. Service Token 속성의 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 콘솔에서도 함수 tags를 찾을 수 있습니다.

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년 전