CloudFormation Custom Resource with Lambda using boto3

Can we have an example on CloudFormation Custom Resource with Lambda using boto3

  • post-author-pic
    Phil Z
    09-20-2018

    Hi Vinayak, what are you trying to do? We'd be happy to give you some direction, but it would help if you could tell us a little more about what you're having trouble with and what your goal is.

  • post-author-pic
    Vinayak P
    09-20-2018

    In the Cloudformation deep dive course,we have a section on Custom resource with Lambda which has its code in node.js and even that code is not available in the download section. So I was trying to create a templated with custom resource using boto3. This is the template I've created so far:


    {
    "AWSTemplateFormatVersion" : "2010-09-09",

    "Description" : "AWS CloudFormation template for Custom Lambda resource",

    "Parameters": {
    "Password" : {
    "Description" : "Password",
    "Type" : "String"
    },
    "ConfirmPassword" : {
    "Description" : "Password Confirmation",
    "Type" : "String"
    }
    },

    "Resources" : {
    "PasswordChecker": {
    "Type": "Custom::PasswordChecker",
    "Properties": {
    "ServiceToken": { "Fn::GetAtt" : ["PasswordCheckerFunction", "Arn"] },
    "Password": {
    "Ref": "Password"
    },
    "ConfirmPassword": {
    "Ref": "ConfirmPassword"
    }

    }
    },

    "PasswordCheckerFunction": {
    "Type": "AWS::Lambda::Function",
    "Properties": {
    "Code": {
    "ZipFile" : { "Fn::Join" : ["\n", [
    "import json",
    "import cfnresponse",
    "def handler(event, context):",
    " ec2c = boto3.client('ec2')",
    " print event['ResourceProperties']",
    " password = event['ResourceProperties']['Password']",
    " confpassword = event['ResourceProperties']['ConfirmPassword']",
    " print password,confpassword",
    " if password == confpassword:",
    " resp='Password Matched',
    " else:",
    " resp='Password does not match',
    " cfnresponse.send(event, context, cfnresponse.SUCCESS, resp)",
    " return resp"
    ]]}
    },

    "Handler": "lambda_handler",
    "Role": { "Fn::GetAtt" : ["LambdaExecutionRole", "Arn"] },
    "Runtime": "python2.7",
    "Timeout": "30"
    }},

    "LambdaExecutionRole": {
    "Type": "AWS::IAM::Role",
    "Properties": {
    "AssumeRolePolicyDocument": {
    "Version": "2012-10-17",
    "Statement": [{
    "Effect": "Allow",
    "Principal": {"Service": ["lambda.amazonaws.com"]},
    "Action": ["sts:AssumeRole"]
    }]
    },
    "Path": "/",
    "Policies": [{
    "PolicyName": "root",
    "PolicyDocument": {
    "Version": "2012-10-17",
    "Statement": [{
    "Effect": "Allow",
    "Action": ["logs:CreateLogGroup","logs:CreateLogStream","logs:PutLogEvents"],
    "Resource": "arn:aws:logs:*:*:*"
    },
    {
    "Effect": "Allow",
    "Action": ["ec2:DescribeImages"],
    "Resource": "*"
    }]
    }
    }]
    }
    } }
    }


    I just want to check whether the password and confirm password matches, then only proceed further otherwise give an error on the console


  • post-author-pic
    Phil Z
    09-20-2018

    I noticed a couple errors here. First, there are missing end quotes on a few lines of your Lambda code - a JSON validator should be able to help you find these. The handler must also match the function you provide - change the "Handler" property to "index.handler" so that Python is able to find the function. You will also need to import boto3 - it's included in the Lambda service so you can simply add the line "import boto3", but it does need to be explicitly imported.


    Finally, the cfnresponse returns a dictionary, not a string. Try something like this when you're handling the response:

    responseData = {}
    responseData['Data'] = 'Password Matched'
    cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData)


    Hope this helps! You can also check out the docs on the cfn-response module for more info: 

    https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-code.html#cfn-lambda-function-code-cfnresponsemodule 

  • post-author-pic
    Vinayak P
    09-21-2018

    Hi Phil, Thanks a lot. With all your suggestions,I got that CFT working. Is there a way I can print a message whenever passwords doesn't match,at the time of specifying input parameters?

  • post-author-pic
    Phil Z
    09-26-2018

    Yes, you can set the response to anything you like. For example, use the if/else condition like you did in your original code and set `responseData['Data']` depending on whether the password matches. Hope this helps

Looking For Team Training?

Learn More