Skip to content

Commit 7b3dfbd

Browse files
committed
WIP
1 parent 0b323c6 commit 7b3dfbd

19 files changed

Lines changed: 625 additions & 106 deletions

File tree

.github/workflows/deploy-aws.yml

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
name: Deploy to AWS
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
branches:
7+
- dev
8+
9+
paths:
10+
- 'client/**'
11+
- 'cms/**'
12+
- '.github/workflows/*'
13+
- 'infrastructure/**'
14+
- 'package.json'
15+
16+
jobs:
17+
set_environment:
18+
runs-on: ubuntu-latest
19+
name: Set Deployment Environment
20+
outputs:
21+
env_name: ${{ steps.set_env.outputs.env_name }}
22+
steps:
23+
- id: set_env
24+
run: echo "env_name=${{ github.ref_name == 'main' && 'production' || github.ref_name }}" >> $GITHUB_OUTPUT
25+
26+
trigger_build:
27+
runs-on: ubuntu-latest
28+
outputs:
29+
build_cms: ${{ steps.changes.outputs.cms == 'true' || github.ref_name == 'staging' || github.ref_name == 'main' }}
30+
build_client: ${{ steps.changes.outputs.client == 'true' || github.ref_name == 'staging' || github.ref_name == 'main' }}
31+
steps:
32+
- name: Checkout code
33+
uses: actions/checkout@v4
34+
35+
- name: Detect changes in client and CMS paths
36+
uses: dorny/paths-filter@v3
37+
id: changes
38+
with:
39+
filters: |
40+
client:
41+
- '.github/workflows/**'
42+
- 'client/**'
43+
cms:
44+
- '.github/workflows/**'
45+
- 'cms/**'
46+
47+
build_client:
48+
needs: [set_environment, trigger_build]
49+
if: ${{ github.event_name == 'workflow_dispatch' || needs.trigger_build.outputs.build_client == 'true' }}
50+
environment:
51+
name: ${{ needs.set_environment.outputs.env_name }}
52+
runs-on: ubuntu-latest
53+
name: Build Client image and push to Amazon ECR
54+
steps:
55+
- name: Checkout code
56+
uses: actions/checkout@v4
57+
58+
- name: Configure AWS credentials
59+
uses: aws-actions/configure-aws-credentials@v4
60+
with:
61+
aws-access-key-id: ${{ secrets.PIPELINE_USER_ACCESS_KEY_ID }}
62+
aws-secret-access-key: ${{ secrets.PIPELINE_USER_SECRET_ACCESS_KEY }}
63+
aws-region: ${{ vars.AWS_REGION }}
64+
65+
- name: Login to Amazon ECR
66+
id: login-ecr
67+
uses: aws-actions/amazon-ecr-login@v2
68+
with:
69+
mask-password: 'true'
70+
71+
- name: Set up Docker Buildx
72+
uses: docker/setup-buildx-action@v3
73+
74+
- name: Build, tag, and push Client image to Amazon ECR
75+
uses: docker/build-push-action@v5
76+
env:
77+
NEXT_PUBLIC_API_URL: ${{ vars.NEXT_PUBLIC_API_URL }}
78+
NEXT_PUBLIC_MAPBOX_API_TOKEN: ${{ vars.NEXT_PUBLIC_MAPBOX_API_TOKEN }}
79+
NEXT_PUBLIC_MAPBOX_USERNAME: ${{ vars.NEXT_PUBLIC_MAPBOX_USERNAME }}
80+
NEXT_PUBLIC_MAPBOX_STYLE_ID: ${{ vars.NEXT_PUBLIC_MAPBOX_STYLE_ID }}
81+
NEXT_PUBLIC_BASE_PATH: /impact-sphere
82+
with:
83+
build-args: |
84+
NEXT_PUBLIC_API_URL=${{ vars.NEXT_PUBLIC_API_URL }}
85+
NEXT_PUBLIC_MAPBOX_API_TOKEN=${{ vars.NEXT_PUBLIC_MAPBOX_API_TOKEN }}
86+
NEXT_PUBLIC_MAPBOX_USERNAME=${{ vars.NEXT_PUBLIC_MAPBOX_USERNAME }}
87+
NEXT_PUBLIC_MAPBOX_STYLE_ID=${{ vars.NEXT_PUBLIC_MAPBOX_STYLE_ID }}
88+
NEXT_PUBLIC_BASE_PATH=/impact-sphere
89+
context: .
90+
cache-from: type=gha
91+
cache-to: type=gha,mode=max
92+
file: ./client/Dockerfile.prod
93+
push: true
94+
tags: |
95+
${{ steps.login-ecr.outputs.registry }}/${{ vars.CLIENT_REPOSITORY_NAME }}:${{ github.sha }}
96+
${{ steps.login-ecr.outputs.registry }}/${{ vars.CLIENT_REPOSITORY_NAME }}:${{ needs.set_environment.outputs.env_name }}
97+
98+
build_cms:
99+
needs: [set_environment, trigger_build]
100+
if: ${{ github.event_name == 'workflow_dispatch' || needs.trigger_build.outputs.build_cms == 'true' }}
101+
environment:
102+
name: ${{ needs.set_environment.outputs.env_name }}
103+
runs-on: ubuntu-latest
104+
name: Build CMS image and push to Amazon ECR
105+
steps:
106+
- name: Checkout code
107+
uses: actions/checkout@v4
108+
109+
- name: Configure AWS credentials
110+
uses: aws-actions/configure-aws-credentials@v4
111+
with:
112+
aws-access-key-id: ${{ secrets.PIPELINE_USER_ACCESS_KEY_ID }}
113+
aws-secret-access-key: ${{ secrets.PIPELINE_USER_SECRET_ACCESS_KEY }}
114+
aws-region: ${{ vars.AWS_REGION }}
115+
116+
- name: Login to Amazon ECR
117+
id: login-ecr
118+
uses: aws-actions/amazon-ecr-login@v2
119+
with:
120+
mask-password: 'true'
121+
122+
- name: Set up Docker Buildx
123+
uses: docker/setup-buildx-action@v3
124+
125+
- name: Build, tag, and push CMS image to Amazon ECR
126+
uses: docker/build-push-action@v5
127+
with:
128+
context: .
129+
cache-from: type=gha
130+
cache-to: type=gha,mode=max
131+
file: ./cms/Dockerfile.prod
132+
push: true
133+
tags: |
134+
${{ steps.login-ecr.outputs.registry }}/${{ vars.CMS_REPOSITORY_NAME }}:${{ github.sha }}
135+
${{ steps.login-ecr.outputs.registry }}/${{ vars.CMS_REPOSITORY_NAME }}:${{ needs.set_environment.outputs.env_name }}
136+
137+
deploy:
138+
name: Deploy Services to Amazon EBS
139+
needs: [set_environment, build_client, build_cms]
140+
if: >
141+
!failure() &&
142+
(
143+
needs.build_client.result == 'success' ||
144+
needs.build_cms.result == 'success'
145+
)
146+
runs-on: ubuntu-latest
147+
environment:
148+
name: ${{ needs.set_environment.outputs.env_name }}
149+
150+
steps:
151+
- name: Checkout code
152+
uses: actions/checkout@v4
153+
154+
- name: Configure AWS credentials
155+
uses: aws-actions/configure-aws-credentials@v4
156+
with:
157+
aws-access-key-id: ${{ secrets.PIPELINE_USER_ACCESS_KEY_ID }}
158+
aws-secret-access-key: ${{ secrets.PIPELINE_USER_SECRET_ACCESS_KEY }}
159+
aws-region: ${{ vars.AWS_REGION }}
160+
161+
- name: Login to Amazon ECR
162+
id: login-ecr
163+
uses: aws-actions/amazon-ecr-login@v2
164+
165+
- name: Generate docker compose file
166+
working-directory: infrastructure/terraform/source_bundle
167+
env:
168+
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
169+
ECR_REPOSITORY_CLIENT: ${{ vars.CLIENT_REPOSITORY_NAME }}
170+
ECR_REPOSITORY_CMS: ${{ vars.CMS_REPOSITORY_NAME }}
171+
IMAGE_TAG: ${{ needs.set_environment.outputs.env_name }}
172+
run: |
173+
cat <<EOF >> docker-compose.yml
174+
services:
175+
client:
176+
image: $ECR_REGISTRY/$ECR_REPOSITORY_CLIENT:$IMAGE_TAG
177+
restart: always
178+
ports:
179+
- 3000:3000
180+
environment:
181+
- NODE_ENV=production
182+
- NEXTAUTH_SECRET=${{ secrets.NEXTAUTH_SECRET }}
183+
- NEXT_PUBLIC_PREVIEW_SECRET=${{ vars.NEXT_PUBLIC_PREVIEW_SECRET }}
184+
cms:
185+
image: $ECR_REGISTRY/$ECR_REPOSITORY_CMS:$IMAGE_TAG
186+
restart: always
187+
ports:
188+
- 1337:1337
189+
environment:
190+
- NODE_ENV=production
191+
- CMS_URL=${{ vars.CMS_URL }}
192+
- DATABASE_URL=${{ secrets.DATABASE_URL }}
193+
- DATABASE_HOST=${{ secrets.DATABASE_HOST }}
194+
- DATABASE_NAME=${{ secrets.DATABASE_NAME }}
195+
- DATABASE_PASSWORD=${{ secrets.DATABASE_PASSWORD }}
196+
- DATABASE_USERNAME=${{ secrets.DATABASE_USERNAME }}
197+
- DATABASE_PORT=${{ secrets.DATABASE_PORT }}
198+
- DATABASE_SSL=${{ vars.DATABASE_SSL }}
199+
- DATABASE_SSL_REJECT_UNAUTHORIZED=${{ vars.DATABASE_SSL_REJECT_UNAUTHORIZED }}
200+
- AWS_SES_ACCESS_KEY_ID=${{ secrets.AWS_SES_ACCESS_KEY_ID }}
201+
- AWS_SES_ACCESS_KEY_SECRET=${{ secrets.AWS_SES_ACCESS_KEY_SECRET }}
202+
- AWS_SES_DOMAIN=${{ secrets.AWS_SES_DOMAIN }}
203+
- AWS_S3_BUCKET=${{ vars.AWS_S3_BUCKET }}
204+
- AWS_S3_REGION=${{ vars.AWS_S3_REGION }}
205+
- AWS_S3_BUCKET_URL=${{ vars.AWS_S3_BUCKET_URL }}
206+
- ADMIN_JWT_SECRET=${{ secrets.ADMIN_JWT_SECRET }}
207+
- API_TOKEN_SALT=${{ secrets.API_TOKEN_SALT }}
208+
- JWT_SECRET=${{ secrets.JWT_SECRET }}
209+
- PORT=${{ secrets.PORT }}
210+
nginx:
211+
image: nginx
212+
restart: always
213+
volumes:
214+
- ./proxy/conf.d:/etc/nginx/conf.d
215+
- "\${EB_LOG_BASE_DIR}/nginx:/var/log/nginx"
216+
ports:
217+
- 80:80
218+
depends_on:
219+
- cms
220+
- client
221+
EOF
222+
223+
- name: Generate zip file
224+
working-directory: infrastructure/terraform/source_bundle
225+
run: |
226+
zip -r deploy.zip * .[^.]*
227+
228+
- name: Deploy to Amazon EB
229+
uses: einaregilsson/beanstalk-deploy@v21
230+
with:
231+
aws_access_key: ${{ secrets.PIPELINE_USER_ACCESS_KEY_ID }}
232+
aws_secret_key: ${{ secrets.PIPELINE_USER_SECRET_ACCESS_KEY }}
233+
application_name: ${{ vars.PROJECT_NAME}}-${{ needs.set_environment.outputs.env_name }}
234+
environment_name: ${{ vars.PROJECT_NAME}}-${{ needs.set_environment.outputs.env_name }}-env
235+
region: ${{ vars.AWS_REGION }}
236+
version_label: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
237+
deployment_package: infrastructure/terraform/source_bundle/deploy.zip
238+
wait_for_deployment: true

