Souad
Souad

Reputation: 5094

Can't invoke lambda function by a custom cloudformation resource

I am creating a cloudformation template, that creates a DynamoDB table. I want to put the values of the parameters of the template inside the DynamoDB table. To do so, I created a lambda function that takes the stack parameters and put them in the table item as follows:

import boto3

def lambda_handler(event, context):
    parameters = {}
    outputs = {}
    cf_client = boto3.client('cloudformation')
    dynamodb = boto3.resource('dynamodb')
    # Get the name of the stack cloudformation
    stack_name = context.invoked_function_arn.split(':')[6].rsplit('-', 2)[0]
    response = cf_client.describe_stacks(StackName=stack_name)
    # Get the outputs of the stack
    for r in response['Stacks'][0]['Outputs']:
        outputs[r['OutputKey']] = r['OutputValue']
    policy_table_name = outputs['PolicyDDBTableName']
    # Get the parametres of the stack
    for e in response['Stacks'][0]['Parameters']:
        parameters[e['ParameterKey']] = e['ParameterValue']
    DefaultRetentionDays = parameters['DefaultRetentionDays']
    CustomTagName = parameters['CustomTagName']
    AutoSnapshotDeletion = parameters['AutoSnapshotDeletion']
    response = dynamodb.put_item(
        TableName=policy_table_name,
        Item={'SolutionName': {'S': 'EbsSnapshotScheduler'},
              'DefaultRetentionDays': {'S': DefaultRetentionDays},
              'CustomTagName': {'S': CustomTagName},
              'AutoSnapshotDeletion': {'S': AutoSnapshotDeletion}
             })

Then in the template cloudformation, I created a custom resource to invoke the function:

"PutInDB" : {
  "Type" : "Custom::customhelper",
  "Properties" : {
    "ServiceToken": { "Fn::GetAtt" :  ["FunctionHelper" , "Arn"]  },
    "StackName": {"Ref": "AWS::StackName" }
  }
},

The function and its role are also created in the same stack.

When I create the stack the custom resource hangs and fails to create with the error:

Custom Resource failed to stabilize in expected time

. Am I missing something here? How can I successfully create the custom resource and invoke the function so that the parameters of the stack get inserted inside the DynamoDB table ?

From the AWS Documentation:

When you associate a Lambda function with a custom resource, the function is invoked whenever the custom resource is created, updated, or deleted

Upvotes: 3

Views: 2502

Answers (1)

Tim Bassett
Tim Bassett

Reputation: 1178

Are you creating the lambda function in the same CF template?

I haven't looked at this closely, but my initial impression is that the lambda function is not completing the requirements to let cloudformation know that it has completed creation.

The key being that the CF "response.SUCCESS" response has not been sent back to CF. CF will create the lambda function but it needs to know it was successful.

This is how you would do it in node.js, I don't know the syntax for python.

response.send(event, context, response.SUCCESS, responseData);

See http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-code.html

Upvotes: 1

Related Questions