n8n DevOps Automation: CI/CD Notifications, Monitoring, and Incident Response
Automate your DevOps workflows with n8n. Set up CI/CD notifications, infrastructure monitoring, incident response, deployment tracking, and automated runbooks for your engineering team.

n8n DevOps Automation: CI/CD Notifications, Monitoring, and Incident Response
DevOps teams live in a sea of tools and notifications. n8n can be the connective tissue that ties your CI/CD pipelines, monitoring systems, and incident response processes together — without writing custom integrations.
The DevOps Automation Landscape
Code Push → CI/CD → Build/Test → Deploy → Monitor → Alert → Incident Response
↓ ↓ ↓ ↓ ↓ ↓ ↓
GitHub Jenkins Results Vercel Datadog PagerDuty Runbook
GitLab Actions Coverage AWS Grafana Slack Auto-fix
Bitbucket CircleCI Lint K8s Sentry Opsgenie Rollback
Workflow 1: CI/CD Pipeline Intelligence
GitHub Actions → Slack Digest
// Consolidate CI/CD notifications into a single digest
const events = $input.all(); // Workflow run events
// Only notify on significant events
const significant = events.filter(e => {
const isFailure = e.json.conclusion === 'failure';
const wasSuccessBefore = e.json.previous_conclusion === 'success';
const isMainBranch = e.json.branch === 'main';
return isFailure && (wasSuccessBefore || isMainBranch);
});
if (significant.length > 0) {
// Build Slack message
const message = significant.map(e =>
`❌ *${e.json.repository}*: ${e.json.workflow} failed on \`${e.json.branch}\`\n` +
` Commit: ${e.json.commit_message}\n` +
` <${e.json.run_url}|View Run> | <${e.json.commit_url}|View Commit>`
).join('\n\n');
await sendSlack(message);
}
Deployment Tracker
// Track all deployments in one dashboard
const deployment = $input.item.json;
await db.insert('deployments', {
service: deployment.service,
environment: deployment.environment,
version: deployment.version,
commit: deployment.commit_sha,
deployed_by: deployment.deployer,
timestamp: new Date().toISOString(),
status: deployment.status
});
// Calculate deployment frequency (DORA metric)
const lastWeekDeploys = await db.count('deployments', {
timestamp: { $gte: oneWeekAgo },
status: 'success'
});
// Alert if deployment frequency drops
if (lastWeekDeploys < MIN_DEPLOY_FREQUENCY) {
await sendAlert('⚠️ Deployment frequency below target');
}
Workflow 2: Infrastructure Monitoring Hub
Multi-Source Alert Aggregation
// Aggregate alerts from multiple monitoring tools
const alerts = [];
// Datadog
const ddAlerts = await datadog.getAlerts();
alerts.push(...ddAlerts.map(a => ({ source: 'datadog', ...a })));
// Grafana
const grafanaAlerts = await grafana.getAlerts();
alerts.push(...grafanaAlerts.map(a => ({ source: 'grafana', ...a })));
// AWS CloudWatch
const cwAlerts = await cloudwatch.getAlarms('ALARM');
alerts.push(...cwAlerts.map(a => ({ source: 'cloudwatch', ...a })));
// Sentry
const sentryIssues = await sentry.getIssues({ status: 'unresolved' });
alerts.push(...sentryIssues.map(i => ({ source: 'sentry', ...i })));
// Deduplicate and prioritize
const deduped = deduplicateAlerts(alerts);
const prioritized = prioritizeAlerts(deduped);
// Route based on severity
for (const alert of prioritized) {
if (alert.severity === 'critical') {
await pageOncall(alert);
} else if (alert.severity === 'warning') {
await sendSlack(alert);
} else {
await logToDashboard(alert);
}
}
Server Health Monitor
// Scheduled health check for all servers
const servers = [
{ name: 'prod-api-1', ip: '10.0.1.10', port: 443 },
{ name: 'prod-api-2', ip: '10.0.1.11', port: 443 },
{ name: 'prod-db-1', ip: '10.0.2.10', port: 5432 },
{ name: 'prod-redis-1', ip: '10.0.3.10', port: 6379 }
];
const results = await Promise.all(servers.map(async server => {
const start = Date.now();
try {
const response = await $http.get(`http://${server.ip}:${server.port}/health`);
return {
...server,
status: 'healthy',
latency: Date.now() - start,
timestamp: new Date().toISOString()
};
} catch (error) {
return {
...server,
status: 'unhealthy',
error: error.message,
timestamp: new Date().toISOString()
};
}
}));
// Alert on unhealthy servers
const unhealthy = results.filter(r => r.status !== 'healthy');
if (unhealthy.length > 0) {
await sendSlack(`🚨 ${unhealthy.length} server(s) unhealthy:\n` +
unhealthy.map(s => ` • ${s.name} (${s.ip}): ${s.error}`).join('\n'));
}
Workflow 3: Incident Response Automation
Automated Incident Workflow
// When critical alert fires
const incident = $input.item.json;
// 1. Create incident ticket
const ticket = await jira.createIssue({
project: 'OPS',
type: 'Incident',
summary: incident.title,
priority: incident.severity === 'critical' ? 'Highest' : 'High',
description: incident.description,
labels: ['automated', incident.source]
});
// 2. Create Slack incident channel
const channel = await slack.createChannel(
`incident-${ticket.key.toLowerCase()}-${Date.now()}`
);
// 3. Post incident context
await slack.postMessage(channel, {
text: `🚨 *Incident: ${incident.title}*\n` +
`Severity: ${incident.severity}\n` +
`Service: ${incident.service}\n` +
`Jira: ${ticket.url}\n\n` +
`Recent deployments:\n${getRecentDeployments(incident.service)}\n\n` +
`Recent changes:\n${getRecentChanges(incident.service)}`
});
// 4. Page on-call engineer
await pagerduty.triggerIncident({
title: incident.title,
severity: incident.severity,
details: incident,
links: [{ href: ticket.url, text: 'Jira Ticket' }]
});
// 5. Start incident timer
await db.insert('incidents', {
ticket: ticket.key,
start_time: new Date().toISOString(),
service: incident.service,
severity: incident.severity,
status: 'open'
});
Automated Runbooks
// Execute runbooks based on alert type
const alertType = incident.type;
const runbooks = {
'high_cpu': [
{ action: 'check', target: 'top_processes', params: { server: incident.server } },
{ action: 'check', target: 'recent_deployments', params: { server: incident.server } },
{ action: 'scale', target: 'horizontal_pod_autoscaler', params: { service: incident.service } },
{ action: 'notify', message: 'CPU alert — scaling initiated' }
],
'disk_full': [
{ action: 'check', target: 'disk_usage', params: { server: incident.server } },
{ action: 'cleanup', target: 'docker_images', params: { server: incident.server } },
{ action: 'cleanup', target: 'old_logs', params: { days: 7, server: incident.server } },
{ action: 'notify', message: 'Disk cleanup completed' }
],
'service_down': [
{ action: 'check', target: 'health_endpoint', params: { service: incident.service } },
{ action: 'restart', target: 'service', params: { service: incident.service } },
{ action: 'verify', target: 'health_check', params: { service: incident.service } },
{ action: 'escalate', if_fail: true, message: 'Auto-restart failed' }
]
};
const runbook = runbooks[alertType] || [{ action: 'notify', message: 'No runbook — manual investigation needed' }];
for (const step of runbook) {
const result = await executeRunbookStep(step);
await logRunbookStep(incident.id, step, result);
if (result.failed && step.escalate_on_fail) {
await escalateToHuman(incident, step);
break;
}
}
Workflow 4: Security Operations (SecOps)
Vulnerability Alert Triage
// Process vulnerability scan results
const vulnerability = $input.item.json;
// Calculate risk score
const riskScore = calculateRisk({
cvss: vulnerability.cvss_score,
exploitability: vulnerability.exploit_maturity,
exposure: vulnerability.internet_facing,
dataAccess: vulnerability.data_access_level
});
// Route based on risk
if (riskScore >= 9) {
// Critical — immediate action
await createJiraTicket(vulnerability, 'Highest');
await pageSecurityTeam(vulnerability);
} else if (riskScore >= 7) {
// High — fix within 24 hours
await createJiraTicket(vulnerability, 'High');
await notifyTeam(vulnerability);
} else if (riskScore >= 4) {
// Medium — fix within sprint
await createJiraTicket(vulnerability, 'Medium');
} else {
// Low — backlog
await createJiraTicket(vulnerability, 'Low');
}
Workflow 5: Developer Experience (DX)
Automated PR Review Assignment
// Auto-assign PR reviewers based on code owners
const pr = $input.item.json;
// Get changed files
const files = await github.listFiles(pr.repo, pr.number);
// Map files to teams
const teams = new Set();
for (const file of files) {
if (file.startsWith('src/api/')) teams.add('backend-team');
if (file.startsWith('src/frontend/')) teams.add('frontend-team');
if (file.startsWith('infra/') || file.startsWith('.github/')) teams.add('devops-team');
if (file.includes('.sql') || file.includes('migration')) teams.add('data-team');
}
// Find available reviewers from each team
const reviewers = [];
for (const team of teams) {
const available = await getAvailableReviewers(team);
reviewers.push(available[0]); // Pick first available
}
await github.requestReviewers(pr.repo, pr.number, reviewers);
Metrics and DORA Reporting
// Weekly DORA metrics report
const metrics = {
deployment_frequency: await countDeployments('week'),
lead_time: await averageLeadTime('week'), // Commit to production
change_failure_rate: await calculateCFR('week'),
mean_time_to_recovery: await calculateMTTR('week')
};
const report = `
📊 *Weekly DevOps Metrics*
🚀 Deploy Frequency: ${metrics.deployment_frequency}/week
⏱ Lead Time: ${formatMinutes(metrics.lead_time)}
💥 Change Failure Rate: ${(metrics.change_failure_rate * 100).toFixed(1)}%
🏥 MTTR: ${formatMinutes(metrics.mean_time_to_recovery)}
${metrics.change_failure_rate > 0.15 ? '⚠️ CFR above 15% threshold' : '✅ CFR within target'}
${metrics.mean_time_to_recovery > 60 ? '⚠️ MTTR above 60 min target' : '✅ MTTR within target'}
`;
await sendSlack(report);
Getting Started
- Week 1: Set up CI/CD notifications → Slack
- Week 2: Add deployment tracking and basic monitoring
- Week 3: Implement incident response automations
- Week 4: Layer on security and DORA metrics
Explore our DevOps automation workflows and SecOps templates for production-ready automations.
Share this article
Help others discover n8n automation tips and tricks
Related Articles

n8n Error Handling and Workflow Reliability: Production Best Practices
Essential error handling patterns for n8n workflows in production. Learn retry strategies, circuit breakers, dead letter queues, monitoring, and how to build resilient automation systems.

n8n Webhooks Mastery: Real-Time Automation Triggers Explained
Master n8n webhooks for real-time automation. Learn webhook security, payload handling, retry logic, and advanced patterns. Build instant-trigger workflows that respond in milliseconds.

n8n Workflow Templates: 15 Ready-to-Use Automations for Every Business
A curated collection of 15 battle-tested n8n workflow templates covering marketing, sales, operations, and engineering. Import, customize, and deploy in minutes.
