Feb 14, 2023
AWS CDK + API Gateway and Integrations. A little guide how to.
I’ve been working with CDK and I think is brilliant, the way it lets you define resources and infrastructure using your favorite coding language is awesome, I personally use Python. Sometimes what happens is that CDK takes over a lot of control and creates resources as it thinks is proper… Also, documentation lacks some advanced configuration.
For instance, I come across this AWS documentation page to develop a proxy to S3 using API Gateway. I thought to reproduce the same in CDK, but I faced some issues in defining the integrations.
In this post, I’m going to show how I created the API Gateway, the challenges I faced, and how I solved them, with the hope it might help you too!
So let’s start from the beginning.
Defining REST APIs
To define a REST API you can use the following snippet, in a single row, in CDK, you can define a new set of REST API
my_apig = apig.RestApi(self, "ApigAndS3")
Defining Resources
Now it’s time to define a couple of resources, to be clear our final goal is to create something like the following: http://myapigateway/bucketName/item
where bucketName and item are placeholder the client will pass along with a request body. Whatever is passed in the body will be saved in bucketName/item. Of course, you need to own write permissions on the bucket defined by bucketName. Here again, a couple of lines define two resources. Awesome!
Defining the integration
Here I started to sweat, as defining the integrations per se is not complicated
bucket_integration = apig.AwsIntegration(service="s3", integration_http_method="PUT", path="{bucket}/{object}", region="eu-west-1", options=integration_options)
Is the integration_options really hard to define, considering I got the error apigateway Invalid mapping expression parameter specified: method.request.path. many, many, times… I couldn’t find an answer online and even the AWS Post here added confusion.
First: what are integration options? Well in integration options you can define how API Gateway will integrate with the defined service, in particular, you can map URL/Body parameters with parameters for your integration. What we aim to do is to use the URL path parameters bucketName/item to define the S3 path where to save the request body payload.
In the AWS console, you do something like this, very far from what you do in CDK
Instead in CDK, you will define something like
integration_response = apig.IntegrationResponse(status_code="200")
integration_options = IntegrationOptions(request_parameters={ "integration.request.path.bucket":"method.request.path.bucketName", "integration.request.path.object":"method.request.path.item",credentials_role=role,
integration_responses=[integration_response])
As you can notice the correct path URL to be passed are integration.request.path.bucket and integration.request.path.object mapped to method.request.path.bucketName and method.request.path.item.
What really helped me is the CLI, commands
aws apigateway get-integration --rest-api-id abcd --resource-id 1234 --http-method POST
aws apigateway get-method --rest-api-id abcd --resource-id 1234 --http-method POST
Final thoughts
CDK is really cool, the documentation needs to be expanded to care also for advanced scenarios, and be extensive to describe all you can actually do.
Use the CLI when in doubt… This always helps.
The full code for this mini-POC can be found here.
If your organisation is scaling its AWS usage and needs help in implementing AWS Guardrails, AWS Control Tower, AWS Landing Zones, and any other AWS Service, please feel free to reach out by visiting our contact page or sending an email to team@virtuability.com.