Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,13 @@ jobs:
with:
node-version: 20

- name: Install LocalStack
- name: Install lstk and the AWS CLI wrapper
run: |
pip install localstack awscli-local[ver1] virtualenv
npm install -g @localstack/lstk
# Write the localstack AWS profile. Without it, lstk aws prints a setup note on stdout,
# which breaks scripts that pipe its output into jq.
lstk setup aws --force --non-interactive
pip install awscli virtualenv
pip install --upgrade boto3 botocore

- name: Setup config
Expand All @@ -59,8 +63,9 @@ jobs:
make test-ci
env:
LOCALSTACK_AUTH_TOKEN: ${{ secrets.LOCALSTACK_AUTH_TOKEN }}
DEBUG: 1
DNS_ADDRESS: 127.0.0.1
# lstk forwards LOCALSTACK_-prefixed variables to the emulator container
LOCALSTACK_DEBUG: 1
LOCALSTACK_DNS_ADDRESS: 127.0.0.1

- name: Compute sample name
if: always()
Expand Down
7 changes: 3 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@ lint: ## Run code linter for all projects
MAKE_TARGET='lint' make for-each-dir

start: ## Start LocalStack infrastructure
localstack start -d

lstk start --non-interactive --type aws
ready: ## Check if the LocalStack container is up and running.
localstack wait -t 20 && echo "LocalStack is ready to use!"
lstk status > /dev/null && echo "LocalStack is ready to use!"

stop: ## Stop LocalStack infrastructure
localstack stop
lstk stop

for-each-dir:
./make-for-each.sh $$MAKE_TARGET $$CMD
Expand Down
20 changes: 11 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ Each example in the repository is prefixed with the name of the AWS service bein
## Prerequisites

