3
votes

Trying to create inline python lambda function as custom backed cloudformation resource.. with cfnresponse to get the information of the resource creation..but my stack is rolling back with errors.

Error: CustomResource attribute error: Vendor response doesn't contain Message key in object arn:aws:cloudformation:us-west-2:stack/Custom-lambda/8eaeead0-68b8-11e9-8e31-0247c451c136|CustomResource|3a7885fc-0959-4284-b4f6-8153fe6420df in S3 bucket cloudformation-custom-resource-storage-uswest2. Rollback requested by user.

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "AWS CloudFormation to set up a custom CloudFormation resource with Lambda, and then call it in the same template.",
    "Resources": {
        "CustomFunction": {
            "Type": "AWS::Lambda::Function",
            "Properties": {
                "Code": {
                    "ZipFile": {
                        "Fn::Join": [
                            "\n",
                            [
                                "import urllib2",
                                "import os",
                                "import boto3",
                                "import json",
                                "import cfnresponse",
                                "def lambda_handler(event, context):",
                                "",
                                "    print 'EVENT ##################'",
                                "    print json.dumps(event)",
                                "    print '########################'",
                                "",
                                "    pid = 'optionalPhysicalID'",
                                "    response = {}",
                                "",
                                "    try:",
                                "",
                                "        response['Output'] = '-' + event['ResourceProperties']['Input'].upper() + '-'",
                                "",
                                "        if event['RequestType'] == 'Create':",
                                "            print 'Creating stack'",
                                "",
                                "        if event['RequestType'] == 'Update':",
                                "            print 'Updating Stack'",
                                "",
                                "        if event['RequestType'] == 'Delete':",
                                "            print 'Deleting Stack'",
                                "",
                                "    except Exception as e:",
                                "        print str(e)",
                                "        cfnresponse.send(event, context, cfnresponse.FAILED, { 'error': str(e) }, pid)",
                                "        return",
                                "",
                                "    cfnresponse.send(event, context, cfnresponse.SUCCESS, response, pid)",
                                "",
                                "    client = boto3.client('s3')",
                                "    response = urllib2.urlopen('https://s3-us-west-2.amazonaws.com/')",
                                "    html = response.read()",
                                "    filename = 'test.sh' ",
                                "    path ='/tmp/'+filename",
                                "    file_ = open(path, 'w')",
                                "    file_.write(html)",
                                "    file_.close()",
                                "    local_file_name = 'tmp/'+filename",
                                "    account_number =boto3.client('sts').get_caller_identity().get('Account')",
                                "    print(account_number)",
                                "    client.create_bucket(Bucket='abc-'+account_number+'-emr-files',",
                                "    CreateBucketConfiguration={'LocationConstraint': 'us-west-2'})",
                                "    client.put_object(Bucket='abc-'+account_number+'-emr-files',Key=filename)"
                            ]
                        ]
                    }
                },
                "Role": {
                    "Fn::Join": [
                        "",
                        [
                            "arn:aws:iam::",
                            {
                                "Ref": "AWS::AccountId"
                            },
                            ":role/AWS__AD_DNS_EMR_Clnup_Lambda_Exctn_Role"
                        ]
                    ]
                },
                "Handler": "index.lambda_handler",
                "MemorySize": "128",
                "Runtime": "python2.7",
                "Timeout": 180
            },
            "Metadata": {
                "AWS::CloudFormation::Designer": {
                    "id": "e683a5e0-d8e2-4747-84ed-3273acd09d66"
                }
            }
        },
        "CustomResource": {
            "Type": "Custom::CustomResource",
            "Properties": {
                "ServiceToken": {
                    "Fn::GetAtt": [
                        "CustomFunction",
                        "Arn"
                    ]
                },
                "Input": "Parameter to pass into Custom Lambda Function"
            },
            "Metadata": {
                "AWS::CloudFormation::Designer": {
                    "id": "2a474cb7-859c-4647-958e-c72674dd1a6b"
                }
            }
        }
    },
    "Outputs": {
        "Message": {
            "Description": "The message from the custom resource.",
            "Value": {
                "Fn::GetAtt": [
                    "CustomResource",
                    "Message"
                ]
            }
        },
        "CustomFunctionArn": {
            "Description": "The arn of the custom resource function.",
            "Value": {
                "Fn::GetAtt": [
                    "CustomFunction",
                    "Arn"
                ]
            }
        }
    },
    "Metadata": {
        "AWS::CloudFormation::Designer": {
            "e683a5e0-d8e2-4747-84ed-3273acd09d66": {
                "size": {
                    "width": 60,
                    "height": 60
                },
                "position": {
                    "x": 60,
                    "y": 90
                },
                "z": 1,
                "embeds": []
            },
            "2a474cb7-859c-4647-958e-c72674dd1a6b": {
                "size": {
                    "width": 60,
                    "height": 60
                },
                "position": {
                    "x": 180,
                    "y": 90
                },
                "z": 1,
                "embeds": []
            }
        }
    }
}
1

1 Answers

3
votes

Check the key Message in the Outputs section. You are using intrinsic function GetAtt to get an attribute called Message from CustomResource. Resulting CloudFormation error tells us that the function doesn't have Message as a return value of the very resource.