Skip to content

Commit

Permalink
Merge pull request #5 from wri/feat/TM-1273-deployment
Browse files Browse the repository at this point in the history
[TM-1273] AWS Deployment
  • Loading branch information
roguenet authored Oct 23, 2024
2 parents 762c35e + 0d96c71 commit 4153047
Show file tree
Hide file tree
Showing 30 changed files with 5,148 additions and 97 deletions.
4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
dist
tmp
.vscode
47 changes: 47 additions & 0 deletions .github/workflows/deploy-api-gateway.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Api Gateway Deploy

on:
workflow_dispatch:
inputs:
env:
description: 'Deployment target environment'
type: choice
required: true
options:
- dev
- test
- staging
- prod

permissions:
id-token: write
contents: read

env:
NODE_ENV: production
AWS_REGION: eu-west-1
AWS_ROLE_TO_ASSUME: arn:aws:iam::603634817705:role/terramatch-microservices-github-actions
AWS_ROLE_SESSION_NAME: terramatch-microservices-cicd-api-gateway
PHP_PROXY_TARGET: ${{ vars.PHP_PROXY_TARGET }}

jobs:
main:
runs-on: ubuntu-latest
environment: ${{ inputs.env }}
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Configure AWS credentials
uses: aws-actions/[email protected]
with:
role-to-assume: ${{ env.AWS_ROLE_TO_ASSUME }}
role-session-name: ${{ env.AWS_ROLE_SESSION_NAME }}
aws-region: ${{ env.AWS_REGION }}

- name: CDK Deploy
id: cdk-deploy
run: |
cd apps/api-gateway
NODE_ENV=development npm i
TM_ENV=${{ inputs.env }} npx --yes cdk deploy --require-approval never
65 changes: 65 additions & 0 deletions .github/workflows/deploy-user-service.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: User Service Deploy

on:
workflow_dispatch:
inputs:
env:
description: 'Deployment target environment'
type: choice
required: true
options:
- dev
- test
- staging
- prod

permissions:
id-token: write
contents: read

env:
AWS_REGION: eu-west-1
AWS_ROLE_TO_ASSUME: arn:aws:iam::603634817705:role/terramatch-microservices-github-actions
AWS_ROLE_SESSION_NAME: terramatch-microservices-cicd-user-service
ECR_REPOSITORY: terramatch-microservices/user-service-${{ inputs.env }}
ECR_REGISTRY: 603634817705.dkr.ecr.eu-west-1.amazonaws.com
IMAGE_TAG: ${{ github.sha }}

jobs:
main:
runs-on: ubuntu-latest
environment: ${{ inputs.env }}
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Configure AWS credentials
uses: aws-actions/[email protected]
with:
role-to-assume: ${{ env.AWS_ROLE_TO_ASSUME }}
role-session-name: ${{ env.AWS_ROLE_SESSION_NAME }}
aws-region: ${{ env.AWS_REGION }}

- name: Login to AWS
id: AWS
uses: aws-actions/amazon-ecr-login@v1

- name: Build, tag, and push images to Amazon ECR
id: build-images
run: |
echo "${{ vars.ENV }}" > .env
echo "DB_PASSWORD=\"${{ secrets.DB_PASSWORD }}\"" >> .env
: # Don't build the base image with NODE_ENV because it'll limit the packages that are installed
docker build -t terramatch-microservices-base:nx-base .
USER_SERVICE_IMAGE=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
docker build --build-arg NODE_ENV=production --build-arg BUILD_FLAG=--prod -f apps/user-service/Dockerfile -t $USER_SERVICE_IMAGE .
docker push $USER_SERVICE_IMAGE
echo "image=$USER_SERVICE_IMAGE"
- name: Launch new task definition
id: launch
run: |
cd apps/user-service/stack
npm i
IMAGE_TAG=$IMAGE_TAG TM_ENV=${{ inputs.env }} npx --yes cdk deploy --require-approval never
14 changes: 7 additions & 7 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,11 @@ jobs:
with:
fetch-depth: 0

- uses: KengoTODA/actions-setup-docker-compose@v1
with:
version: '2.29.1'

# This enables task distribution via Nx Cloud
# Run this command as early as possible, before dependencies are installed
# Learn more at https://nx.dev/ci/reference/nx-cloud-cli#npx-nxcloud-startcirun
- run: npx nx-cloud start-ci-run --distribute-on="3 linux-medium-js" --stop-agents-after="build"

- run: docker-compose up -d

# Cache node_modules
- uses: actions/setup-node@v4
with:
Expand All @@ -43,6 +37,12 @@ jobs:
# cacheable. Since the codebase is currently small, we can get away without distribution, but once
# it grows, we'll want to look into what it will take to make the api gateway build cacheable and remove
# NX_CLOUD_DISTRIBUTED_EXECUTION=false from this command.
- run: NX_CLOUD_DISTRIBUTED_EXECUTION=false npx nx affected -t lint build
- run: NX_CLOUD_DISTRIBUTED_EXECUTION=false ARCH=X86 npx nx affected -t lint build

- uses: KengoTODA/actions-setup-docker-compose@v1
with:
version: '2.29.1'

- run: docker-compose up -d

