DevOps

Advanced DevOps Project: Full CI/CD Pipeline on Azure with Terraform, Docker, and Ansible

📌 Introduction

In today’s fast-paced cloud-native world, DevOps engineers are expected to not only understand automation and CI/CD but also to architect, deploy, and monitor production-grade infrastructures. This project showcases a full-scale DevOps pipeline that orchestrates a multi-tier web application on Microsoft Azure using a modern stack:

  • Terraform for infrastructure as code
  • Docker for containerization
  • GitHub Actions for CI/CD automation
  • Ansible for configuration management
  • Prometheus & Grafana for monitoring and alerting

By the end of this tutorial, you’ll have built a resilient, scalable, and secure DevOps workflow deployable on real-world cloud environments.


🧱 Architecture Overview

Let’s visualize the overall design of this DevOps pipeline:

 

  • Frontend: React application served via Docker container
  • Backend: Node.js/Express API in a separate container
  • Database: MongoDB container with volume persistence
  • CI/CD: GitHub Actions building/pushing images to Azure Container Registry (ACR) and running Terraform + Ansible
  • Monitoring: Prometheus and Grafana on a dedicated VM
  • Infrastructure: Azure VNet, NSGs, Load Balancer, Virtual Machines

🔧 Step 1: Provisioning Azure Infrastructure with Terraform

Start by defining infrastructure as code using Terraform modules.

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "rg" {
  name     = "devops-rg"
  location = "East US"
}

resource "azurerm_virtual_network" "vnet" {
  name                = "devops-vnet"
  address_space       = ["10.0.0.0/16"]
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
}

Then add:

  • Subnets for app and monitoring
  • NSGs (Network Security Groups)
  • Public IPs and Load Balancer
  • Azure Container Registry
  • Virtual Machines (Ubuntu)

🚢 Step 2: Dockerizing the Application

Create Dockerfiles for each component.

Dockerfile (backend):

FROM node:18-alpine
WORKDIR /app
COPY . .
RUN npm install
EXPOSE 3000
CMD ["node", "server.js"]

Dockerfile (frontend):

FROM node:18-alpine
WORKDIR /app
COPY . .
RUN npm install && npm run build
EXPOSE 80
CMD ["npx", "serve", "-s", "build"]

Dockerfile (MongoDB) is optional since we can use the official image from Docker Hub.


🔄 Step 3: GitHub Actions CI/CD Pipeline

Create .github/workflows/deploy.yml:

name: CI/CD Pipeline

on:
  push:
    branches: [ main ]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout Code
      uses: actions/checkout@v3

    - name: Log in to Azure
      uses: azure/login@v1
      with:
        creds: ${{ secrets.AZURE_CREDENTIALS }}

    - name: Build Docker Images
      run: |
        docker build -t frontend ./frontend
        docker build -t backend ./backend

    - name: Push to ACR
      run: |
        az acr login --name myacr
        docker tag frontend myacr.azurecr.io/frontend:latest
        docker push myacr.azurecr.io/frontend:latest

    - name: Terraform Init & Apply
      run: |
        cd infrastructure
        terraform init
        terraform apply -auto-approve

🔐 Don’t forget to store secrets like AZURE_CREDENTIALS safely in GitHub Secrets.


⚙️ Step 4: Automating Server Setup with Ansible

Once Terraform creates the VMs, use Ansible to configure them.

Inventory file:

[webservers]
10.0.1.4 ansible_user=azureuser

Playbook (deploy.yml):

- hosts: webservers
  become: yes
  tasks:
    - name: Install Docker
      apt:
        name: docker.io
        state: present

    - name: Pull App Images from ACR
      shell: docker pull myacr.azurecr.io/frontend:latest

    - name: Run Frontend Container
      docker_container:
        name: frontend
        image: myacr.azurecr.io/frontend:latest
        state: started
        ports:
          - "80:80"

📊 Step 5: Monitoring with Prometheus & Grafana

Provision a dedicated VM for monitoring. SSH into it and install:

  • Prometheus for metrics collection
  • Node Exporter on all VMs
  • Grafana for dashboards

Install Prometheus:

sudo useradd --no-create-home prometheus
wget https://github.com/prometheus/prometheus/releases/latest/download/prometheus-*.tar.gz

Prometheus config (prometheus.yml):

scrape_configs:
  - job_name: 'node_exporter'
    static_configs:
      - targets: ['10.0.1.4:9100', '10.0.1.5:9100']

Grafana Dashboards: Import pre-built dashboards for Docker, node metrics, etc.


🔐 Step 6: Security Best Practices

  • Use SSH key pairs for VM access
  • Use GitHub secrets for tokens and credentials
  • Create separate service principals for Terraform and ACR
  • Apply NSG rules to only allow necessary ports (80, 443, 22)
  • Configure auto-updates on VMs

🧠 Conclusion

This advanced DevOps project demonstrates a real-world, production-ready workflow covering everything from infrastructure provisioning to continuous deployment and monitoring. You can extend this further with:

  • SSL termination using NGINX + Let’s Encrypt
  • Horizontal pod scaling via AKS (Azure Kubernetes Service)
  • Advanced alerting via Alertmanager or Azure Monitor

If you’re looking to impress recruiters, showcase your skillset in a portfolio, or solidify your DevOps knowledge, replicating (and customizing) this pipeline will give you a major edge.

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button