AWS Azure GCP多云成本监控与预算控制警报
这是一个DevOps, Multimodal AI领域的自动化工作流,包含 12 个节点。主要使用 If, Code, Cron, Slack, WhatsApp 等节点。 AWS Azure GCP多云成本监控与预算控制警报
- •Slack Bot Token 或 Webhook URL
- •可能需要目标 API 的认证凭证
{
"id": "EeqqXkRfJ6ADiRgm",
"meta": {
"instanceId": "dd69efaf8212c74ad206700d104739d3329588a6f3f8381a46a481f34c9cc281",
"templateCredsSetupCompleted": true
},
"name": "AWS Azure GCP 多云成本监控与预算控制警报",
"tags": [],
"nodes": [
{
"id": "b172287e-8522-4204-af8c-a85554e1b9f8",
"name": "Cron 触发器",
"type": "n8n-nodes-base.cron",
"position": [
140,
-180
],
"parameters": {},
"typeVersion": 1
},
{
"id": "9a9bbc21-a699-499e-8c49-1e93ae8304ff",
"name": "AWS 账单获取",
"type": "n8n-nodes-base.httpRequest",
"position": [
360,
-380
],
"parameters": {
"url": "https://ce.us-east-1.amazonaws.com/",
"method": "POST",
"options": {},
"sendBody": true,
"sendHeaders": true,
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": []
},
"genericAuthType": "httpBasicAuth",
"headerParameters": {
"parameters": [
{
"name": "X-Amz-Target",
"value": "AWSInsightsIndexService.GetCostAndUsage"
},
{
"name": "Content-Type",
"value": "application/x-amz-json-1.1"
}
]
}
},
"credentials": {
"httpBasicAuth": {
"id": "in1EZeEnhkmqnkds",
"name": "test - auth"
}
},
"typeVersion": 4.2
},
{
"id": "df146231-83a9-4a21-abcd-d614aeed73d2",
"name": "Azure 账单获取",
"type": "n8n-nodes-base.httpRequest",
"position": [
360,
-180
],
"parameters": {
"url": "https://management.azure.com/subscriptions/{{ $vars.AZURE_SUBSCRIPTION_ID }}/providers/Microsoft.CostManagement/query?api-version=2021-10-01",
"method": "POST",
"options": {},
"sendBody": true,
"sendHeaders": true,
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{}
]
},
"genericAuthType": "oAuth1Api",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"credentials": {
"oAuth1Api": {
"id": "wGEB2bR15nIzYwVz",
"name": "test-auth"
}
},
"typeVersion": 4.2
},
{
"id": "cc6d124d-c8fe-4da7-ab36-46d5f4d896bf",
"name": "GCP 账单获取",
"type": "n8n-nodes-base.httpRequest",
"position": [
360,
20
],
"parameters": {
"url": "https://cloudbilling.googleapis.com/v1/billingAccounts/{{ $vars.GCP_BILLING_ACCOUNT_ID }}/services",
"options": {},
"sendQuery": true,
"authentication": "genericCredentialType",
"genericAuthType": "oAuth1Api",
"queryParameters": {
"parameters": [
{
"name": "filter",
"value": "usage_start_time >= \"{{ $now.minus({hours: 1}).toISO() }}\" AND usage_start_time < \"{{ $now.toISO() }}\""
}
]
}
},
"credentials": {
"oAuth1Api": {
"id": "wGEB2bR15nIzYwVz",
"name": "test-auth"
}
},
"typeVersion": 4.2
},
{
"id": "51f29b8b-cbc0-41e4-8116-1768cc411073",
"name": "数据解析器",
"type": "n8n-nodes-base.code",
"position": [
580,
-180
],
"parameters": {
"jsCode": "const items = $input.all();\nconst mergedData = [];\n\nfor (const item of items) {\n const platform = item.json.platform || 'unknown';\n const cost = item.json.cost || item.json.totalCost || 0;\n const resourceId = item.json.resourceId || item.json.service || 'unknown';\n \n mergedData.push({\n platform,\n cost: parseFloat(cost),\n resourceId,\n timestamp: new Date().toISOString(),\n owner: item.json.tags?.owner || item.json.owner || 'untagged'\n });\n}\n\nreturn mergedData.map(data => ({ json: data }));"
},
"typeVersion": 2
},
{
"id": "6eb4ef65-cdc4-43eb-86f4-00a063b50e90",
"name": "成本激增检测器",
"type": "n8n-nodes-base.code",
"position": [
800,
-180
],
"parameters": {
"jsCode": "const items = $input.all();\nconst alerts = [];\nconst COST_THRESHOLD = parseFloat($vars.COST_THRESHOLD || '50');\nconst SPIKE_MULTIPLIER = parseFloat($vars.SPIKE_MULTIPLIER || '2.0');\n\nfor (const item of items) {\n const cost = item.json.cost;\n const platform = item.json.platform;\n const resourceId = item.json.resourceId;\n \n // Simple spike detection - compare with threshold\n if (cost > COST_THRESHOLD) {\n alerts.push({\n type: 'threshold_exceeded',\n platform,\n resourceId,\n currentCost: cost,\n threshold: COST_THRESHOLD,\n owner: item.json.owner,\n severity: cost > (COST_THRESHOLD * 2) ? 'HIGH' : 'MEDIUM'\n });\n }\n}\n\nreturn alerts.map(alert => ({ json: alert }));"
},
"typeVersion": 2
},
{
"id": "ee98766c-e7e2-4f2c-8d25-9b25a8d9ef24",
"name": "所有者标识符",
"type": "n8n-nodes-base.if",
"position": [
1020,
-180
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "owner-check",
"operator": {
"type": "string",
"operation": "equals",
"rightType": "manual"
},
"leftValue": "={{ $json.owner }}",
"rightValue": "untagged"
}
]
}
},
"typeVersion": 2
},
{
"id": "8eb36fe2-846e-47db-9771-38648146a629",
"name": "自动标记资源",
"type": "n8n-nodes-base.code",
"position": [
1240,
-180
],
"parameters": {
"jsCode": "// Auto-tagging logic based on platform\nconst item = $input.first().json;\nconst platform = item.platform;\nconst resourceId = item.resourceId;\n\nlet tagCommand = '';\n\nswitch(platform) {\n case 'aws':\n tagCommand = `aws ec2 create-tags --resources ${resourceId} --tags Key=CostAlert,Value=true Key=AlertTime,Value=${new Date().toISOString()}`;\n break;\n case 'azure':\n tagCommand = `az resource tag --ids ${resourceId} --tags CostAlert=true AlertTime=${new Date().toISOString()}`;\n break;\n case 'gcp':\n tagCommand = `gcloud compute instances add-labels ${resourceId} --labels=cost-alert=true,alert-time=${Date.now()}`;\n break;\n}\n\nreturn [{ json: { ...item, tagCommand } }];"
},
"typeVersion": 2
},
{
"id": "d07764c6-fc5b-4614-ad39-b9373b67daaa",
"name": "通过电子邮件发送警报",
"type": "n8n-nodes-base.emailSend",
"position": [
1460,
-380
],
"webhookId": "21220fdd-726e-49ea-bb17-acb0f492c96e",
"parameters": {
"text": "=🚨 **Cost Alert** 🚨|**Platform:** {{ $json.platform }}**Resource:** {{ $json.resourceId }}**Current Cost:** ${{ $json.currentCost }}**Threshold:** ${{ $json.threshold }}**Owner:** {{ $json.owner }}**Severity:** {{ $json.severity }}**Time:** {{ $json.timestamp }}*Auto-tagging command:*```{{ $json.tagCommand }}```",
"options": {},
"subject": "🚨 **Cost Alert** 🚨",
"toEmail": "abcdef@gmail.com,xyzabc@gmail.com",
"fromEmail": "abc@gmail.com",
"emailFormat": "text"
},
"credentials": {
"smtp": {
"id": "G1kyF8cSWTZ4vouN",
"name": "SMTP -test"
}
},
"typeVersion": 2.1
},
{
"id": "becc8559-a46a-4d31-a2f9-9b92d2de2d55",
"name": "通过 WhatsApp 发送警报",
"type": "n8n-nodes-base.whatsApp",
"position": [
1460,
-180
],
"webhookId": "6054006c-c647-4ca7-8c64-185201aeebe7",
"parameters": {
"textBody": "=🚨 **Cost Alert** 🚨|**Platform:** {{ $json.platform }}**Resource:** {{ $json.resourceId }}**Current Cost:** ${{ $json.currentCost }}**Threshold:** ${{ $json.threshold }}**Owner:** {{ $json.owner }}**Severity:** {{ $json.severity }}**Time:** {{ $json.timestamp }}*Auto-tagging command:*```{{ $json.tagCommand }}```",
"operation": "send",
"phoneNumberId": "=+919999888877",
"additionalFields": {},
"recipientPhoneNumber": "+919999888844,+919999888833,+919999888822"
},
"credentials": {
"whatsAppApi": {
"id": "b0PxTDPdWzznWnfG",
"name": "WhatsApp-test "
}
},
"typeVersion": 1
},
{
"id": "7cfa7945-ad77-46aa-9942-30a27bc77d55",
"name": "通过 Slack 发送警报",
"type": "n8n-nodes-base.slack",
"position": [
1460,
20
],
"webhookId": "13a6db34-bc6a-4744-9c02-ed3d9260ceb2",
"parameters": {
"text": "🚨 **Cost Alert** 🚨\n\n**Platform:** {{ $json.platform }}\n**Resource:** {{ $json.resourceId }}\n**Current Cost:** ${{ $json.currentCost }}\n**Threshold:** ${{ $json.threshold }}\n**Owner:** {{ $json.owner }}\n**Severity:** {{ $json.severity }}\n**Time:** {{ $json.timestamp }}\n\n*Auto-tagging command:*\n```{{ $json.tagCommand }}```",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "name",
"value": "{{ $vars.SLACK_CHANNEL_ID }}"
},
"otherOptions": {}
},
"credentials": {
"slackApi": {
"id": "MQ0fgwuS8AzfwFvy",
"name": "Slack account - test "
}
},
"typeVersion": 2
},
{
"id": "e3274f83-533e-4cc9-af50-cb50e7ba5db4",
"name": "便签",
"type": "n8n-nodes-base.stickyNote",
"position": [
620,
-620
],
"parameters": {
"color": 6,
"width": 700,
"height": 300,
"content": "## **工作原理**"
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "3e35fbfb-6c60-4cf3-a680-bc0fb7e7239e",
"connections": {
"Data Parser": {
"main": [
[
{
"node": "Cost Spike Detector",
"type": "main",
"index": 0
}
]
]
},
"Cron Trigger": {
"main": [
[
{
"node": "AWS Billing Fetch",
"type": "main",
"index": 0
},
{
"node": "Azure Billing Fetch",
"type": "main",
"index": 0
},
{
"node": "GCP Billing Fetch",
"type": "main",
"index": 0
}
]
]
},
"Owner Identifier": {
"main": [
[
{
"node": "Auto-Tag Resource",
"type": "main",
"index": 0
}
],
[
{
"node": "Auto-Tag Resource",
"type": "main",
"index": 0
}
]
]
},
"AWS Billing Fetch": {
"main": [
[
{
"node": "Data Parser",
"type": "main",
"index": 0
}
]
]
},
"Auto-Tag Resource": {
"main": [
[
{
"node": "Alert Sender On Slack",
"type": "main",
"index": 0
},
{
"node": "Alert Sender On WhatsApp",
"type": "main",
"index": 0
},
{
"node": "Alert Sender On Email",
"type": "main",
"index": 0
}
]
]
},
"GCP Billing Fetch": {
"main": [
[
{
"node": "Data Parser",
"type": "main",
"index": 0
}
]
]
},
"Azure Billing Fetch": {
"main": [
[
{
"node": "Data Parser",
"type": "main",
"index": 0
}
]
]
},
"Cost Spike Detector": {
"main": [
[
{
"node": "Owner Identifier",
"type": "main",
"index": 0
}
]
]
},
"Alert Sender On Email": {
"main": [
[]
]
}
}
}如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
中级 - 开发运维, 多模态 AI
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
Oneclick AI Squad
@oneclick-aiThe AI Squad Initiative is a pioneering effort to build, automate and scale AI-powered workflows using n8n.io. Our mission is to help individuals and businesses integrate AI agents seamlessly into their daily operations from automating tasks and enhancing productivity to creating innovative, intelligent solutions. We design modular, reusable AI workflow templates that empower creators, developers and teams to supercharge their automation with minimal effort and maximum impact.
分享此工作流