AWS Lamba Debugging - How to connect to an API on your local(host) machine
One of my recent bald-patch inducing struggles was to develop and test an AWS Lambda function that connects to a REST API to do some stuff.
It is rather nice that you can deploy (using a local Docker container) and debug the said Lambda code in VSCode using the AWS Toolkit extension. In my case, the Lambda attempts to open a connection to a Django REST API which I had running in debug mode on my local machine (i.e. localhost interface).
Seems fairly straightforward. If you haven't previously, you'll probably soon run into the issue of opening an API connection to "localhost" from the Lambda code which doesn't work, since in the container context, that's the container's local connection, not the host's.
So you need to point the API connection at host.docker.internal instead which is already mapped to your physical machine by Docker.
This works like a charm if you are doing straight forward things - like not using prefixes on your domain name. In my case, I was using the django-tenants package which differentiates multiple "customers" on a single database with different schemas, and it uses a name prefix, such as test.localhost to determine which database schema to connect to. The Docker localhost remapping is a one-to-one mapping - wildcards don't work - so trying to connect to test.host.docker.internal results in no connection reaching the host API.
There are a couple of configuration items to be aware of to make this whole scenario work:
On the Django API side:
- In your Django settings.py file, you need to adjust your allowed hosts setting to include .host.docker.internal as this is name of the endpoint as far as the Lambda request is concerned.
- If you are launching your Django REST API from VSCode in order to debug it, make sure you edit your launch.json file to start the server with the "0.0.0.0:portnumber" argument to bind the server to all interfaces on your machine.
- If you are specifically using django-tenants, make sure you add additional domain name entries for the tenant names you are testing into the domain table in your public schema database. For example, if your tenant primary schema name is "test.localhost", you will need to add "test.host.docker.internal" as a non-primary domain as well.
For the Lambda side:
- For local debugging purposes, make sure you are trying to connect to your local Django API on port 8000 via "http://host.docker.internal:8000" instead of "http://localhost:8000".
- Create and then edit your Lambda project's debug launch.json file and add the specific tenant prefix host mappings you need as a "--add-host" localArgument parameter under the "sam" configuration section. You can add multiple mappings - for example, to map "experiment" and "test" tenant domains to be passed to your localhost API:
- In the above configuration, note that host-gateway is a docker-defined alias to your host machine.
Comments
Post a Comment