Add the code for localstack posts

master
Baptiste Bouchereau 2019-08-27 18:10:26 +02:00
rodzic 0decf40b90
commit 08740af94e
9 zmienionych plików z 345 dodań i 0 usunięć

5
.gitignore vendored 100644
Wyświetl plik

@ -0,0 +1,5 @@
.terraform/
*.zip
output.txt
terraform.tfstate
terraform.tfstate.backup

Wyświetl plik

@ -7,3 +7,5 @@ The code from some of my blog posts.
- [Profile PHP applications with xhgui and xhprof on docker](docker-xhprof-xhgui)
- [Debug PHP applications running on docker with vscode](docker-vscode-php-xdebug)
- [Backup docker volumes with borg](docker-volume-borg-backup)
- [A guide to localstack (part 1) - How to mock Amazon web services in local](localstack-part-1)
- [A guide to localstack (part 2) - deploying resources with Terraform](localstack-part-2)

Wyświetl plik

@ -0,0 +1,58 @@
Replicate AWS in local with localstack
======================================
An example on how to use localstack to mock AWS services. The following instructions focus on how to run localstack and deploy:
* a dynamodb table
* a lambda reading data and putting data to this table
Usage
-----
Run
```bash
docker-compose up -d
docker-compose logs -f localstack
```
Wait for set up to be done, then create a dynamodb table:
```bash
aws dynamodb create-table \
--endpoint-url http://localhost:4569 \
--table-name table_1 \
--attribute-definitions AttributeName=id,AttributeType=S \
--key-schema AttributeName=id,KeyType=HASH \
--provisioned-throughput ReadCapacityUnits=20,WriteCapacityUnits=20
```
To check if the table was properly created, run:
```bash
aws dynamodb list-tables --endpoint-url http://localhost:4569
```
Create and deploy the lambda function:
```bash
cd lambda
zip -r ../lambda.zip .
cd ..
aws lambda create-function \
--function-name counter \
--runtime nodejs8.10 \
--role fake_role \
--handler main.handler \
--endpoint-url http://localhost:4574 \
--zip-file fileb://$PWD/lambda.zip
```
Invoke the function multiple times and scan the table to see new items and their counters being incremented:
``bash
aws lambda invoke --function-name counter --endpoint-url=http://localhost:4574 --payload '{"id": "test"}' output.txt
aws dynamodb scan --endpoint-url http://localhost:4569 --table-name table_1
aws lambda invoke --function-name counter --endpoint-url=http://localhost:4574 --payload '{"id": "test2"}' output.txt
aws dynamodb scan --endpoint-url http://localhost:4569 --table-name table_1
```

Wyświetl plik

@ -0,0 +1,32 @@
version: '3.3'
networks:
default:
external:
name: localstack-tutorial
volumes:
localstack:
services:
localstack:
image: localstack/localstack:0.9.0
ports:
- 8080:8080 # webui
- 4569:4569 # dynamodb
- 4574:4574 # lamba
environment:
- DATA_DIR=/tmp/localstack/data
- DEBUG=1
- DEFAULT_REGION=ap-southeast-2
- DOCKER_HOST=unix:///var/run/docker.sock
- LAMBDA_EXECUTOR=docker-reuse
- PORT_WEB_UI=8080
- SERVICES=lambda,dynamodb
- LAMBDA_DOCKER_NETWORK=localstack-tutorial
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- localstack:/tmp/localstack/data

Wyświetl plik

@ -0,0 +1,66 @@
'use strict';
const AWS = require('aws-sdk');
AWS.config.update({
region: 'ap-southeast-2',
endpoint: 'http://localstack:4569'
});
class DynamoDBService {
constructor() {
this.docClient = new AWS.DynamoDB.DocumentClient({ apiVersion: '2012-08-10' });
}
async increment(id) {
return new Promise(async (resolve, reject) => {
try {
const count = await this.getCount(id);
var params = {
TableName: 'table_1',
Item: {
count: count + 1,
id: id
}
};
this.docClient.put(params, function(err, data) {
if (err) {
reject(err);
} else {
resolve(data);
}
});
} catch (err) {
reject(err);
}
});
}
async getCount(id) {
return new Promise(async (resolve, reject) => {
var params = {
TableName: 'table_1',
Key: {id}
};
this.docClient.get(params, function(err, data) {
if (err) {
reject(err);
} else {
resolve(data['Item'] ? data['Item']['count'] : 0);
}
});
});
}
}
exports.handler = async (event, context, callback) => {
try {
const dynamoDBService = new DynamoDBService();
await dynamoDBService.increment(event.id);
callback(null, {});
} catch (error) {
callback(error);
}
}

Wyświetl plik

@ -0,0 +1,42 @@
Deploy AWS resources in localstack with Terraform
=================================================
An example on how to use Terraform to deploy localstack resources that mock AWS services. The following instructions focus on how to deploy:
* a dynamodb table
* a lambda reading data and putting data to this table
Usage
-----
Run
```bash
docker-compose up -d
docker-compose logs -f localstack
```
Create the lambda:
```bash
cd lambda
zip -r ../lambda.zip .
cd ..
```
Wait for set up to be done, then apply the Terraform configuration:
```bash
terraform init
terraform plan
terraform apply --auto-approve
```
Invoke the lambda multiple times and scan the table to see new items and their counters being incremented:
``bash
aws lambda invoke --function-name counter --endpoint-url=http://localhost:4574 --payload '{"id": "test"}' output.txt
aws dynamodb scan --endpoint-url http://localhost:4569 --table-name table_1
aws lambda invoke --function-name counter --endpoint-url=http://localhost:4574 --payload '{"id": "test2"}' output.txt
aws dynamodb scan --endpoint-url http://localhost:4569 --table-name table_1
```

