Skip to content

Commit

Permalink
Local environment demo
Browse files Browse the repository at this point in the history
  • Loading branch information
AshtonStephens committed May 14, 2024
1 parent 996548d commit 2ac528f
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 13 deletions.
39 changes: 28 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
EMILY_PATH=emily
EMILY_DEVENV_PATH=$(EMILY_PATH)/devenv
EMILY_API_PROJECT_NAME=emily-api
EMILY_CDK_PROJECT_NAME=emily-cdk

install:
pnpm install

build: install | emily-client
build: install emily-client
cargo build \
&& pnpm --recursive build

test: install | emily-client
test: install emily-client
cargo test \
&& pnpm --recursive test

lint: install | emily-client
lint: install emily-client
cargo clippy \
&& pnpm --recursive run lint

clean:
cargo clean \
&& pnpm --recursive clean
&& pnpm --recursive clean \
&& rm -f $(EMILY_DEVENV_PATH)/dynamodb/data/*.db

# Emily API
# ----------------------------------------------------

EMILY_PATH=emily
EMILY_API_PROJECT_NAME=emily-api
EMILY_CDK_PROJECT_NAME=emily-cdk

emily-cdk: emily-client | emily-lambda
pnpm --filter $(EMILY_CDK_PROJECT_NAME) run build
emily-cdk: emily-client emily-lambda
pnpm --filter $(EMILY_CDK_PROJECT_NAME) synth

# Overwrite the default architecture with --arm64 configuration
# on arm machines.
Expand All @@ -40,5 +42,20 @@ emily-lambda: emily-client
--output-format zip \
$(_LAMBDA_FLAGS)

emily-client:
emily-client: install
pnpm --filter $(EMILY_API_PROJECT_NAME) run build

emily-devenv-up:
cd $(EMILY_DEVENV_PATH) \
&& docker compose up --remove-orphans -d

emily-devenv-down:
cd $(EMILY_DEVENV_PATH) \
&& docker compose down

emily-devenv-build:
cd $(EMILY_DEVENV_PATH) \
&& sudo docker compose build

emily-devenv-full: emily-cdk emily-devenv-build emily-devenv-up

3 changes: 1 addition & 2 deletions emily/cdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
"emily": "bin/emily.js"
},
"scripts": {
"build": "(cd ../api-definition && npm run build-openapi) && tsc",
"synth": "tsc && npx aws-cdk synth -q --no-staging",
"watch": "tsc -w",
"test": "jest",
"cdk": "npx aws-cdk",
"clean": "rm -rf node_modules .cdk.staging cdk.out .generated-sources"
},
"devDependencies": {
Expand Down
7 changes: 7 additions & 0 deletions emily/devenv/apigateway/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM public.ecr.aws/sam/build-provided.al2023

EXPOSE 3000

RUN dnf update

RUN dnf install -y docker
71 changes: 71 additions & 0 deletions emily/devenv/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
services:

# Hosts the DynamoDB Tables.
dynamodb:
image: "amazon/dynamodb-local:latest"
command: "-jar DynamoDBLocal.jar -sharedDb -dbPath ./data"
ports:
- "8000:8000"
volumes:
- "/Users/ashtonstephens/workplace/sbtc/emily/devenv/dynamodb/data:/home/dynamodblocal/data"
networks:
- aws-local-vpc

# Creates DynamoDB Tables if necessary.
dynamodb-setup:
build: dynamodb-setup
depends_on:
dynamodb:
condition: service_started
volumes:
- "/Users/ashtonstephens/workplace/sbtc/emily/devenv/dynamodb-setup/initialize.py:/initialize.py"
- "/Users/ashtonstephens/workplace/sbtc/emily/cdk/cdk.out/EmilyStack.template.json:/template.json"
environment:
- DYNAMODB_ENDPOINT=http://dynamodb:8000
- CDK_TEMPLATE=/template.json
- AWS_DEFAULT_REGION=us-west-2
- AWS_ACCESS_KEY_ID=xxxxxxxxxxxx
- AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxx
command: python3 ./initialize.py
networks:
- aws-local-vpc

# Hosts the SAM CLI
apigateway:
build: apigateway
depends_on:
dynamodb-setup:
condition: service_completed_successfully
ports:
- "3000:3000"
volumes:
# Executes in /var/task/
- "/Users/ashtonstephens/workplace/sbtc/target/lambda/emily-lambda/bootstrap.zip:/Users/ashtonstephens/workplace/sbtc/target/lambda/emily-lambda/bootstrap.zip"
- "/Users/ashtonstephens/workplace/sbtc/emily/cdk/cdk.out/EmilyStack.template.json:/var/task/template.json"
- "/Users/ashtonstephens/workplace/sbtc/emily/devenv/lambda/env.json:/var/task/env.json"
# Set SAM to create sibling containers and not child containers.
- "/var/run/docker.sock:/var/run/docker.sock"
# When the SAM CLI launches a lambda container it decompresses the sources in folder under
# `tmp` and then mounts that folder onto the new container. When two sibling containers
# need access to the same directory they need to do that via a directory on the shared host.
#
# tl;dr: We're running SAM in a docker container and launching the lambda as a sibling container
# so we need the `tmp` directory to be shared on the host.
- "/tmp:/tmp"
environment:
- SAM_CLI_TELEMETRY=0
- SAM_CLI_CONTAINER_CONNECTION_TIMEOUT=30
command: |
sam local start-api
--host 0.0.0.0
--container-host host.docker.internal
--docker-network aws-local-vpc
--warm-containers LAZY
--env-vars /var/task/env.json
-t /var/task/template.json
networks:
- aws-local-vpc

networks:
aws-local-vpc:
name: aws-local-vpc
3 changes: 3 additions & 0 deletions emily/devenv/dynamodb-setup/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FROM python:3.12-slim

RUN pip3 install boto3
41 changes: 41 additions & 0 deletions emily/devenv/dynamodb-setup/initialize.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import boto3
import os
import uuid
import json
from decimal import Decimal
from time import sleep
from datetime import datetime

# Extract environment variables.
template_file = os.environ["CDK_TEMPLATE"]
dynamodb_endpoint = os.environ["DYNAMODB_ENDPOINT"]

# Read CDK Template.
with open(template_file) as fp:
template = json.load(fp)

# Setup boto3 client for dynamodb with the dynamodb container as the endpoint.
client = boto3.client('dynamodb', endpoint_url=dynamodb_endpoint)

# Get the set of existing tables so we don't attempt to recreate any existing
# tables later.
list_tables_response = client.list_tables(Limit=10)
existing_tables = set()
if "TableNames" in list_tables_response:
existing_tables = set(list_tables_response["TableNames"])

# Isolate only the table resources.
resources = template["Resources"]
tables = [resource for resource in resources.values() if resource["Type"] == "AWS::DynamoDB::Table"]

for table in tables:
properties = table["Properties"]
table_name = properties["TableName"]
if table_name not in existing_tables:
# Make table if it's not present.
print(f"Creating table {table_name}.")
client.create_table(**properties)
print(f"Successfully created table {table_name}.")
else:
# Don't make the table if it's already present.
print(f"Table {table_name} already exists, leaving it alone.")
5 changes: 5 additions & 0 deletions emily/devenv/lambda/env.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"Parameters": {
"IS_LOCAL": "true"
}
}

0 comments on commit 2ac528f

Please sign in to comment.