Create a Custom Resource to call a lambda function from a Cloud Formation template

Jagan Selva
BI3 Technologies
Published in
4 min readOct 28, 2021

AWS CloudFormation

AWS CloudFormation is a model and provisioning language for AWS and third-party application resources in your cloud environment.

The Lambda Function

To allow custom resource methods, you should first create a lambda function.

The lambda function gets the responseURL and it needs to send a PUT with required parameters. This will notify that CloudFormation that resource is ready.

These are the required parameters to send with the request

  • Status — Status of the resource (SUCCESS / FAILED)
  • PhysicalResourceId — identifier of the resource
  • Data — Output
  • StackId — Value available in request object
  • RequestId — Value available in request object
  • LogicalResourceId — Value available in request object

Sample Code Here

//Main Functionpublic async Task<CloudFormationResponse> FunctionName(CustomCloudFormationRequest request, ILambdaContext context){// Code your functionality herereturn await CompleteCloudFormationResponse(output, request, context);}//Cloud Formation Request Propertiespublic class CustomCloudFormationRequest : CloudFormationRequest{public ResourcePropertiesModel ResourceProperties { get; set; }    public class ResourcePropertiesModel    {        public string Region { get; set; }        public string ChildIdList { get; set; }        public string RolePattern { get; set; }        public string AccountId { get; set; }    }}//Cloud Formation Responsepublic class CloudFormationResponse{    public string Status { get; set; }    public string Reason { get; set; }    public string PhysicalResourceId { get; set; }    public string StackId { get; set; }    public string RequestId { get; set; }    public string LogicalResourceId { get; set; }    public object Data { get; set; }}//Notify Cloud formation about resource statuspublic static async Task<CloudFormationResponse> CompleteCloudFormationResponse(object output, CloudFormationRequest request, ILambdaContext context){var responseBody = new CloudFormationResponse{    Status = “SUCCESS”,    PhysicalResourceId = context.LogStreamName,    StackId = request.StackId,    RequestId = request.RequestId,    LogicalResourceId = request.LogicalResourceId,    Data = output};HttpClient client = new HttpClient(new LoggingHandler(new HttpClientHandler()));var jsonContent = new StringContent(JsonConvert.SerializeObject(responseBody));jsonContent.Headers.Remove(“Content-Type”);var postResponse = await client.PutAsync(request.ResponseURL, jsonContent);postResponse.EnsureSuccessStatusCode();return responseBody;}

CloudFormation Template

For this, you’ll need a lambda function and an execution role. This part is common as any other lambda functions.

Define the policies necessary for lambda functions, which are the same for all types of lambda functions.

Then we need to define the lambda resource properties like Runtime, Role, Code and the handler

Yes, the lambda code is defined in local drive. All you need to do is publish and packaging the code in zip format and upload the package in S3.

Sample lambda function config as look like this

To add the lambda function to custom resource, pass the function Arn as the ServiceToken parameter:

This is the part to trigger the lambda function after cloud formation template created

In most cases, we create, update, or delete the cloud formation stack. The lambda function is called on every event.

Create

A Create event is fired when the resource is created.

This is an example of a create event

{“RequestType”: “Create”,“ServiceToken”: “…”,“ResponseURL”: “…”,“StackId”: “…”,“RequestId”: “…”,“LogicalResourceId”: “Custom”,“ResourceType”: “Custom::CustomResource”,“ResourceProperties”: {    “ServiceToken”: “…”,    “CustomParam2”: “value2”,    “CustomParam1”: “value1”    }}

The custom properties from the cloud formation template are stored in ResourceProperties.

Delete

A Delete event is triggered when a resource is deleted. This event is similar to the Create event, except that the RequestType is Delete.

This event can be used to remove any custom resources.

Update

The resource receives an Update event when it is updated.

The new values will be returned by ResourceProperties, while the old values will be returned by OldResourceProperties.

This is an example of an update event

“ResourceProperties”: {    “ServiceToken”: “…”,    “CustomParam2”: “value3”,    “CustomParam1”: “value1”},“OldResourceProperties”: {    “ServiceToken”: “…”,    “CustomParam2”: “value2”,    “CustomParam1”: “value1”}

Handling Outputs

If you use the Data object to send certain values as a response, those values will be available in the template.

For example, If you want to send a parameter named OutParam, it would be like Data: {OutParam:”value”}. Then you can refer it in template with !GetAtt customresource.OutParam

Conclusion

In the Cloud Formation template, custom resources are a powerful property. They support aws and third-party resources of all kinds.

Only things we have to focus on handling the process carefully. Calling the response URL is mandatory by using PUT method. If we failed to add this, we will face the stack creation is in pending state.

About Us

Bi3 has been recognized for being one of the fastest-growing companies in Australia. Our team has delivered substantial and complex projects for some of the largest organizations around the globe and we’re quickly building a brand that is well known for superior delivery.

Website : https://bi3technologies.com/

Follow us on,
LinkedIn : https://www.linkedin.com/company/bi3technologies
Instagram :
https://www.instagram.com/bi3technologies/
Twitter :
https://twitter.com/Bi3Technologies

--

--