Skip to content

Commit 17b57ea

Browse files
Add samples for using hot reloading with terraform, fix role arns (#210)
Co-authored-by: Dominik Schubert <[email protected]>
1 parent 61e8b51 commit 17b57ea

File tree

19 files changed

+402
-15
lines changed

19 files changed

+402
-15
lines changed

cloudwatch-metrics-aws/run.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ awslocal lambda create-function \
1414
--zip-file fileb://failing-lambda.zip \
1515
--handler failing-lambda.lambda_handler \
1616
--runtime python3.8 \
17-
--role my-role
17+
--role arn:aws:iam::000000000000:role/my-role
1818

1919
echo 'creating sns topic'
2020
topic_arn=$(awslocal sns create-topic --name my-topic-alarm | jq -r .TopicArn)

lambda-function-urls/javascript/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ run: ## Build, deploy, and invoke the Lambda function URL
1616
--runtime nodejs14.x \
1717
--zip-file fileb://function.zip \
1818
--handler index.handler \
19-
--role cool-stacklifter
19+
--role arn:aws:iam::000000000000:role/cool-stacklifter
2020

2121
awslocal lambda create-function-url-config \
2222
--function-name localstack-lamba-url-example \

lambda-function-urls/javascript/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ awslocal lambda create-function \
2525
--runtime nodejs14.x \
2626
--zip-file fileb://function.zip \
2727
--handler index.handler \
28-
--role cool-stacklifter
28+
--role arn:aws:iam::000000000000:role/cool-stacklifter
2929
```
3030

3131
## Creating a Lambda function URL

lambda-function-urls/python/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ run: ## Build, deploy, and invoke the Lambda function URL
1818
--timeout 10 \
1919
--zip-file fileb://function.zip \
2020
--handler lambda_function.lambda_handler \
21-
--role cool-stacklifter
21+
--role arn:aws:iam::000000000000:role/cool-stacklifter
2222

2323
awslocal lambda create-function-url-config \
2424
--function-name trending \
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
!layer_src/**
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# LocalStack Demo: Hot code swapping for Lambda functions using LocalStack’s code mounting in JavaScript
2+
3+
## Prerequisites
4+
5+
* LocalStack Pro
6+
* Docker
7+
* [awslocal](https://github.com/localstack/awscli-local) CLI
8+
* Terraform
9+
* [tflocal](https://github.com/localstack/terraform-local) CLI
10+
11+
## Introduction to the sample
12+
In this sample, we demonstrate a hot reloading setup where both the function code and the layer code are hot reloaded.
13+
Any changes to either of those two directories will reload the function. The changed code will be available almost immediately for the next invocation.
14+
15+
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.
16+
17+
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.
18+
19+
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/).
20+
21+
22+
## Starting up
23+
24+
First, we need to make sure we start LocalStack with the right configuration.
25+
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.
26+
27+
```bash
28+
PROVIDER_OVERRIDE_LAMBDA=v2 localstack start
29+
```
30+
31+
Accordingly, if you are launching LocalStack via Docker or Docker Compose:
32+
33+
```bash
34+
#docker-compose.yml
35+
36+
services:
37+
localstack:
38+
...
39+
environment:
40+
...
41+
- PROVIDER_OVERRIDE_LAMBDA=v2
42+
```
43+
44+
## Deploying
45+
46+
Now we can deploy our terraform stack by using `tflocal`.
47+
First, we initialize the terraform working directory using:
48+
49+
```bash
50+
tflocal init
51+
```
52+
53+
Afterwards, we can deploy our stack on LocalStack:
54+
55+
```bash
56+
tflocal apply
57+
```
58+
59+
The terraform configuration will automatically deploy the lambda with hot reloading for the function code.
60+
The function code consists of the contents of the `lambda_src` subdirectory and the layer code in the `layer_src` subdirectory.
61+
62+
## Invoking the Lambda function
63+
64+
We can quickly make sure that our deployed function works by invoking it with a simple payload:
65+
66+
```bash
67+
awslocal lambda invoke --function-name hotreloadlambda output.txt
68+
```
69+
70+
The invocation response:
71+
72+
```json
73+
{
74+
"Number1": 21,
75+
"Number2": 31,
76+
"Sum": 52,
77+
"Product": 651,
78+
"Difference": 10,
79+
"Quotient": 0.6774193548387096
80+
}
81+
```
82+
83+
## Changing things up
84+
85+
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.
86+
87+
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:
88+
89+
```json
90+
{
91+
"Number1": 21,
92+
"Number2": 20,
93+
"Sum": 41,
94+
"Product": 420,
95+
"Difference": 1,
96+
"Quotient": 1.05
97+
}
98+
```
99+
100+
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.
101+
102+
Our output after another invoke will be:
103+
104+
```json
105+
{
106+
"Number1": 10,
107+
"Number2": 20,
108+
"Sum": 30,
109+
"Product": 200,
110+
"Difference": 10,
111+
"Quotient": 0.5
112+
}
113+
```
114+
115+
Now we can change layer and function independently or together, and test the outcome in real time.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
const testDep = require('test-dep')
2+
3+
exports.handler = async function (event, context) {
4+
var number1 = testDep();
5+
var number2 = 31;
6+
var sum = number1 + number2;
7+
var product = number1 * number2;
8+
var difference = Math.abs(number1 - number2);
9+
var quotient = number1 / number2;
10+
return {
11+
"Number1": number1,
12+
"Number2": number2,
13+
"Sum": sum,
14+
"Product": product,
15+
"Difference": difference,
16+
"Quotient": quotient
17+
};
18+
};

lambda-hot-reloading/javascript-terraform-layers/layer_src/nodejs/node_modules/test-dep/index.js

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
terraform {
2+
required_providers {
3+
aws = {
4+
source = "hashicorp/aws"
5+
version = "~> 4.0"
6+
}
7+
}
8+
}
9+
10+
# Configure the AWS Provider
11+
provider "aws" {
12+
region = "us-east-1"
13+
}
14+
15+
resource "aws_iam_role" "iam_for_lambda" {
16+
name = "iam_for_lambda"
17+
18+
assume_role_policy = <<EOF
19+
{
20+
"Version": "2012-10-17",
21+
"Statement": [
22+
{
23+
"Action": "sts:AssumeRole",
24+
"Principal": {
25+
"Service": "lambda.amazonaws.com"
26+
},
27+
"Effect": "Allow",
28+
"Sid": ""
29+
}
30+
]
31+
}
32+
EOF
33+
}
34+
35+
resource "aws_lambda_layer_version" "test_layer" {
36+
layer_name = "hot_reload_layer"
37+
compatible_runtimes = ["nodejs16.x"]
38+
39+
s3_bucket = "hot-reload"
40+
s3_key = "${abspath(path.root)}/layer_src"
41+
42+
}
43+
44+
resource "aws_lambda_function" "test_lambda" {
45+
# If the file is not in the current working directory you will need to include a
46+
# path.module in the filename.
47+
function_name = "hotreloadlambda"
48+
role = aws_iam_role.iam_for_lambda.arn
49+
handler = "index.handler"
50+
51+
52+
s3_bucket = "hot-reload"
53+
s3_key = "${abspath(path.root)}/lambda_src"
54+
layers = [aws_lambda_layer_version.test_layer.arn]
55+
56+
runtime = "nodejs16.x"
57+
58+
environment {
59+
variables = {
60+
foo = "bar"
61+
}
62+
}
63+
}
64+
65+
output "hot_reloading_lambda_arn" {
66+
value = aws_lambda_function.test_lambda.arn
67+
}
68+
69+
output "hot_reloading_layer_arn" {
70+
value = aws_lambda_layer_version.test_layer.arn
71+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# LocalStack Demo: Hot code swapping for Lambda functions using LocalStack’s code mounting in JavaScript
2+
3+
## Prerequisites
4+
5+
* LocalStack
6+
* Docker
7+
* [awslocal](https://github.com/localstack/awscli-local) CLI
8+
* Terraform
9+
* [tflocal](https://github.com/localstack/terraform-local) CLI
10+
11+
## Introduction to the sample
12+
Other than the deployment of the sample, it is practically identical to [our javascript hot reloading sample](../javascript/).
13+
14+
We will use terraform to deploy a hot reloaded lambda function, and then interact with it by invoking it and changing its source.
15+
16+
The source code of the created lambda function `hotreloadlambda` is located in the subfolder [lambda_src](./lambda_src/).
17+
18+
19+
## Starting up
20+
21+
First, we need to make sure we start LocalStack with the right configuration.
22+
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.
23+
24+
25+
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):
26+
27+
```bash
28+
LAMBDA_REMOTE_DOCKER=0 localstack start
29+
```
30+
31+
Accordingly, if you are launching LocalStack via Docker or Docker Compose:
32+
33+
```bash
34+
#docker-compose.yml
35+
36+
services:
37+
localstack:
38+
...
39+
environment:
40+
...
41+
- LAMBDA_REMOTE_DOCKER=0
42+
```
43+
44+
## Deploying
45+
46+
Now we can deploy our terraform stack by using `tflocal`.
47+
First, we initialize the terraform working directory using:
48+
49+
```bash
50+
tflocal init
51+
```
52+
53+
We can now check the plan of terraform for our deployment:
54+
55+
```bash
56+
tflocal plan
57+
```
58+
59+
Afterwards, we can deploy our stack on LocalStack:
60+
61+
```bash
62+
tflocal apply
63+
```
64+
65+
The terraform configuration will automatically deploy the lambda with hot reloading for the function code.
66+
The function code will be the contents of the `lambda_src` subdirectory.
67+
68+
## Invoking the Lambda function
69+
70+
We can quickly make sure that it works by invoking it with a simple payload:
71+
72+
```bash
73+
awslocal lambda invoke --function-name hotreloadlambda output.txt
74+
```
75+
76+
The invocation itself returns:
77+
78+
```json
79+
{
80+
"Difference": 10,
81+
"Number1": 21,
82+
"Number2": 31,
83+
"Product": 651,
84+
"Quotient": 0.6774193548387096,
85+
"Sum": 52
86+
}
87+
```
88+
89+
## Changing things up
90+
91+
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.
92+
93+
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:
94+
95+
```json
96+
{
97+
"Difference": 10,
98+
"Number1": 10,
99+
"Number2": 20,
100+
"Product": 200,
101+
"Quotient": 0.5,
102+
"Sum": 30
103+
}
104+
```
105+

0 commit comments

Comments
 (0)