CI/CD Integration

Monitor CI/CD pipelines and deployments

GitHub Actions

Monitor GitHub Actions workflows:

# .github/workflows/deploy.yml
name: Deploy to Production

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Deploy application
        run: |
          ./deploy.sh
      
      - name: Report success
        if: success()
        run: |
          curl -X POST ${{ secrets.TELEMETRY_MONITOR_URL }} \
            -H "Content-Type: application/json" \
            -d '{
              "status": "success",
              "message": "Deploy completed",
              "metadata": {
                "commit": "${{ github.sha }}",
                "actor": "${{ github.actor }}",
                "run_id": "${{ github.run_id }}"
              }
            }'
      
      - name: Report failure
        if: failure()
        run: |
          curl -X POST ${{ secrets.TELEMETRY_MONITOR_URL }} \
            -H "Content-Type: application/json" \
            -d '{
              "status": "error",
              "message": "Deploy failed",
              "metadata": {
                "commit": "${{ github.sha }}",
                "run_id": "${{ github.run_id }}"
              }
            }'

Set TELEMETRY_MONITOR_URL in GitHub Secrets.

GitLab CI

# .gitlab-ci.yml
deploy:
  stage: deploy
  script:
    - ./deploy.sh
  after_script:
    - |
      if [ "$CI_JOB_STATUS" == "success" ]; then
        STATUS="success"
        MESSAGE="Deploy completed"
      else
        STATUS="error"
        MESSAGE="Deploy failed"
      fi
      
      curl -X POST "$TELEMETRY_MONITOR_URL" \
        -H "Content-Type: application/json" \
        -d "{
          \"status\": \"$STATUS\",
          \"message\": \"$MESSAGE\",
          \"metadata\": {
            \"commit\": \"$CI_COMMIT_SHA\",
            \"pipeline\": \"$CI_PIPELINE_ID\",
            \"job\": \"$CI_JOB_ID\"
          }
        }"

Jenkins Pipeline

// Jenkinsfile
pipeline {
    agent any
    
    environment {
        MONITOR_URL = credentials('telemetry-monitor-url')
    }
    
    stages {
        stage('Build') {
            steps {
                sh './build.sh'
            }
        }
        
        stage('Test') {
            steps {
                sh './test.sh'
            }
        }
        
        stage('Deploy') {
            steps {
                sh './deploy.sh'
            }
        }
    }
    
    post {
        success {
            sh '''
                curl -X POST "$MONITOR_URL" \
                  -H "Content-Type: application/json" \
                  -d "{
                    \\"status\\": \\"success\\",
                    \\"message\\": \\"Pipeline completed\\",
                    \\"metadata\\": {
                      \\"build\\": \\"$BUILD_NUMBER\\",
                      \\"branch\\": \\"$GIT_BRANCH\\"
                    }
                  }"
            '''
        }
        
        failure {
            sh '''
                curl -X POST "$MONITOR_URL" \
                  -d '{"status":"error","message":"Pipeline failed"}'
            '''
        }
    }
}

CircleCI

# .circleci/config.yml
version: 2.1

jobs:
  deploy:
    docker:
      - image: cimg/base:stable
    steps:
      - checkout
      - run:
          name: Deploy
          command: ./deploy.sh
      - run:
          name: Report to monitoring
          when: always
          command: |
            if [ "$CIRCLE_JOB_STATUS" == "success" ]; then
              STATUS="success"
            else
              STATUS="error"
            fi
            
            curl -X POST "$TELEMETRY_MONITOR_URL" \
              -H "Content-Type: application/json" \
              -d "{
                \"status\": \"$STATUS\",
                \"metadata\": {
                  \"build\": \"$CIRCLE_BUILD_NUM\",
                  \"workflow\": \"$CIRCLE_WORKFLOW_ID\"
                }
              }"

workflows:
  deploy-workflow:
    jobs:
      - deploy

Docker Build Monitoring

#!/bin/bash
# build-and-push.sh

MONITOR_URL="https://telemetry.host/ping/YOUR_MONITOR_ID"
IMAGE_NAME="myapp:latest"

START_TIME=$(date +%s)

# Build image
if docker build -t "$IMAGE_NAME" .; then
    # Push to registry
    if docker push "$IMAGE_NAME"; then
        END_TIME=$(date +%s)
        DURATION=$((END_TIME - START_TIME))
        
        IMAGE_SIZE=$(docker images "$IMAGE_NAME" --format "{{.Size}}")
        
        curl -X POST "$MONITOR_URL" \
            -d "{\"status\":\"success\",\"message\":\"Image built and pushed: $IMAGE_SIZE in ${DURATION}s\"}"
    else
        curl -X POST "$MONITOR_URL" \
            -d '{"status":"error","message":"Failed to push image"}'
        exit 1
    fi
else
    curl -X POST "$MONITOR_URL" \
        -d '{"status":"error","message":"Failed to build image"}'
    exit 1