infrastructure/terraform/.terraform.lock.hcl

Lines changed: 59 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

infrastructure/terraform/main.tf

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ module "frontend_ecr" {
3030
ecr_repo_name = "frontend"
3131
}
3232

33+
module "cms_ecr" {
34+
source = "./modules/ecr"
35+
project_name = var.project_name
36+
ecr_repo_name = "cms"
37+
}
38+
3339
module "iam" {
3440
source = "./modules/iam"
3541
}
@@ -45,8 +51,10 @@ module "dev" {
4551
aws = aws.dev
4652
}
4753

48-
source = "./modules/env"
49-
domain = "dev.catalyse.dev-vizzuality.com"
54+
source = "./modules/env"
55+
domain = "esa-gda.dev-vizzuality.com"
56+
base_path = "/impact-sphere"
57+
5058
project = var.project_name
5159
environment = "dev"
5260

@@ -56,7 +64,7 @@ module "dev" {
5664
subnet_ids = module.vpc.public_subnet_ids
5765
availability_zones = module.vpc.availability_zones
5866

59-
beanstalk_platform = "64bit Amazon Linux 2023 v4.7.2 running Docker"
67+
beanstalk_platform = "64bit Amazon Linux 2023 v4.7.3 running Docker"
6068
beanstalk_tier = "WebServer"
6169
ec2_instance_type = "t3.medium"
6270

@@ -67,18 +75,14 @@ module "dev" {
6775
rds_engine_version = "15.13"
6876
rds_backup_retention_period = 3
6977

70-
repo_name = "catalyse"
78+
repo_name = var.github_repo_name
7179
github_owner = var.github_owner
7280
github_token = var.github_token
73-
74-
github_additional_environment_variables = {
75-
AWS_REGION = var.aws_region
76-
}
7781
}
7882

7983
module "github" {
8084
source = "./modules/github"
81-
repo_name = "catalyse"
85+
repo_name = var.github_repo_name
8286
github_owner = var.github_owner
8387
github_token = var.github_token
8488
global_secret_map = {
@@ -88,7 +92,10 @@ module "github" {
8892
global_variable_map = {
8993
PROJECT_NAME = var.project_name
9094
NEXT_PUBLIC_MAPBOX_API_TOKEN = var.mapbox_api_token
95+
NEXT_PUBLIC_MAPBOX_USERNAME = var.mapbox_username
96+
NEXT_PUBLIC_MAPBOX_STYLE_ID = var.mapbox_style_id
9197
AWS_REGION = var.aws_region
9298
CLIENT_REPOSITORY_NAME = module.frontend_ecr.repository_name
99+
CMS_REPOSITORY_NAME = module.cms_ecr.repository_name
93100
}
94101
}

infrastructure/terraform/modules/beanstalk/iam.tf

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -26,31 +26,8 @@ resource "aws_iam_role" "beanstalk_ec2" {
2626
EOF
2727
}
2828

29-
## Instance S3 bucket access policy
30-
31-
resource "aws_iam_role_policy" "beanstalk_ec2_s3_access" {
32-
name = "${var.application_name}-beanstalk-ec2-s3-access"
33-
role = aws_iam_role.beanstalk_ec2.id
34-
35-
policy = jsonencode({
36-
Version = "2012-10-17",
37-
Statement = [
38-
{
39-
Effect = "Allow",
40-
Action = [
41-
"s3:PutObject",
42-
"s3:GetObject",
43-
"s3:DeleteObject",
44-
"s3:ListBucket"
45-
],
46-
Resource = [
47-
var.s3.arn,
48-
"${var.s3.arn}/*"
49-
]
50-
}
51-
]
52-
})
53-
}
29+
## Removed - using Beanstalk's own S3 bucket for artifacts
30+
# resource "aws_iam_role_policy" "beanstalk_ec2_s3_access" { ... }
5431

5532
resource "aws_iam_role_policy_attachment" "beanstalk_ec2_worker" {
5633
role = aws_iam_role.beanstalk_ec2.id

0 commit comments

Comments
 (0)