Skip to content

Commit 8f8f4e8

Browse files
committed
ci: add CI/CD pipeline via OpsTools
1 parent 211fedb commit 8f8f4e8

1 file changed

Lines changed: 194 additions & 0 deletions

File tree

.github/workflows/ci-cd.yml

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
name: CI/CD Pipeline - Node.js API to AWS ECS
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
- develop
8+
pull_request:
9+
branches:
10+
- main
11+
- develop
12+
13+
env:
14+
AWS_REGION: us-east-1
15+
ECR_REPOSITORY: node-api
16+
ECS_SERVICE: node-api-service
17+
ECS_CLUSTER: node-api-cluster
18+
19+
permissions:
20+
id-token: write
21+
contents: read
22+
23+
jobs:
24+
lint:
25+
name: Lint Code
26+
runs-on: ubuntu-22.04
27+
steps:
28+
- name: Checkout code
29+
uses: actions/checkout@b4ffde65f69735febad081b8f525ce356e475d86 # v4.1.1
30+
31+
- name: Setup Node.js
32+
uses: actions/setup-node@60edb5dd545a775178fbb3563ff8483803168bc5 # v4.0.2
33+
with:
34+
node-version: '20'
35+
cache: 'npm'
36+
37+
- name: Install dependencies
38+
run: npm ci
39+
40+
- name: Run ESLint
41+
run: npm run lint --if-present
42+
43+
test:
44+
name: Run Tests
45+
runs-on: ubuntu-22.04
46+
steps:
47+
- name: Checkout code
48+
uses: actions/checkout@b4ffde65f69735febad081b8f525ce356e475d86 # v4.1.1
49+
50+
- name: Setup Node.js
51+
uses: actions/setup-node@60edb5dd545a775178fbb3563ff8483803168bc5 # v4.0.2
52+
with:
53+
node-version: '20'
54+
cache: 'npm'
55+
56+
- name: Install dependencies
57+
run: npm ci
58+
59+
- name: Run tests
60+
run: npm test
61+
62+
- name: Upload coverage
63+
uses: codecov/codecov-action@5ecb98a3c6b747ed38dc09f64a43ec8d490d8de9 # v3.1.4
64+
if: always()
65+
66+
build-and-push:
67+
name: Build and Push Docker Image
68+
runs-on: ubuntu-22.04
69+
needs: [lint, test]
70+
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop')
71+
outputs:
72+
image-tag: ${{ steps.image.outputs.tag }}
73+
steps:
74+
- name: Checkout code
75+
uses: actions/checkout@b4ffde65f69735febad081b8f525ce356e475d86 # v4.1.1
76+
77+
- name: Configure AWS credentials with OIDC
78+
uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2
79+
with:
80+
role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
81+
aws-region: ${{ env.AWS_REGION }}
82+
role-session-name: github-actions-session
83+
84+
- name: Login to Amazon ECR
85+
id: login-ecr
86+
uses: aws-actions/amazon-ecr-login@062b18b96a7aabf0d32092427e2b915fcc71c7de # v2.0.1
87+
88+
- name: Build and tag image
89+
id: image
90+
env:
91+
REGISTRY: ${{ steps.login-ecr.outputs.registry }}
92+
COMMIT_SHA: ${{ github.sha }}
93+
BRANCH_NAME: ${{ github.ref_name }}
94+
run: |
95+
IMAGE_TAG="${BRANCH_NAME}-${COMMIT_SHA::8}"
96+
docker build -t $REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
97+
docker tag $REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG $REGISTRY/$ECR_REPOSITORY:latest
98+
echo "tag=$IMAGE_TAG" >> $GITHUB_OUTPUT
99+
echo "registry=$REGISTRY" >> $GITHUB_OUTPUT
100+
101+
- name: Push image to ECR
102+
env:
103+
REGISTRY: ${{ steps.image.outputs.registry }}
104+
IMAGE_TAG: ${{ steps.image.outputs.tag }}
105+
run: |
106+
docker push $REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
107+
docker push $REGISTRY/$ECR_REPOSITORY:latest
108+
109+
terraform-plan:
110+
name: Terraform Plan
111+
runs-on: ubuntu-22.04
112+
needs: [build-and-push]
113+
if: github.event_name == 'push'
114+
steps:
115+
- name: Checkout code
116+
uses: actions/checkout@b4ffde65f69735febad081b8f525ce356e475d86 # v4.1.1
117+
118+
- name: Configure AWS credentials with OIDC
119+
uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2
120+
with:
121+
role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
122+
aws-region: ${{ env.AWS_REGION }}
123+
role-session-name: github-actions-session
124+
125+
- name: Setup Terraform
126+
uses: hashicorp/setup-terraform@3523b56c0e4a3f2d19eff39fe629ab42f7c5e2e4 # v2.4.0
127+
128+
- name: Terraform Init
129+
working-directory: terraform
130+
run: terraform init
131+
132+
- name: Terraform Format Check
133+
working-directory: terraform
134+
run: terraform fmt -check
135+
136+
- name: Terraform Validate
137+
working-directory: terraform
138+
run: terraform validate
139+
140+
- name: Terraform Plan
141+
working-directory: terraform
142+
env:
143+
TF_VAR_image_tag: ${{ needs.build-and-push.outputs.image-tag }}
144+
run: terraform plan -out=tfplan
145+
146+
- name: Upload Terraform Plan
147+
uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5d # v4.3.1
148+
with:
149+
name: tfplan
150+
path: terraform/tfplan
151+
152+
deploy:
153+
name: Deploy to AWS ECS
154+
runs-on: ubuntu-22.04
155+
needs: [build-and-push, terraform-plan]
156+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
157+
environment:
158+
name: production
159+
steps:
160+
- name: Checkout code
161+
uses: actions/checkout@b4ffde65f69735febad081b8f525ce356e475d86 # v4.1.1
162+
163+
- name: Configure AWS credentials with OIDC
164+
uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2
165+
with:
166+
role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
167+
aws-region: ${{ env.AWS_REGION }}
168+
role-session-name: github-actions-session
169+
170+
- name: Download Terraform Plan
171+
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.1
172+
with:
173+
name: tfplan
174+
path: terraform
175+
176+
- name: Setup Terraform
177+
uses: hashicorp/setup-terraform@3523b56c0e4a3f2d19eff39fe629ab42f7c5e2e4 # v2.4.0
178+
179+
- name: Terraform Init
180+
working-directory: terraform
181+
run: terraform init
182+
183+
- name: Terraform Apply
184+
working-directory: terraform
185+
env:
186+
TF_VAR_image_tag: ${{ needs.build-and-push.outputs.image-tag }}
187+
run: terraform apply -auto-approve tfplan
188+
189+
- name: Update ECS Service
190+
run: |
191+
aws ecs update-service \
192+
--cluster $ECS_CLUSTER \
193+
--service $ECS_SERVICE \
194+
--force-new-deployment \

0 commit comments

Comments
 (0)