Azure DevOps CI/CD Pipeline: Technical Implementation
- Objective: Implement a robust, scalable CI/CD pipeline
- Key Technologies:
Azure DevOps
Azure Pipelines
Jira API
Azure Web Apps
Docker
Pipeline Architecture
- 1. Code Commit (Azure Repos)
- 2. CI Pipeline Trigger
- 3. Build, Lint, and Unit Test
- 4. Containerization & Push to Azure Container Registry
- 5. Blue-Green Deployment to Staging
- 6. Automated Jira Issue Creation
- 7. Integration Testing & Approval
- 8. Production Deployment (Blue-Green Swap)
Local Agent Implementation
- Challenge: Azure for Students subscription parallelism limitations
- Solution: Implement self-hosted agent
- Implementation Steps:
- Download and install agent on local machine
- Configure agent pool in Azure DevOps
- Set up authentication for the agent
# PowerShell script to configure and run the agent
.\config.cmd --unattended `
--url https://dev.azure.com/yourorg `
--auth pat `
--token yourpat `
--pool default `
--agent myagent `
--replace
.\run.cmd
Azure Pipelines Configuration
- YAML-based pipeline definition
- Multi-stage pipeline for CI/CD
# Azure Pipelines YAML
trigger:
- main
stages:
- stage: Build
jobs:
- job: BuildJob
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
inputs:
versionSpec: '14.x'
- script: |
npm install
npm run build
npm test
displayName: 'npm install, build and test'
- stage: Deploy
jobs:
- deployment: DeployWeb
pool:
vmImage: 'ubuntu-latest'
environment: 'production'
strategy:
runOnce:
deploy:
steps:
- task: AzureWebApp@1
inputs:
azureSubscription: 'Resource Manager Connection'
appName: 'yourwebappname'
appType: 'webApp'
Blue-Green Deployment Implementation
- Utilized Azure Web App deployment slots
- Process:
- Deploy to staging slot
- Run tests against staging
- Swap slots if tests pass
# Azure CLI commands for slot swapping
az webapp deployment slot swap \
--resource-group myResourceGroup \
--name myWebApp \
--slot staging \
--target-slot production
Jira Integration
- Used Jira REST API for issue creation
- Implemented in Azure Pipeline using a custom task
# Python script for Jira issue creation
import requests
import json
url = "https://your-domain.atlassian.net/rest/api/2/issue"
auth = ("email@example.com", "api_token")
headers = {"Accept": "application/json", "Content-Type": "application/json"}
payload = json.dumps({
"fields": {
"project": {"key": "PROJECT_KEY"},
"summary": "New build ready for testing",
"description": "A new build has been deployed to staging.",
"issuetype": {"name": "Task"}
}
})
response = requests.post(url, data=payload, headers=headers, auth=auth)
print(json.dumps(json.loads(response.text), sort_keys=True, indent=4, separators=(",", ": ")))
Containerization
- Used Docker for application containerization
- Implemented multi-stage Dockerfile for optimized images
# Multi-stage Dockerfile
FROM node:14 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM node:14-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY package*.json ./
RUN npm install --only=production
EXPOSE 3000
CMD ["npm", "start"]
Security Implementation
- Azure Key Vault for secrets management
- Implemented least-privilege access model
- Container image scanning
# Azure CLI command to create a Key Vault and add a secret
az keyvault create --name "myKeyvault" --resource-group "myResourceGroup" --location "eastus"
az keyvault secret set --vault-name "myKeyvault" --name "mySecret" --value "secretValue"
# Retrieving secret in pipeline
variables:
mySecret: $[azKeyVault(myKeyvault)mySecret]
Challenges and Solutions
- Challenge: Complex service principal configuration
Solution: Implemented a script to automate service principal creation and role assignment
- Challenge: Inconsistent build environments
Solution: Implemented Docker-based build agents for consistency
- Challenge: Long-running tests slowing down the pipeline
Solution: Implemented parallel test execution and test splitting strategies