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
- See microservices monitoring
- Learn about Docker health checks
- Explore cron monitoring