Skip to content
Merged
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
73 changes: 73 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
name: Setup infrastructure using CDK

on:
push:
paths-ignore:
- 'README.md'
branches:
- main
pull_request:
branches:
- main
schedule:
# “At 00:00 on Sunday.”
- cron: "0 0 * * 0"
workflow_dispatch:

jobs:
cdk:
name: Run Integration Tests
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: 22

- name: Start LocalStack
uses: LocalStack/setup-localstack@main
env:
LOCALSTACK_AUTH_TOKEN: ${{ secrets.LOCALSTACK_AUTH_TOKEN }}
with:
use-pro: 'true'

- name: Install CDK
run: |
npm install -g aws-cdk-local aws-cdk
cdklocal --version
- name: Install dependencies
run: make install

- name: Deploy the CDK stack
run: make deploy

- name: Run the tests
run: make test

- name: Send a Slack notification
if: failure() || github.event_name != 'pull_request'
uses: ravsamhq/notify-slack-action@v2
with:
status: ${{ job.status }}
token: ${{ secrets.GITHUB_TOKEN }}
notification_title: "{workflow} has {status_message}"
message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>"
footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Workflow run>"
notify_when: "failure"
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

- name: Generate a Diagnostic Report
if: failure()
run: |
curl -s localhost:4566/_localstack/diagnose | gzip -cf > diagnose.json.gz

- name: Upload the Diagnostic Report
if: failure()
uses: actions/upload-artifact@v4
with:
name: diagnose.json.gz
path: ./diagnose.json.gz
17 changes: 17 additions & 0 deletions .github/workflows/keepalive.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Keep Alive
on:
schedule:
- cron: "0 0 * * *"
jobs:
main-job:
name: Main Job
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
workflow-keepalive:
if: github.event_name == 'schedule'
runs-on: ubuntu-latest
permissions:
actions: write
steps:
- uses: liskin/gh-workflow-keepalive@v1
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
.vscode
.idea
iac/awscdk/output.json
.env-gdc-local
logs.txt
15 changes: 15 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"version": "0.2.0",
"configurations": [
{
"address": "127.0.0.1",
"localRoot": "${workspaceFolder}",
"name": "Attach to Remote Node.js",
"port": 9229,
"remoteRoot": "/app",
"request": "attach",
"type": "node",
"preLaunchTask": "Wait Remote Debugger Server"
}
]
}
10 changes: 10 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Wait Remote Debugger Server",
"type": "shell",
"command": "while [[ -z $(docker ps | grep :9229) ]]; do sleep 1; done; sleep 1;"
}
]
}
77 changes: 53 additions & 24 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ SHELL := /bin/bash
-include .env-gdc-local

CDIR = cd iac/awscdk
TDIR = cd tests

export APP_NAME?=ecslb
export ENFORCE_IAM?=0
Expand All @@ -12,42 +13,70 @@ usage: ## Show this help in table format
@echo "|------------------------|-------------------------------------------------------------------|"
@fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/:.*##\s*/##/g' | awk -F'##' '{ printf "| %-22s | %-65s |\n", $$1, $$2 }'

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 aws > /dev/null 2>&1 || { echo "AWS CLI is not installed. Please install AWS CLI 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 cdk > /dev/null 2>&1 || { echo "CDK is not installed. Please install CDK and try again."; exit 1; }
@command -v cdklocal > /dev/null 2>&1 || { echo "cdklocal is not installed. Please install cdklocal and try again."; exit 1; }
@echo "All required prerequisites are available."

install: ## Install NPM dependencies
@${CDIR}; if [ ! -d "node_modules" ]; then \
echo "Installing NPM dependencies..."; \
npm install; \
else \
echo "NPM dependencies for CDK project already installed."; \
fi
@${TDIR}; if [ ! -d "node_modules" ]; then \
echo "Installing NPM dependencies..."; \
npm install; \
else \
echo "NPM dependencies for tests already installed."; \
fi

deploy: ## Bootstrap and deploy the CDK app on LocalStack
${CDIR}; cdklocal bootstrap; cdklocal deploy --outputs-file ./output.json --json --require-approval never

deploy-aws: ## Bootstrap and deploy the CDK app on AWS
${CDIR}; cdk bootstrap && \
cdk deploy --outputs-file ./output.json --json

destroy: ## Destroy the deployed CDK stack on LocalStack
${CDIR}; cdklocal destroy

deploy: ## Bootstrap and deploy the CDK app to AWS
${CDIR}; cdk bootstrap; cdk deploy --outputs-file ./output.json --json

destroy: ## Destroy the deployed CDK stack in AWS
destroy-aws: ## Destroy the deployed CDK stack on AWS
${CDIR}; cdk destroy

destroy-local: ## Destroy the deployed CDK stack locally
${CDIR}; cdklocal destroy

deploy-local: ## Bootstrap and deploy the CDK app locally
${CDIR}; cdklocal bootstrap && \
cdklocal deploy --outputs-file ./output.json --json --require-approval never
test: ## Run integration tests on LocalStack
cd tests && LOCALSTACK=1 npm run test

test: ## Run integration tests
test-aws: ## Run integration tests on AWS
cd tests && npm run test

test-local: ## Run integration tests
cd tests && LOCALSTACK=1 npm run test

curl-local:
curl: ## Curl the LocalStack service load balancer
curl $(shell cat iac/awscdk/output.json | jq '.RepoStack.localstackserviceslb')

curl-aws:
curl-aws: ## Curl the AWS service load balancer
curl $(shell cat iac/awscdk/output.json | jq '.RepoStack.serviceslb')

install: ## Install npm dependencies
${CDIR}; npm install

start: ## Start LocalStack
@echo "Starting LocalStack..."
@LOCALSTACK_AUTH_TOKEN=$(LOCALSTACK_AUTH_TOKEN) localstack start -d
@echo "LocalStack started successfully."

start-localstack:
cd devops-tooling && docker compose -p $(APP_NAME) up
stop: ## Stop LocalStack
@echo "Stopping LocalStack..."
@localstack stop
@echo "LocalStack stopped successfully."

stop-localstack:
cd devops-tooling && docker compose -p $(APP_NAME) down
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)

logs: ## Save the logs in a separate file
@localstack logs > logs.txt

PKG_SUB_DIRS := $(dir $(shell find . -type d -name node_modules -prune -o -type d -name "venv*" -prune -o -type f -name package.json -print))

Expand All @@ -56,4 +85,4 @@ update-deps: $(PKG_SUB_DIRS)
pushd $$i && ncu -u && npm install && popd; \
done

.PHONY: usage install test test-local deploy destroy deploy-local destroy-local bootstrap-local update-deps start-localstack stop-localstack curl-local curl-aws
.PHONY: usage install check start deploy curl test destroy logs deploy-aws curl-aws test-aws destroy-aws update-deps
2 changes: 1 addition & 1 deletion src/app/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const http = require('http')

const server = http.createServer((req, res) => {
res.setHeader('Content-Type', 'application/json')
res.end(JSON.stringify({message: "Hi Localstack!"}))
res.end(JSON.stringify({message: "Hi LocalStack!"}))
})

const PORT = 3000
Expand Down
2 changes: 1 addition & 1 deletion tests/integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe('User API', function () {

// Assert the body
expect(response.data).to.be.an('object')
expect(response.data).to.have.property('message', "Hello, Welcome to Localstack!")
expect(response.data).to.have.property('message', "Hi LocalStack!")
expect(response.data.message).to.be.a('string')
})
})
Loading