Wyświetl plik

@ -0,0 +1,32 @@
version: '3.3'
networks:
default:
external:
name: localstack-tutorial
volumes:
localstack:
services:
localstack:
image: localstack/localstack:0.9.0
ports:
- 8080:8080 # webui
- 4569:4569 # dynamodb
- 4574:4574 # lamba
environment:
- DATA_DIR=/tmp/localstack/data
- DEBUG=1
- DEFAULT_REGION=ap-southeast-2
- DOCKER_HOST=unix:///var/run/docker.sock
- LAMBDA_EXECUTOR=docker-reuse
- PORT_WEB_UI=8080
- SERVICES=lambda,dynamodb
- LAMBDA_DOCKER_NETWORK=localstack-tutorial
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- localstack:/tmp/localstack/data

Wyświetl plik

@ -0,0 +1,66 @@
'use strict';
const AWS = require('aws-sdk');
AWS.config.update({
region: 'ap-southeast-2',
endpoint: 'http://localstack:4569'
});
class DynamoDBService {
constructor() {
this.docClient = new AWS.DynamoDB.DocumentClient({ apiVersion: '2012-08-10' });
}
async increment(id) {
return new Promise(async (resolve, reject) => {
try {
const count = await this.getCount(id);
var params = {
TableName: 'table_1',
Item: {
count: count + 1,
id: id
}
};
this.docClient.put(params, function(err, data) {
if (err) {
reject(err);
} else {
resolve(data);
}
});
} catch (err) {
reject(err);
}
});
}
async getCount(id) {
return new Promise(async (resolve, reject) => {
var params = {
TableName: 'table_1',
Key: {id}
};
this.docClient.get(params, function(err, data) {
if (err) {
reject(err);
} else {
resolve(data['Item'] ? data['Item']['count'] : 0);
}
});
});
}
}
exports.handler = async (event, context, callback) => {
try {
const dynamoDBService = new DynamoDBService();
await dynamoDBService.increment(event.id);
callback(null, {});
} catch (error) {
callback(error);
}
}

Wyświetl plik

@ -0,0 +1,42 @@
provider "aws" {
region = "ap-southeast-2"
access_key = "fake"
secret_key = "fake"
skip_credentials_validation = true
skip_requesting_account_id = true
endpoints {
dynamodb = "http://localhost:4569"
lambda = "http://localhost:4574"
}
}
resource "aws_dynamodb_table" "table_1" {
name = "table_1"
read_capacity = "20"
write_capacity = "20"
hash_key = "id"
attribute {
name = "id"
type = "S"
}
}
resource "aws_lambda_function" "counter" {
function_name = "counter"
filename = "lambda.zip"
role = "fake_role"
handler = "main.handler"
runtime = "nodejs8.10"
timeout = 30
lifecycle {
ignore_changes = [
"environment",
"memory_size",
"role",
]
}
}