AWS lambda:没有名为 'cfnresponse' 的模块

AWS lambda: No module named 'cfnresponse'

我部署了一个 AWS lambda,其中包含:

import json
import boto3
import cfnresponse
import urllib.request
from botocore.exceptions import ClientError

def lambda_handler(event, context):
...
cfnresponse.send(event, context, status, responseData, "CustomResourcePhysicalID")

我试图在我的 cloudformations 中获取 cfnresponse 的值:

Resources:
  API:
    Type: Custom::API
    Version: '1.0'
    Properties:
      ServiceToken: arn:aws:lambda:eu-west-1:1234567891011:function:getCountry
Outputs:
  Status:
    Value:
       !GetAtt API.Data

现在 cfn 卡住了,我得到了错误:

Unable to import module 'lambda_function': No module named 'cfnresponse' 

我做错了什么?当我检查 docs.

时,这似乎是这样做的方法

您是否在 ZipFile 中指定了函数的源代码?如果您指定实际的 zip 文件,则不会包含该模块。

When you use the ZipFile property to specify your function's source code and that function interacts with an AWS CloudFormation custom resource, you can load the cfn-response module to send responses to those resources. The module contains a send method, which sends a response object to a custom resource by way of an Amazon S3 presigned URL (the ResponseURL).

如果您需要使用实际的 zip 文件,或者由于任何其他原因这不起作用,您可以自己包含该模块。它的源代码在您提供的 link 中可用。 Python 3 是:

#  Copyright 2016 Amazon Web Services, Inc. or its affiliates. All Rights Reserved.
#  This file is licensed to you under the AWS Customer Agreement (the "License").
#  You may not use this file except in compliance with the License.
#  A copy of the License is located at http://aws.amazon.com/agreement/ .
#  This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied.
#  See the License for the specific language governing permissions and limitations under the License.

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

    json_responseBody = json.dumps(responseBody)

    print("Response body:\n" + json_responseBody)

    headers = {
        'content-type' : '',
        'content-length' : str(len(json_responseBody))
    }

    try:
        response = requests.put(responseUrl,
                                data=json_responseBody,
                                headers=headers)
        print("Status code: " + response.reason)
    except Exception as e:
        print("send(..) failed executing requests.put(..): " + str(e))

Cfnresponse 仅在 python 2.7 默认情况下在 lambda 中可用。可能你正在使用 3.6.