fi

Kubernetes Deployment

# deployment-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: deploy-app
spec:
  template:
    spec:
      containers:
      - name: deploy
        image: kubectl:latest
        env:
        - name: MONITOR_URL
          valueFrom:
            secretKeyRef:
              name: telemetry-secrets
              key: monitor-url
        command:
        - /bin/sh
        - -c
        - |
          if kubectl apply -f deployment.yaml; then
            curl -X POST "$MONITOR_URL" \
              -d '{"status":"success","message":"Deployment applied"}'
          else
            curl -X POST "$MONITOR_URL" \
              -d '{"status":"error","message":"Deployment failed"}'
            exit 1
          fi
      restartPolicy: Never

Terraform Apply Monitoring

#!/bin/bash
# terraform-apply-monitored.sh

MONITOR_URL="https://telemetry.host/ping/YOUR_MONITOR_ID"

# Create plan
terraform plan -out=tfplan

# Apply with monitoring
if terraform apply tfplan 2>&1 | tee /tmp/tf-output.log; then
    # Extract resources changed
    ADDED=$(grep "resources added" /tmp/tf-output.log | awk '{print $1}')
    CHANGED=$(grep "resources changed" /tmp/tf-output.log | awk '{print $3}')
    DESTROYED=$(grep "resources destroyed" /tmp/tf-output.log | awk '{print $5}')
    
    curl -X POST "$MONITOR_URL" \
        -d "{\"status\":\"success\",\"message\":\"Terraform apply: +$ADDED ~$CHANGED -$DESTROYED\"}"
else
    cat /tmp/tf-output.log | curl -X POST "$MONITOR_URL" \
        -H "Content-Type: text/plain" \
        --data-binary @-
    exit 1
fi

rm /tmp/tf-output.log tfplan

Ansible Playbook Monitoring

# deploy-playbook.yml
- name: Deploy application
  hosts: production
  tasks:
    - name: Deploy application
      command: /opt/deploy.sh
      register: deploy_result
      
    - name: Report success
      uri:
        url: "{{ telemetry_monitor_url }}"
        method: POST
        body_format: json
        body:
          status: "success"
          message: "Ansible deploy completed"
          metadata:
            host: "{{ inventory_hostname }}"
      when: deploy_result.rc == 0
      delegate_to: localhost
      
    - name: Report failure
      uri:
        url: "{{ telemetry_monitor_url }}"
        method: POST
        body_format: json
        body:
          status: "error"
          message: "Ansible deploy failed"
          metadata:
            host: "{{ inventory_hostname }}"
            error: "{{ deploy_result.stderr }}"
      when: deploy_result.rc != 0
      delegate_to: localhost

Multi-Stage Pipeline

#!/bin/bash
# multi-stage-deploy.sh

PROJECT_KEY="your-project-key"
BASE_URL="https://telemetry.host/ping/$PROJECT_KEY"

# Build stage
echo "Building..."
if ./build.sh; then
    curl -X POST "$BASE_URL/timeout/30m/deploy-build?create=1" \
        -d '{"status":"success"}'
else
    curl -X POST "$BASE_URL/timeout/30m/deploy-build?create=1" \
        -d '{"status":"error"}'
    exit 1
fi

# Test stage
echo "Testing..."
if ./test.sh; then
    curl -X POST "$BASE_URL/timeout/30m/deploy-test?create=1" \
        -d '{"status":"success"}'
else
    curl -X POST "$BASE_URL/timeout/30m/deploy-test?create=1" \
        -d '{"status":"error"}'
    exit 1
fi

# Deploy stage
echo "Deploying..."
if ./deploy.sh; then
    curl -X POST "$BASE_URL/timeout/30m/deploy-prod?create=1" \
        -d '{"status":"success"}'
else
    curl -X POST "$BASE_URL/timeout/30m/deploy-prod?create=1" \
        -d '{"status":"error"}'
    exit 1
fi

echo "All stages completed"

Database Migration Monitoring

#!/bin/bash
# run-migrations.sh

MONITOR_URL="https://telemetry.host/ping/YOUR_MONITOR_ID"

# Run migrations
MIGRATION_OUTPUT=$(./manage.py migrate 2>&1)
EXIT_CODE=$?

if [ $EXIT_CODE -eq 0 ]; then
    # Count applied migrations
    APPLIED=$(echo "$MIGRATION_OUTPUT" | grep "Applying" | wc -l)
    
    if [ $APPLIED -gt 0 ]; then
        MESSAGE="Applied $APPLIED migrations"
    else
        MESSAGE="No migrations to apply"
    fi
    
    curl -X POST "$MONITOR_URL" \
        -d "{\"status\":\"success\",\"message\":\"$MESSAGE\"}"
else
    echo "$MIGRATION_OUTPUT" | curl -X POST "$MONITOR_URL" \
        -H "Content-Type: text/plain" \
        --data-binary @-
    exit 1
fi

Next Steps