The cuckoo egg testing lambda



Oh, there is an error in my Lambda function. But - what is the event JSON input which caused the error? Oh, I forgot to log the event in my Lambda code. Damned! It would be great to swap the code with a “just dump the event code” and slip it like a cuckoo egg. Afterwards, get the event and restore the old Lambda!

No problem!

Swap

Only some people know that you can also download the function code of a Lambda function. This can be done via the Code.Location property in the get-function API call. This property contains a presigned URL to download the function code.

That means we could save the old function code and swap it with the test “cuckoo egg” function code. Then we store the event and restore the function afterwards.

You could also use this pattern to replace Lambda functions in a distributed system with mock Functions, which respond with a fixed value.

swap

Walkthrough

These are the steps:

  1. Save old Lambda, download code
aws lambda get-function
        --function-name "{{.NAME}}"
        --query 'Code.Location'
        --output text >download.txt
wget -i download.txt -O {{.CODE}}

You must also store the Function Name, the Runtime and the handler. The language and the handler will often be the same as in your other Lambda Functions.

  1. Deploy egg
  aws lambda update-function-configuration --runtime go1.x --function-name {{.NAME}} --handler main
  aws lambda update-function-code --function-name  {{.NAME}} --zip-file fileb://./dist/main.zip

The function for the event is of course written in GO. Should be easy to port to other languages.

  1. Create event, get data from CloudWatch logs

  2. Restore old code:

aws lambda update-function-configuration --runtime {{.RUNTIME}} --function-name {{.NAME}} --handler {{.HANDLER}}
aws lambda update-function-code --function-name  {{.NAME}} --zip-file fileb://{{.CODE}}

All steps are coded in the Taskfile.yml file. See the Repo on github

Usage with taskfile.dev

See Taskfile.yaml

A) Get code from github

B) Update the Taskfile.yml with your values:

NAME: polly-notes-api-searchFunction
RUNTIME: python3.8
HANDLER: app.lambda_handler
CODE: code.zip

These are example values.

  1. Save: task save
  2. Deploy: task deploy
  3. Invoke Lambda with event
  4. Restore: task restore

Save

task save
task: [save] aws lambda get-function --function-name "polly-notes-api-searchFunction" --query 'Code.Location' --output text >download.txt
task: [save] wget -i download.txt -O code.zip
--2023-06-19 18:07:27--  https://awslambda-eu-cent-1-tasks.s3.eu-central-1.amazonaws.com/snapshots/139008737997/polly-notes-api-searchFunction-***
&X-Amz-Credential=ASIAZ***%2Feu-central-1%2Fs3%2Faws4_request
&X-Amz-Signature=00***7
Auflösen des Hostnamens awslambda-eu-cent-1-tasks.s3.eu-central-1.amazonaws.com (awslambda-eu-cent-1-tasks.s3.eu-central-1.amazonaws.com)… 52.219.171.254
Verbindungsaufbau zu awslambda-eu-cent-1-tasks.s3.eu-central-1.amazonaws.com (awslambda-eu-cent-1-tasks.s3.eu-central-1.amazonaws.com)|52.219.171.254|:443 … verbunden.
HTTP-Anforderung gesendet, auf Antwort wird gewartet … 200 OK
Länge: 12042877 (11M) [application/zip]
Wird in »code.zip« gespeichert.

code.zip                                    100%[========================================================================================>]  11,48M  23,9MB/s    in 0,5s

2023-06-19 18:07:28 (23,9 MB/s) - »code.zip« gespeichert [12042877/12042877]

BEENDET --2023-06-19 18:07:28--
Verstrichene Zeit: 1,0s
Geholt: 1 Dateien, 11M in 0,5s (23,9 MB/s)

Deploy

task deploy
updating: main (deflated 58%)
task: [deploy] aws lambda update-function-configuration --runtime go1.x --function-name polly-notes-api-searchFunction --handler main
{
    "FunctionName": "polly-notes-api-searchFunction",
    ...
    "Runtime": "go1.x",
    ...
}
task: [deploy] aws lambda update-function-code --function-name  polly-notes-api-searchFunction --zip-file fileb://./dist/main.zip
{
    "FunctionName": "polly-notes-api-searchFunction",
    "Runtime": "go1.x",
    "Handler": "main",
    "CodeSize": 2691074,
    ...
    "PackageType": "Zip",
    ...
}

Restore

task restore
task: [restore] aws lambda update-function-configuration --runtime python3.8 --function-name polly-notes-api-searchFunction --handler app.lambda_handler
{
    "FunctionName": "polly-notes-api-searchFunction",
    ...
    "Runtime": "python3.8",
    ...
    "Handler": "app.lambda_handler",
    ...
}
task: [restore] aws lambda update-function-code --function-name  polly-notes-api-searchFunction-GdFQpjWz1XKZ --zip-file fileb://code.zip
{
    "FunctionName": "polly-notes-api-searchFunction",
    ...
    "Runtime": "python3.8",
    ...
    "Handler": "app.lambda_handler",
    "CodeSize": 12042877,
    ...
}

Conclusion

With this little trick, you can inject test code into a running Lambda based microservice system and restore the old environment afterwards.

Happy building!

If you need consulting for your serverless project, don’t hesitate to get in touch with the sponsor of this blog, tecRacer.

For more AWS development stuff, follow me on dev https://dev.to/megaproaktiv. Want to learn GO on AWS? GO here

See also

Similar Posts You Might Enjoy

Harnessing the Power of Serverless PHP with Laravel Vapor

I need to start this blog post with a confession. But only if you promise to not tell anything to my tecRacer colleagues, deal? So, I built a monolith. And I loved it. And you will likely love it too if you decide to try out Laravel. Luckily, there is a service called Vapor that will let you deploy your Laravel project on serverless AWS infrastructure. That means I can continue to enjoy the top-notch developer experience of Laravel while also getting all the benefits of serverless technologies (plus, I can maintain a healthy relationship with my colleagues 🎉). But let’s start at the beginning. - by Leon Bittner

Amazon Pinpoint - How it works

If you need omni-channel engagement with your customers to run marketing campaigns, send notifications, or tailored (transactional) messages in bulk, then Amazon Pinpoint is the right tool for you. It allows you to manage your audience and templates and reach customers through email, text, voice messages, custom channels and push or in-app notifications. The provided events and analytics make it easy to track and measure the results of your campaigns and gain valuable insights about customer interactions. - by Emilia Nenova

Serverless Swagger UI for AWS API Gateway

When implementing REST APIs in AWS there is one service that always comes to mind - Amazon API Gateway. Even though feature-rich, properly documenting your API may become a time-consuming task relatively quickly. In this post, I would like to show you how you can use Swagger UI in combination with a serverless deployment to automatically generate interactive and up-to-date documentation for your APIs. - by Hendrik Hagen