AWS Chalice + Terraform Part 2: Local Development With LocalStack
In part 1 we went through the basics of AWS Chalice and how to integrate it with Terraform. You can check that here:
AWS Chalice + Terraform: A serverless codebase that makes senseSo far we have deployed our infrastructure against the cloud. This could be a slow process during development, even more if debugging a pesky error.
It is possible to deploy our infrastructure against LocalStack, a project that aims to emulate AWS resources and API calls locally, using Docker as its backend.
How-to
Follow https://github.com/localstack/localstack#running to get up and running with LocalStack. You require to have Docker installed.
The LocalStack team provides chalice-local, a tool that will be useful for checking logs and invoking our functions.
One more tool also provided by the LocalStack team that we are going to use is awscli-local, which is simply the AWS CLI with some configuration to run against LocalStack, instead of actual AWS servers.
We can install all these tools using pip
:
1 | pip install localstack chalice-local awscli-local |
You can add these to requirements-dev.txt
for local development purposes:
1 | -r requirements-ci.txt # Installs the base dependencies |
These are the steps followed to run the sample app we have built so far locally:
1. Configure and start LocalStack:
We can start all the Docker containers that LocalStack provides with the following command:
1 | # The list of services we want to enable in LocalStack |
Keep in mind that once we stop the server, all infrastructure will be lost.
2. Configure the AWS Terraform provider to point to LocalStack:
We need to tell Terraform that we don’t want to hit the default AWS endpoints, but our own instead. We also need to mock authentication and disable some checks to speed up the process. We can do this by modifying the AWS provider:
1 | provider "aws" { |
You can read more about the AWS Terraform provider endpoint customization here:
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/guides/custom-service-endpoints#localstack
Lastly we can add an output with the format LocalStack follows for API Gateway:
1 | output "local_url" { |
More info here:
https://github.com/localstack/localstack#invoking-api-gateway
3. Add a local stage to the Chalice config file
LocalStack isn’t perfect. Sometimes their API fails to retrieve VPC data (among other errors). One way of getting around these errors is disabling VPC locally:
1 | { |
Here we keep our Security group and Subnet configuration for all of our functions on all stages but local, where we manually disable them.
4. Package the app with the local stage configuration
Here we are packaging the app as before, but passing the --stage
flag to specify we want the local configuration:
1 | chalice package --stage local --pkg-format terraform . |
5. Apply the Terraform code against LocalStack
We are ready to apply the Terraform code and create our infrastructure locally:
1 | # Refreshing against LocalStack can be unstable. We don't really need it here so we can disable it |
If everything goes right, you should have the same application you had in AWS up and running locally. You may have also noticed that applying against LocalStack is blazing fast compared to AWS.
During development iteration, you can use the following script to package, fix and apply your code quickly against LocalStack:
1 | chalice package --pkg-format terraform . --stage local |
Nothing that we haven’t seen before, but pretty useful to have on a apply.sh
script.
Running our local functions
We can trigger our HTTP enabled function by hitting the local API Gateway url using curl
:
1 | curl http://localhost:4566/restapis/ur5mwyfjy6/local/_user_request_/ |
To hit the local SNS and SQS server and trigger those functions, we will use awslocal
:
1 | awslocal sns publish --topic-arn arn:aws:sns:us-east-1:000000000000:chalice-tf-topic --message "local SNS" |
See the logs of the local functions and confirm they ran:
1 | chalice-local logs --stage local --name handle_sns_message |
1 | chalice-local logs --stage local --name handle_sqs_message |
intermittent SQS Error
1 | curl http://localhost:4566/restapis/a0ah4jhr1g/local/_user_request_/ |
What’s next
Hopefully with this local setup you can increase your development speed and comfort. Up next, let’s test our new app. You can check the third part of the series here:
AWS Chalice + Terraform Part 3: Testing your app