AWS lambda: No module named 'cfnresponse'

假装没事ソ 提交于 2019-12-19 19:44:37

问题


I have deployed an AWS lambda which contains:

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")

I tried to get the values of the cfnresponse in my cloudformations:

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

Now th cfn is stuck and I got the error:

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

What am I doing wrong? It seems the way to do it when I check the docs.


回答1:


Cfnresponse is just available in lambda by default with python 2.7. Probably you are using 3.6.




回答2:


Did you specify your function's source code in ZipFile? If you specify an actual zip file, that module won't be included.

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).

If you need to use an actual zip file, or this doesn't work for any other reason, you can include the module yourself. Its source code is available in the link you provided. For Python 3 it's:

#  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))


来源:https://stackoverflow.com/questions/49885243/aws-lambda-no-module-named-cfnresponse

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!