Skip to content

🚀 Add CI/CD pipeline (via OpsTools) #3

🚀 Add CI/CD pipeline (via OpsTools)

🚀 Add CI/CD pipeline (via OpsTools) #3

Workflow file for this run

name: CI/CD Pipeline - Node.js API to AWS ECS
on:
push:
branches:
- main
- develop
pull_request:
branches:
- main
- develop
env:
AWS_REGION: us-east-1
ECR_REPOSITORY: node-api
ECS_SERVICE: node-api-service
ECS_CLUSTER: node-api-cluster
permissions:
id-token: write
contents: read
jobs:
lint:
name: Lint Code
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@b4ffde65f69735febad081b8f525ce356e475d86 # v4.1.1
- name: Setup Node.js
uses: actions/setup-node@60edb5dd545a775178fbb3563ff8483803168bc5 # v4.0.2
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run ESLint
run: npm run lint --if-present
test:
name: Run Tests
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@b4ffde65f69735febad081b8f525ce356e475d86 # v4.1.1
- name: Setup Node.js
uses: actions/setup-node@60edb5dd545a775178fbb3563ff8483803168bc5 # v4.0.2
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
- name: Upload coverage
uses: codecov/codecov-action@5ecb98a3c6b747ed38dc09f64a43ec8d490d8de9 # v3.1.4
if: always()
build-and-push:
name: Build and Push Docker Image
runs-on: ubuntu-22.04
needs: [lint, test]
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop')
outputs:
image-tag: ${{ steps.image.outputs.tag }}
steps:
- name: Checkout code
uses: actions/checkout@b4ffde65f69735febad081b8f525ce356e475d86 # v4.1.1
- name: Configure AWS credentials with OIDC
uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2
with:
role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
aws-region: ${{ env.AWS_REGION }}
role-session-name: github-actions-session
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@062b18b96a7aabf0d32092427e2b915fcc71c7de # v2.0.1
- name: Build and tag image
id: image
env:
REGISTRY: ${{ steps.login-ecr.outputs.registry }}
COMMIT_SHA: ${{ github.sha }}
BRANCH_NAME: ${{ github.ref_name }}
run: |
IMAGE_TAG="${BRANCH_NAME}-${COMMIT_SHA::8}"
docker build -t $REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker tag $REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG $REGISTRY/$ECR_REPOSITORY:latest
echo "tag=$IMAGE_TAG" >> $GITHUB_OUTPUT
echo "registry=$REGISTRY" >> $GITHUB_OUTPUT
- name: Push image to ECR
env:
REGISTRY: ${{ steps.image.outputs.registry }}
IMAGE_TAG: ${{ steps.image.outputs.tag }}
run: |
docker push $REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
docker push $REGISTRY/$ECR_REPOSITORY:latest
terraform-plan:
name: Terraform Plan
runs-on: ubuntu-22.04
needs: [build-and-push]
if: github.event_name == 'push'
steps:
- name: Checkout code
uses: actions/checkout@b4ffde65f69735febad081b8f525ce356e475d86 # v4.1.1
- name: Configure AWS credentials with OIDC
uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2
with:
role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
aws-region: ${{ env.AWS_REGION }}
role-session-name: github-actions-session
- name: Setup Terraform
uses: hashicorp/setup-terraform@3523b56c0e4a3f2d19eff39fe629ab42f7c5e2e4 # v2.4.0
- name: Terraform Init
working-directory: terraform
run: terraform init
- name: Terraform Format Check
working-directory: terraform
run: terraform fmt -check
- name: Terraform Validate
working-directory: terraform
run: terraform validate
- name: Terraform Plan
working-directory: terraform
env:
TF_VAR_image_tag: ${{ needs.build-and-push.outputs.image-tag }}
run: terraform plan -out=tfplan
- name: Upload Terraform Plan
uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5d # v4.3.1
with:
name: tfplan
path: terraform/tfplan
deploy:
name: Deploy to AWS ECS
runs-on: ubuntu-22.04
needs: [build-and-push, terraform-plan]
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
environment:
name: production
steps:
- name: Checkout code
uses: actions/checkout@b4ffde65f69735febad081b8f525ce356e475d86 # v4.1.1
- name: Configure AWS credentials with OIDC
uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2
with:
role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
aws-region: ${{ env.AWS_REGION }}
role-session-name: github-actions-session
- name: Download Terraform Plan
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.1
with:
name: tfplan
path: terraform
- name: Setup Terraform
uses: hashicorp/setup-terraform@3523b56c0e4a3f2d19eff39fe629ab42f7c5e2e4 # v2.4.0
- name: Terraform Init
working-directory: terraform
run: terraform init
- name: Terraform Apply
working-directory: terraform
env:
TF_VAR_image_tag: ${{ needs.build-and-push.outputs.image-tag }}
run: terraform apply -auto-approve tfplan
- name: Update ECS Service
run: |
aws ecs update-service \
--cluster $ECS_CLUSTER \
--service $ECS_SERVICE \
--force-new-deployment \