* [Docker](https://docs.docker.com/get-docker/)
* [`awslocal` CLI](https://docs.localstack.cloud/user-guide/integrations/aws-cli/)
* [`lstk` CLI](https://docs.localstack.cloud/aws/developer-tools/running-localstack/lstk/), which starts LocalStack: `npm install -g @localstack/lstk` or `brew install localstack/tap/lstk`
* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html), used through `lstk aws`
* [Serverless](https://www.serverless.com/framework/docs/getting-started)
* [Terraform](https://developer.hashicorp.com/terraform/downloads)
* `make` & `jq`
Expand All @@ -22,14 +23,16 @@ All samples require a valid [LocalStack for AWS license](https://localstack.clou
export LOCALSTACK_AUTH_TOKEN=<your-auth-token>
```

Alternatively, use the LocalStack CLI to persist the token:
Alternatively, log in with `lstk`, which stores your credentials:

```bash
localstack auth set-token <your-auth-token>
lstk login
```

You can find your Auth Token on the [LocalStack Web Application](https://app.localstack.cloud/workspace/auth-token).

The samples call the AWS CLI through `lstk aws`. Run `lstk setup aws` once to create the `localstack` AWS profile it uses.

## Outline

| Sample Name | Description |
Expand Down Expand Up @@ -115,8 +118,7 @@ usage: ## Show this help
@fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##//'

install: ## Install dependencies
@which localstack || pip install localstack
@which awslocal || pip install awscli-local
@which lstk > /dev/null || npm install -g @localstack/lstk
## install whatever else you need, like node modules, python packages, etc.
@test -e node_modules || npm install
@test -e .venv || (python3 -m venv .venv; source .venv/bin/activate; pip install -r requirements.txt)
Expand All @@ -126,18 +128,18 @@ run: ## Run the actual sample steps/commands. This assumes LocalStack is

start: ## Start LocalStack in detached mode
@test -n "${LOCALSTACK_AUTH_TOKEN}" || (echo "LOCALSTACK_AUTH_TOKEN is not set. Get your auth token at https://localstack.cloud/pricing."; exit 1)
localstack start -d
lstk start --non-interactive --type aws

stop: ## Stop the Running LocalStack container
@echo
localstack stop
lstk stop

ready: ## Make sure the LocalStack container is up
@echo Waiting on the LocalStack container...
@localstack wait -t 30 && echo LocalStack is ready to use! || (echo Gave up waiting on LocalStack, exiting. && exit 1)
@lstk status > /dev/null && echo LocalStack is ready to use! || (echo Gave up waiting on LocalStack, exiting. && exit 1)

logs: ## Save the logs in a separate file, since the LS container will only contain the logs of the last sample run.
@localstack logs > logs.txt
@lstk logs > logs.txt

test-ci: ## Execute the necessary targets in the correct order for an automatic execution.
make start install ready run; return_code=`echo $$?`;\
Expand Down
16 changes: 7 additions & 9 deletions apigw-custom-domain/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@ check: ## Check if all required prerequisites are installed
@command -v aws > /dev/null 2>&1 || { echo "AWS CLI is not installed. Please install AWS CLI and try again."; exit 1; }
@command -v python > /dev/null 2>&1 || { echo "Python is not installed. Please install Python and try again."; exit 1; }
@command -v openssl > /dev/null 2>&1 || { echo "OpenSSL is not installed. Please install OpenSSL and try again."; exit 1; }
@command -v localstack > /dev/null 2>&1 || { echo "LocalStack is not installed. Please install LocalStack and try again."; exit 1; }
@command -v lstk > /dev/null 2>&1 || { echo "lstk CLI is not installed. Please run: npm install -g @localstack/lstk"; exit 1; }
@echo "All required prerequisites are available."

install: ## Install dependencies
@which serverless || npm install -g serverless
@which awslocal || pip install awscli-local
@if [ ! -d "node_modules" ]; then \
echo "node_modules not found. Running npm install..."; \
npm install; \
Expand All @@ -41,9 +40,9 @@ deploy: ## Deploy Serverless app to local environment with SSL setup for Ro
@echo "Generating and importing test SSL certificate to ACM for Route53 domain test.example.com"
@make cert
@echo "Importing local test certificate into ACM API ..."
@awslocal acm import-certificate --certificate fileb://sslcert/server.crt --private-key fileb://sslcert/ssl.key
@lstk aws acm import-certificate --certificate fileb://sslcert/server.crt --private-key fileb://sslcert/ssl.key
@echo "Creating Route53 hosted zone for test domain 'test.example.com' ..."
@awslocal route53 create-hosted-zone --name test.example.com --caller-reference r1
@lstk aws route53 create-hosted-zone --name test.example.com --caller-reference r1
@echo "Deploying Serverless app to local environment"
@SLS_DEBUG=1 npm run deploy
@echo "Serverless app successfully deployed."
Expand All @@ -56,18 +55,17 @@ test: ## Run tests

start: ## Start LocalStack
@test -n "${LOCALSTACK_AUTH_TOKEN}" || (echo "LOCALSTACK_AUTH_TOKEN is not set. Find your token at https://app.localstack.cloud/workspace/auth-token"; exit 1)
localstack start -d

lstk start --non-interactive --type aws
stop: ## Stop LocalStack
@echo
localstack stop
lstk stop

ready: ## Wait until LocalStack is ready
@echo Waiting on the LocalStack container...
@localstack wait -t 30 && echo Localstack is ready to use! || (echo Gave up waiting on LocalStack, exiting. && exit 1)
@lstk status > /dev/null && echo Localstack is ready to use! || (echo Gave up waiting on LocalStack, exiting. && exit 1)

logs: ## Retrieve LocalStack logs
@localstack logs > logs.txt
@lstk logs > logs.txt

test-ci: ## Run CI tests
make check start install ready test; return_code=`echo $$?`;\
Expand Down
4 changes: 2 additions & 2 deletions apigw-custom-domain/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ Under the hood, the Serverless framework uses the [`serverless-localstack`](http

- A valid [LocalStack for AWS license](https://localstack.cloud/pricing). Your license provides a [`LOCALSTACK_AUTH_TOKEN`](https://docs.localstack.cloud/getting-started/auth-token/) to activate LocalStack.
- [Docker](https://docs.docker.com/get-docker/)
- [`localstack` CLI](https://docs.localstack.cloud/getting-started/installation/#localstack-cli)
- [`awslocal` CLI](https://docs.localstack.cloud/user-guide/integrations/aws-cli/)
- [`lstk` CLI](https://docs.localstack.cloud/aws/developer-tools/running-localstack/lstk/)
- [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html), used through `lstk aws`
- [Node.js 18.x](https://nodejs.org/en/download/package-manager) with `npm`
- [Serverless Framework](https://www.serverless.com/framework/docs/getting-started) 3.x
- `openssl`
Expand Down
15 changes: 7 additions & 8 deletions appsync-graphql-api/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,32 @@ check: ## Check if all required prerequisites are installed
@command -v docker > /dev/null 2>&1 || { echo "Docker is not installed. Please install Docker and try again."; exit 1; }
@command -v node > /dev/null 2>&1 || { echo "Node.js is not installed. Please install Node.js and try again."; exit 1; }
@command -v python3 > /dev/null 2>&1 || { echo "Python 3 is not installed. Please install Python 3 and try again."; exit 1; }
@command -v localstack > /dev/null 2>&1 || { echo "LocalStack CLI is not installed. Please install it and try again."; exit 1; }
@command -v awslocal > /dev/null 2>&1 || { echo "awslocal is not installed. Please run: pip install awscli-local"; exit 1; }
@command -v lstk > /dev/null 2>&1 || { echo "lstk CLI is not installed. Please run: npm install -g @localstack/lstk"; exit 1; }
@command -v aws > /dev/null 2>&1 || { echo "AWS CLI is not installed (required by 'lstk aws'). Please install it and try again."; exit 1; }
@echo "All required prerequisites are available."


install: ## Install dependencies
@test -e node_modules || npm install
@which serverless || npm install -g serverless
@which localstack || pip install localstack
@which awslocal || pip install awscli-local
@which lstk > /dev/null || npm install -g @localstack/lstk
@test -e .venv || (python3 -m venv .venv; source .venv/bin/activate; pip install -r requirements.txt)

run: ## Deploy the app locally and run an AppSync GraphQL test invocation
./run.sh
start:
@test -n "${LOCALSTACK_AUTH_TOKEN}" || (echo "LOCALSTACK_AUTH_TOKEN is not set. Find your token at https://app.localstack.cloud/workspace/auth-token"; exit 1)
DEBUG=1 LOCALSTACK_AUTH_TOKEN=$(LOCALSTACK_AUTH_TOKEN) localstack start -d
LOCALSTACK_DEBUG=1 LOCALSTACK_AUTH_TOKEN=$(LOCALSTACK_AUTH_TOKEN) lstk start --non-interactive --type aws

stop:
@echo
localstack stop
lstk stop
ready:
@echo Waiting on the LocalStack container...
@localstack wait -t 30 && echo Localstack is ready to use! || (echo Gave up waiting on LocalStack, exiting. && exit 1)
@lstk status > /dev/null && echo Localstack is ready to use! || (echo Gave up waiting on LocalStack, exiting. && exit 1)

logs:
@localstack logs > logs.txt
@lstk logs > logs.txt

test-ci:
make start install ready run; return_code=`echo $$?`;\
Expand Down
6 changes: 3 additions & 3 deletions appsync-graphql-api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ A demo application illustrating how to proxy data from different resources (Dyna

- A valid [LocalStack for AWS license](https://localstack.cloud/pricing). Your license provides a [`LOCALSTACK_AUTH_TOKEN`](https://docs.localstack.cloud/getting-started/auth-token/) to activate LocalStack.
- [Docker](https://docs.docker.com/get-docker/)
- [`localstack` CLI](https://docs.localstack.cloud/getting-started/installation/#localstack-cli)
- [`awslocal` CLI](https://docs.localstack.cloud/user-guide/integrations/aws-cli/)
- [`lstk` CLI](https://docs.localstack.cloud/aws/developer-tools/running-localstack/lstk/)
- [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html), used through `lstk aws`
- [Python 3](https://www.python.org/downloads/)

## Check prerequisites
Expand Down Expand Up @@ -63,7 +63,7 @@ You should see a success output in the terminal:
The item should also have been added to your local DynamoDB table:

```bash
$ awslocal dynamodb scan --table-name table1
$ lstk aws dynamodb scan --table-name table1
{
"Items": [
{
Expand Down
6 changes: 3 additions & 3 deletions appsync-graphql-api/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ APPSYNC_URL=http://localhost:4566/graphql
echo "Deploying Serverless app to local environment"; \
SLS_DEBUG=1 npm run deploy && \
echo "Serverless app successfully deployed." && \
api_id=$(awslocal appsync list-graphql-apis | jq -r '(.graphqlApis[] | select(.name=="test-api")).apiId') && \
api_id=$(lstk aws appsync list-graphql-apis | jq -r '(.graphqlApis[] | select(.name=="test-api")).apiId') && \
echo "DEBUG: api_id is: $api_id" && \
api_key=$(awslocal appsync create-api-key --api-id $api_id | jq -r .apiKey.id) && \
api_key=$(lstk aws appsync create-api-key --api-id $api_id | jq -r .apiKey.id) && \
echo "DEBUG: api_key is: $api_key" && \
echo "Starting a WebSocket client to subscribe to GraphQL mutation operations." && \
source .venv/bin/activate && \
Expand All @@ -16,7 +16,7 @@ echo "Now trying to invoke the AppSync API for DynamoDB integration under $APPSY
curl -H "Content-Type: application/json" -H "x-api-key: $api_key" -d '{"query":"mutation {addPostDDB(id: \"id123\"){id}}"}' $APPSYNC_URL/$api_id && \
curl -H "Content-Type: application/json" -H "x-api-key: $api_key" -d '{"query":"query {getPostsDDB{id}}"}' $APPSYNC_URL/$api_id && \
echo "Scanning items from DynamoDB table - should include entry with 'id123':" && \
awslocal dynamodb scan --table-name table1 && \
lstk aws dynamodb scan --table-name table1 && \
echo "Now trying to invoke the AppSync API for RDS integration." && \
curl -H "Content-Type: application/json" -H "x-api-key: $api_key" -d '{"query":"mutation {addPostRDS(id: \"id123\"){id}}"}' $APPSYNC_URL/$api_id && \
curl -H "Content-Type: application/json" -H "x-api-key: $api_key" -d '{"query":"query {getPostsRDS{id}}"}' $APPSYNC_URL/$api_id
Expand Down
17 changes: 8 additions & 9 deletions athena-s3-queries/Makefile
Original file line number Diff line number Diff line change
@@ -1,40 +1,39 @@
export AWS_ACCESS_KEY_ID ?= test
export AWS_SECRET_ACCESS_KEY ?= test
export SERVICES = serverless,athena
export LOCALSTACK_SERVICES = serverless,athena
export AWS_DEFAULT_REGION=us-east-1

usage: ## Show this help
@fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##//'

check: ## Check if all required prerequisites are installed
@command -v docker > /dev/null 2>&1 || { echo "Docker is not installed. Please install Docker and try again."; exit 1; }
@command -v localstack > /dev/null 2>&1 || { echo "LocalStack CLI is not installed. Please install it and try again."; exit 1; }
@command -v awslocal > /dev/null 2>&1 || { echo "awslocal is not installed. Please run: pip install awscli-local"; exit 1; }
@command -v lstk > /dev/null 2>&1 || { echo "lstk CLI is not installed. Please run: npm install -g @localstack/lstk"; exit 1; }
@command -v aws > /dev/null 2>&1 || { echo "AWS CLI is not installed (required by 'lstk aws'). Please install it and try again."; exit 1; }
@echo "All required prerequisites are available."


install: ## Install dependencies
# @test -e node_modules || npm install
@which localstack || pip install localstack
@which awslocal || pip install awscli-local
@which lstk > /dev/null || npm install -g @localstack/lstk

run: ## Set up database connections and run Athena queries locally
@make install; \
echo "Running Athena queries"; \
./run.sh
start:
@test -n "${LOCALSTACK_AUTH_TOKEN}" || (echo "LOCALSTACK_AUTH_TOKEN is not set. Find your token at https://app.localstack.cloud/workspace/auth-token"; exit 1)
DEBUG=1 LOCALSTACK_AUTH_TOKEN=$(LOCALSTACK_AUTH_TOKEN) localstack start -d
LOCALSTACK_DEBUG=1 LOCALSTACK_AUTH_TOKEN=$(LOCALSTACK_AUTH_TOKEN) lstk start --non-interactive --type aws

stop:
@echo
localstack stop
lstk stop
ready:
@echo Waiting on the LocalStack container...
@localstack wait -t 30 && echo Localstack is ready to use! || (echo Gave up waiting on LocalStack, exiting. && exit 1)
@lstk status > /dev/null && echo Localstack is ready to use! || (echo Gave up waiting on LocalStack, exiting. && exit 1)

logs:
@localstack logs > logs.txt
@lstk logs > logs.txt

test-ci:
# skip Athena tests for now, to avoid downloading large images in CI
Expand Down
4 changes: 2 additions & 2 deletions athena-s3-queries/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ A demo application illustrating how to run Athena queries over S3 files locally

- A valid [LocalStack for AWS license](https://localstack.cloud/pricing). Your license provides a [`LOCALSTACK_AUTH_TOKEN`](https://docs.localstack.cloud/getting-started/auth-token/) to activate LocalStack.
- [Docker](https://docs.docker.com/get-docker/)
- [`localstack` CLI](https://docs.localstack.cloud/getting-started/installation/#localstack-cli)
- [`awslocal` CLI](https://docs.localstack.cloud/user-guide/integrations/aws-cli/)
- [`lstk` CLI](https://docs.localstack.cloud/aws/developer-tools/running-localstack/lstk/)
- [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html), used through `lstk aws`
- [Node.js](https://nodejs.org/en/download/) with `npm`

## Check prerequisites
Expand Down
16 changes: 8 additions & 8 deletions athena-s3-queries/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ S3_INPUT=s3://$BUCKET/data/data.csv
S3_OUTPUT=s3://$BUCKET/results

echo Uploading test data to S3...
awslocal s3 mb s3://$BUCKET
awslocal s3 cp data/data.csv $S3_INPUT
lstk aws s3 mb s3://$BUCKET
lstk aws s3 cp data/data.csv $S3_INPUT

function wait_for_query {
for i in {1..50}; do
status=$(awslocal athena get-query-execution --query-execution-id $1 | jq -r '.QueryExecution.Status.State')
status=$(lstk aws athena get-query-execution --query-execution-id $1 | jq -r '.QueryExecution.Status.State')
echo Waiting for completion status of query $1: $status
if [ "$status" != "RUNNING" ]; then
return
Expand All @@ -25,20 +25,20 @@ function wait_for_query {

echo Running queries to create database and table definitions...
echo 'NOTE: This can take a very long time (several minutes) as the system is initializing'
queryId=$(awslocal athena start-query-execution --query-string "`cat queries/create_database.sql`" | jq -r '.QueryExecutionId')
queryId=$(lstk aws athena start-query-execution --query-string "`cat queries/create_database.sql`" | jq -r '.QueryExecutionId')
wait_for_query $queryId
queryId=$(awslocal athena start-query-execution --query-string "`cat queries/create_tables.sql`" --query-execution-context Database=$DATABASE --result-configuration OutputLocation=$S3_OUTPUT | jq -r '.QueryExecutionId')
queryId=$(lstk aws athena start-query-execution --query-string "`cat queries/create_tables.sql`" --query-execution-context Database=$DATABASE --result-configuration OutputLocation=$S3_OUTPUT | jq -r '.QueryExecutionId')
wait_for_query $queryId

queryId=$(awslocal athena start-query-execution --query-string "`cat queries/query_persons.sql`" --query-execution-context Database=$DATABASE --result-configuration OutputLocation=$S3_OUTPUT | jq -r '.QueryExecutionId')
queryId=$(lstk aws athena start-query-execution --query-string "`cat queries/query_persons.sql`" --query-execution-context Database=$DATABASE --result-configuration OutputLocation=$S3_OUTPUT | jq -r '.QueryExecutionId')
echo Starting SELECT query over data in S3. Query ID: $queryId

outputLoc=$(awslocal athena get-query-execution --query-execution-id $queryId | jq -r '.QueryExecution.ResultConfiguration.OutputLocation')
outputLoc=$(lstk aws athena get-query-execution --query-execution-id $queryId | jq -r '.QueryExecution.ResultConfiguration.OutputLocation')
echo S3 query output location: $outputLoc
sleep 6

echo 'Waiting for query results to become available in S3 (this can take some time)'
sleep 15
awslocal s3 cp $outputLoc/results.csv /tmp/$queryId.results.csv
lstk aws s3 cp $outputLoc/results.csv /tmp/$queryId.results.csv
echo Query result downloaded from S3:
cat /tmp/$queryId.results.csv
Loading
Loading