-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add samples for using hot reloading with terraform, fix role arns (#210)
Co-authored-by: Dominik Schubert <[email protected]>
- Loading branch information
1 parent
61e8b51
commit 17b57ea
Showing
19 changed files
with
402 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
!layer_src/** |
115 changes: 115 additions & 0 deletions
115
lambda-hot-reloading/javascript-terraform-layers/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
# LocalStack Demo: Hot code swapping for Lambda functions using LocalStack’s code mounting in JavaScript | ||
|
||
## Prerequisites | ||
|
||
* LocalStack Pro | ||
* Docker | ||
* [awslocal](https://github.com/localstack/awscli-local) CLI | ||
* Terraform | ||
* [tflocal](https://github.com/localstack/terraform-local) CLI | ||
|
||
## Introduction to the sample | ||
In this sample, we demonstrate a hot reloading setup where both the function code and the layer code are hot reloaded. | ||
Any changes to either of those two directories will reload the function. The changed code will be available almost immediately for the next invocation. | ||
|
||
We will again re-use the sample from our [javascript](../javascript/) sample, but one of the values we want to change is supplied by a function defined in our layer. | ||
|
||
We will use terraform to deploy a hot reloaded lambda function and invoke it once. Afterwards we will change its source and invoke it again to demonstrate the hot-reload feature. | ||
|
||
The source code of the created lambda function `hotreloadlambda` is located in the subfolder [lambda_src](./lambda_src/) and the source code of the created layer `hot_reload_layer` is located in the subfolder [layer_src](./layer_src/). | ||
|
||
|
||
## Starting up | ||
|
||
First, we need to make sure we start LocalStack with the right configuration. | ||
Hot reloading of layers is only supported in our new lambda provider, all you need to do is set `PROVIDER_OVERRIDE_LAMBDA=v2`, if you use a LocalStack version < 2.0. | ||
|
||
```bash | ||
PROVIDER_OVERRIDE_LAMBDA=v2 localstack start | ||
``` | ||
|
||
Accordingly, if you are launching LocalStack via Docker or Docker Compose: | ||
|
||
```bash | ||
#docker-compose.yml | ||
|
||
services: | ||
localstack: | ||
... | ||
environment: | ||
... | ||
- PROVIDER_OVERRIDE_LAMBDA=v2 | ||
``` | ||
|
||
## Deploying | ||
|
||
Now we can deploy our terraform stack by using `tflocal`. | ||
First, we initialize the terraform working directory using: | ||
|
||
```bash | ||
tflocal init | ||
``` | ||
|
||
Afterwards, we can deploy our stack on LocalStack: | ||
|
||
```bash | ||
tflocal apply | ||
``` | ||
|
||
The terraform configuration will automatically deploy the lambda with hot reloading for the function code. | ||
The function code consists of the contents of the `lambda_src` subdirectory and the layer code in the `layer_src` subdirectory. | ||
|
||
## Invoking the Lambda function | ||
|
||
We can quickly make sure that our deployed function works by invoking it with a simple payload: | ||
|
||
```bash | ||
awslocal lambda invoke --function-name hotreloadlambda output.txt | ||
``` | ||
|
||
The invocation response: | ||
|
||
```json | ||
{ | ||
"Number1": 21, | ||
"Number2": 31, | ||
"Sum": 52, | ||
"Product": 651, | ||
"Difference": 10, | ||
"Quotient": 0.6774193548387096 | ||
} | ||
``` | ||
|
||
## Changing things up | ||
|
||
Now, that we got everything up and running, the real fun begins. Because the function code directory, in our case `./lambda_src`, is mounted directly into the executing container, any changes that we make in this folder will be reflected in the execution almost instantly. | ||
|
||
To demonstrate this behavior, we can now make a minor change to the API and replace `number2` with a new value, let's say 20. Without redeploying or updating the function, the result of the previous request will look like this: | ||
|
||
```json | ||
{ | ||
"Number1": 21, | ||
"Number2": 20, | ||
"Sum": 41, | ||
"Product": 420, | ||
"Difference": 1, | ||
"Quotient": 1.05 | ||
} | ||
``` | ||
|
||
We can now also change the value provided by our layer. Let's replace it with 10, by editing the index.js in our `./layer_src/nodejs/node_modules/test-dep` folder. | ||
|
||
Our output after another invoke will be: | ||
|
||
```json | ||
{ | ||
"Number1": 10, | ||
"Number2": 20, | ||
"Sum": 30, | ||
"Product": 200, | ||
"Difference": 10, | ||
"Quotient": 0.5 | ||
} | ||
``` | ||
|
||
Now we can change layer and function independently or together, and test the outcome in real time. |
18 changes: 18 additions & 0 deletions
18
lambda-hot-reloading/javascript-terraform-layers/lambda_src/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
const testDep = require('test-dep') | ||
|
||
exports.handler = async function (event, context) { | ||
var number1 = testDep(); | ||
var number2 = 31; | ||
var sum = number1 + number2; | ||
var product = number1 * number2; | ||
var difference = Math.abs(number1 - number2); | ||
var quotient = number1 / number2; | ||
return { | ||
"Number1": number1, | ||
"Number2": number2, | ||
"Sum": sum, | ||
"Product": product, | ||
"Difference": difference, | ||
"Quotient": quotient | ||
}; | ||
}; |
5 changes: 5 additions & 0 deletions
5
...hot-reloading/javascript-terraform-layers/layer_src/nodejs/node_modules/test-dep/index.js
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
terraform { | ||
required_providers { | ||
aws = { | ||
source = "hashicorp/aws" | ||
version = "~> 4.0" | ||
} | ||
} | ||
} | ||
|
||
# Configure the AWS Provider | ||
provider "aws" { | ||
region = "us-east-1" | ||
} | ||
|
||
resource "aws_iam_role" "iam_for_lambda" { | ||
name = "iam_for_lambda" | ||
|
||
assume_role_policy = <<EOF | ||
{ | ||
"Version": "2012-10-17", | ||
"Statement": [ | ||
{ | ||
"Action": "sts:AssumeRole", | ||
"Principal": { | ||
"Service": "lambda.amazonaws.com" | ||
}, | ||
"Effect": "Allow", | ||
"Sid": "" | ||
} | ||
] | ||
} | ||
EOF | ||
} | ||
|
||
resource "aws_lambda_layer_version" "test_layer" { | ||
layer_name = "hot_reload_layer" | ||
compatible_runtimes = ["nodejs16.x"] | ||
|
||
s3_bucket = "hot-reload" | ||
s3_key = "${abspath(path.root)}/layer_src" | ||
|
||
} | ||
|
||
resource "aws_lambda_function" "test_lambda" { | ||
# If the file is not in the current working directory you will need to include a | ||
# path.module in the filename. | ||
function_name = "hotreloadlambda" | ||
role = aws_iam_role.iam_for_lambda.arn | ||
handler = "index.handler" | ||
|
||
|
||
s3_bucket = "hot-reload" | ||
s3_key = "${abspath(path.root)}/lambda_src" | ||
layers = [aws_lambda_layer_version.test_layer.arn] | ||
|
||
runtime = "nodejs16.x" | ||
|
||
environment { | ||
variables = { | ||
foo = "bar" | ||
} | ||
} | ||
} | ||
|
||
output "hot_reloading_lambda_arn" { | ||
value = aws_lambda_function.test_lambda.arn | ||
} | ||
|
||
output "hot_reloading_layer_arn" { | ||
value = aws_lambda_layer_version.test_layer.arn | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
# LocalStack Demo: Hot code swapping for Lambda functions using LocalStack’s code mounting in JavaScript | ||
|
||
## Prerequisites | ||
|
||
* LocalStack | ||
* Docker | ||
* [awslocal](https://github.com/localstack/awscli-local) CLI | ||
* Terraform | ||
* [tflocal](https://github.com/localstack/terraform-local) CLI | ||
|
||
## Introduction to the sample | ||
Other than the deployment of the sample, it is practically identical to [our javascript hot reloading sample](../javascript/). | ||
|
||
We will use terraform to deploy a hot reloaded lambda function, and then interact with it by invoking it and changing its source. | ||
|
||
The source code of the created lambda function `hotreloadlambda` is located in the subfolder [lambda_src](./lambda_src/). | ||
|
||
|
||
## Starting up | ||
|
||
First, we need to make sure we start LocalStack with the right configuration. | ||
To use our new lambda provider, all you need to do is set `PROVIDER_OVERRIDE_LAMBDA=v2`, if you use a LocalStack version < 2.0. | ||
|
||
|
||
If you want to use our old provider, please set `LAMBDA_REMOTE_DOCKER` to `0` (see the [Configuration Documentation](https://docs.localstack.cloud/localstack/configuration/#lambda) for more information): | ||
|
||
```bash | ||
LAMBDA_REMOTE_DOCKER=0 localstack start | ||
``` | ||
|
||
Accordingly, if you are launching LocalStack via Docker or Docker Compose: | ||
|
||
```bash | ||
#docker-compose.yml | ||
|
||
services: | ||
localstack: | ||
... | ||
environment: | ||
... | ||
- LAMBDA_REMOTE_DOCKER=0 | ||
``` | ||
|
||
## Deploying | ||
|
||
Now we can deploy our terraform stack by using `tflocal`. | ||
First, we initialize the terraform working directory using: | ||
|
||
```bash | ||
tflocal init | ||
``` | ||
|
||
We can now check the plan of terraform for our deployment: | ||
|
||
```bash | ||
tflocal plan | ||
``` | ||
|
||
Afterwards, we can deploy our stack on LocalStack: | ||
|
||
```bash | ||
tflocal apply | ||
``` | ||
|
||
The terraform configuration will automatically deploy the lambda with hot reloading for the function code. | ||
The function code will be the contents of the `lambda_src` subdirectory. | ||
|
||
## Invoking the Lambda function | ||
|
||
We can quickly make sure that it works by invoking it with a simple payload: | ||
|
||
```bash | ||
awslocal lambda invoke --function-name hotreloadlambda output.txt | ||
``` | ||
|
||
The invocation itself returns: | ||
|
||
```json | ||
{ | ||
"Difference": 10, | ||
"Number1": 21, | ||
"Number2": 31, | ||
"Product": 651, | ||
"Quotient": 0.6774193548387096, | ||
"Sum": 52 | ||
} | ||
``` | ||
|
||
## Changing things up | ||
|
||
Now, that we got everything up and running, the fun begins. Because the function code directory, in our case `./lambda_src` is mounted into the executing container, any change that we save in this folder will affect the execution almost instantly. | ||
|
||
For example, we can now make a minor change to the API and replace the `number1` and `number2` with new values, let's say 10 and 20. Without redeploying or updating the function, the result of the previous request will look like this: | ||
|
||
```json | ||
{ | ||
"Difference": 10, | ||
"Number1": 10, | ||
"Number2": 20, | ||
"Product": 200, | ||
"Quotient": 0.5, | ||
"Sum": 30 | ||
} | ||
``` | ||
|
16 changes: 16 additions & 0 deletions
16
lambda-hot-reloading/javascript-terraform/lambda_src/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
exports.handler = async function (event, context) { | ||
var number1 = 21; | ||
var number2 = 31; | ||
var sum = number1 + number2; | ||
var product = number1 * number2; | ||
var difference = Math.abs(number1 - number2); | ||
var quotient = number1 / number2; | ||
return { | ||
"Number1": number1, | ||
"Number2": number2, | ||
"Sum": sum, | ||
"Product": product, | ||
"Difference": difference, | ||
"Quotient": quotient | ||
}; | ||
}; |
Oops, something went wrong.