1
votes

I have been looking at developing some custom resources via the use of Lambda from CloudFormation (CF) and have been looking at using the custom resource helper, but it started off ok then the CF stack took ages to create or delete. When I checked the cloud watch logs I noticed there was an error after running the create or cloud functions in my Lambda.

[7cfecd7b-69df-4408-ab12-a764a8bf674e][2021-02-07 12:41:12,535][ERROR] send(..) failed executing requests.put(..): Formatting field not found in record: 'requestid'

I noticed some others had this issue but no resolution. I have used the generic code from the link below, my custom code works and completes but it looks like passing an update to CF. I looked through the crhelper.py the only reference I can find for 'requestid' is this :

logfmt = '[%(requestid)s][%(asctime)s][%(levelname)s] %(message)s \n'
mainlogger.handlers[0].setFormatter(logging.Formatter(logfmt))
return logging.LoggerAdapter(mainlogger, {'requestid': event['RequestId']})

Reference

1
Can show full, reproducable code example demonstrating the issue?Marcin

1 Answers

0
votes

To understand the error that you're having we need to look at a reproducible code example of what you're doing. Take into consideration that every time that you have some kind of error on a custom resource operation it may take ages to finished, as you have noticed.

But, there is a good alternative to the original custom resource helper that you're using, and, in my experience, this works very well while maintaining the code much simpler (thanks to a good level of abstraction) and follows the best practices. This is the custom resource helper framework, as explained on this AWS blog.

You can find more details about the implementation on github here.

Basically, after downloading the needed dependencies and load them on your lambda (this depends on how you handle custom lambda dependencies), you can manage your custom resources operations like this:

from crhelper import CfnResource
import logging

logger = logging.getLogger(__name__)
# Initialise the helper
helper = CfnResource()

try:
    ## put here your initial code for every operation
    pass
except Exception as e:
    helper.init_failure(e)


@helper.create
def create(event, context):
    logger.info("Got Create")
    print('Here we are creating some cool stuff')

@helper.update
def update(event, context):
    logger.info("Got Update")
    print('Here you update the things you want')

@helper.delete
def delete(event, context):
    logger.info("Got Delete")
    print('Here you handle the delete operation')


# this will call the defined function according the
# cloudformation operation that is running (create, update or delete)
def handler(event, context):
    helper(event, context)