- run: NX_CLOUD_DISTRIBUTED_EXECUTION=false npx nx run-many -t test --coverage --passWithNoTests
1 change: 1 addition & 0 deletions .nxignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
apps/*/stack
7 changes: 7 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM node:lts-alpine3.19 as builder
ARG NODE_ENV
ARG BUILD_FLAG

WORKDIR /app/builder
COPY . .
RUN npm i
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ Repository for the Microservices API backend of the TerraMatch service
* The ApiGateway does not hot-reload and needs to be re-built when there are changes:
* `nx build api-gateway` or `nx run-many -t build` (to build all apps)
* This will build the local proxy Lambda function and the CDK Stack
* Note: The architecture for the local lambda proxy defaults to ARM_64. This will be the fastest options on ARM-based Macs
(M1, etc), but will be much slower on X86 (AMD/Intel) based machine. If you're on an X86 machine, pass the architecture in
an environment variable when building the api gateway: `ARCH=X86 nx build api-gateway`.
* To run all services:
* `nx run-many -t serve`
* Note: the first time this runs, the gateway will take quite awhile to start. It'll be faster on subsequent starts.
Expand All @@ -22,8 +25,12 @@ Repository for the Microservices API backend of the TerraMatch service
* `NEXT_PUBLIC_API_BASE_URL='http://localhost:4000'`

# Deployment
TBD. The ApiGateway has been tested to be at least functional on AWS. Tooling around deployment will be
handled in a future ticket.
Deployment is handled via manual trigger of GitHub actions. There is one for each service, and one for the ApiGateway. The
ApiGateway only needs to be redeployed if its code changes; it does not need to be redeployed for updates to individual services
to take effect.

Once this project is live in production, we can explore continuous deployment to at least staging and prod envs on the staging
and main branches.

# Database work
For now, Laravel is the source of truth for all things related to the DB schema. As such, TypeORM is not allowed to modify the
Expand Down
18 changes: 3 additions & 15 deletions apps/api-gateway/bin/api-gateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,6 @@ import * as cdk from 'aws-cdk-lib';
import { ApiGatewayStack } from '../lib/api-gateway-stack';

const app = new cdk.App();
new ApiGatewayStack(app, 'ApiGatewayStack', {
/* If you don't specify 'env', this stack will be environment-agnostic.
* Account/Region-dependent features and context lookups will not work,
* but a single synthesized template can be deployed anywhere. */

/* Uncomment the next line to specialize this stack for the AWS Account
* and Region that are implied by the current CLI configuration. */
// env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION },

/* Uncomment the next line if you know exactly what Account and Region you
* want to deploy the stack to. */
// env: { account: '123456789012', region: 'us-east-1' },

/* For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html */
});
new ApiGatewayStack(app, `ApiGatewayStack-${process.env.TM_ENV ?? 'local'}`, {
env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION },
});
71 changes: 71 additions & 0 deletions apps/api-gateway/cdk.context.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"vpc-provider:account=603634817705:filter.vpc-id=vpc-0beac5973796d96b1:region=eu-west-1:returnAsymmetricSubnets=true": {
"vpcId": "vpc-0beac5973796d96b1",
"vpcCidrBlock": "10.0.0.0/16",
"ownerAccountId": "603634817705",
"availabilityZones": [],
"subnetGroups": [
{
"name": "Private",
"type": "Private",
"subnets": [
{
"subnetId": "subnet-065992a829eb772a3",
"cidr": "10.0.128.0/20",
"availabilityZone": "eu-west-1a",
"routeTableId": "rtb-07f85b7827c451bc9"
},
{
"subnetId": "subnet-0f48d0681051fa49a",
"cidr": "10.0.144.0/20",
"availabilityZone": "eu-west-1b",
"routeTableId": "rtb-06afefb0f592f11d6"
}
]
},
{
"name": "Public",
"type": "Public",
"subnets": [
{
"subnetId": "subnet-0a099d863485e6c39",
"cidr": "10.0.0.0/20",
"availabilityZone": "eu-west-1a",
"routeTableId": "rtb-001c321e760157b3b"
},
{
"subnetId": "subnet-0a91312f58b03ad3f",
"cidr": "10.0.16.0/20",
"availabilityZone": "eu-west-1b",
"routeTableId": "rtb-001c321e760157b3b"
}
]
}
]
},
"load-balancer:account=603634817705:loadBalancerTags.0.key=service:loadBalancerTags.0.value=user-service-test:loadBalancerType=application:region=eu-west-1": {
"loadBalancerArn": "arn:aws:elasticloadbalancing:eu-west-1:603634817705:loadbalancer/app/user-service-test/e1ee1ce635080238",
"loadBalancerCanonicalHostedZoneId": "Z32O12XQLNTSW2",
"loadBalancerDnsName": "internal-user-service-test-1863479300.eu-west-1.elb.amazonaws.com",
"vpcId": "vpc-0beac5973796d96b1",
"securityGroupIds": [
"sg-06a4b12aa14e529be"
],
"ipAddressType": "ipv4"
},
"security-group:account=603634817705:region=eu-west-1:securityGroupId=sg-06a4b12aa14e529be": {
"securityGroupId": "sg-06a4b12aa14e529be",
"allowAllOutbound": false
},
"security-group:account=603634817705:region=eu-west-1:securityGroupName=default:vpcId=vpc-0beac5973796d96b1": {
"securityGroupId": "sg-0fcff87239114297b",
"allowAllOutbound": false
},
"load-balancer-listener:account=603634817705:loadBalancerTags.0.key=service:loadBalancerTags.0.value=user-service-test:loadBalancerType=application:region=eu-west-1": {
"listenerArn": "arn:aws:elasticloadbalancing:eu-west-1:603634817705:listener/app/user-service-test/e1ee1ce635080238/069ab4638dd50686",
"listenerPort": 80,
"securityGroupIds": [
"sg-06a4b12aa14e529be"
]
}
}
Loading

0 comments on commit 4153047

Please sign in to comment.