aitayemi/aws-devops-agent

GitHub: aitayemi/aws-devops-agent

基于 AWS DevOps Agent 与 CloudWatch 构建的跨账户自主事件响应流水线,实现多账户基础设施的自动化监控告警与 AI 辅助调查。

Stars: 0 | Forks: 0

# aws-devops-agent 使用 AWS DevOps Agent、CloudWatch Internet Monitor 和跨账户基础设施构建自主事件响应流水线 # 跨账户 CloudFormation 部署 ## 账户映射 | 角色 | 账户 ID | 资源 | |------|-----------|-----------| | 账户 A (Web 层) | 111111111111 | EC2 httpd, ALB, Elastic IP, CloudWatch Alarms, Internet Monitor, EC2 Auto-Recovery, DevOps Agent Space | | 账户 B (数据层) | 222222222222 | PostgreSQL RDS 16.13, VPC Peering Accepter, NAT Gateway, DevOps Agent Secondary Role, Resource Explorer | ## 架构 ``` ┌──────────────────────────────────────────┐ ┌──────────────────────────────────────┐ │ Account A: 111111111111 │ │ Account B: 222222222222 │ │ (Web Tier + DevOps Agent) │ │ (Data Tier) │ │ │ │ │ │ ┌────────────────────────────────────┐ │ │ ┌────────────────────────────────┐ │ │ │ EC2 (httpd) ─── t3.small │──┼────────►│──│ RDS PostgreSQL 16.13 │ │ │ │ Elastic IP (public) │ │ VPC │ │ Table: whoami → "AWS Rocks" │ │ │ │ Ports 80/443/22 open │ │ Peering │ │ Parameter Group: MD5 auth │ │ │ └────────────────────────────────────┘ │ │ └────────────────────────────────┘ │ │ │ │ │ │ ┌────────────────────────────────────┐ │ │ ┌────────────────────────────────┐ │ │ │ ALB (internet-facing) │ │ │ │ Lambda (DB Seed) │ │ │ │ Internet Monitor (VPC) │ │ │ │ Pure Python socket/ssl │ │ │ │ Resource Explorer (AGGREGATOR) │──┼────────►│ │ SSL negotiation + MD5 auth │ │ │ │ DevOps Agent Space │ │ Source │ └────────────────────────────────┘ │ │ └────────────────────────────────────┘ │ Assoc │ │ │ │ │ ┌────────────────────────────────┐ │ │ CloudWatch Alarms (8 total): │ │ │ NAT Gateway (Lambda internet) │ │ │ • Unhealthy Hosts │ │ │ Resource Explorer (LOCAL) │ │ │ • 5xx Errors │ │ │ DevOps Agent Secondary Role │ │ │ • Status Check Failed │ │ └────────────────────────────────┘ │ │ • High CPU │ │ │ │ • Route53 Health Check │ │ │ │ • Internet Availability < 95% │ │ │ │ • Internet Performance < 95% │ │ │ │ • EC2 Auto-Recovery │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ SNS ──► Email + DevOps Agent ──► AI Investigation │ │ │ EC2 Auto-Recovery ──► Automatic instance recovery │ │ └──────────────────────────────────────────┘ └──────────────────────────────────────┘ ``` ## 标签 所有资源都标记有: - `auto-delete: no` — 防止自动清理 - `devops-agent-app: httpd-whoami` — 为 DevOps Agent 关联跨账户的资源 - `devops-agent-monitored: true` — 标记资源供 Agent 发现 ## 完整部署计划 ### 阶段 1:跨账户 IAM 信任(一次性设置) 这些角色使账户 A 能够将 stack 部署到账户 B 中并建立 VPC peering。 **步骤 1.1 — 在账户 A (111111111111) 中创建 StackSet Administration Role** ``` aws iam create-role --role-name AWSCloudFormationStackSetAdministrationRole \ --assume-role-policy-document '{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": {"Service": "cloudformation.amazonaws.com"}, "Action": "sts:AssumeRole" }] }' --profile account-a aws iam put-role-policy --role-name AWSCloudFormationStackSetAdministrationRole \ --policy-name AssumeExecutionRole \ --policy-document '{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::222222222222:role/AWSCloudFormationStackSetExecutionRole" }] }' --profile account-a ``` **步骤 1.2 — 在账户 B (222222222222) 中创建 StackSet Execution Role** ``` aws iam create-role --role-name AWSCloudFormationStackSetExecutionRole \ --assume-role-policy-document '{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": {"AWS": "arn:aws:iam::111111111111:root"}, "Action": "sts:AssumeRole" }] }' --profile account-b aws iam attach-role-policy --role-name AWSCloudFormationStackSetExecutionRole \ --policy-arn arn:aws:iam::aws:policy/AdministratorAccess \ --profile account-b ``` **步骤 1.3 — 在账户 B (222222222222) 中创建 VPCPeeringRole** ``` aws iam create-role --role-name VPCPeeringRole \ --assume-role-policy-document '{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": {"AWS": "arn:aws:iam::111111111111:root"}, "Action": "sts:AssumeRole" }] }' --profile account-b aws iam put-role-policy --role-name VPCPeeringRole \ --policy-name AcceptVPCPeering \ --policy-document '{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": [ "ec2:AcceptVpcPeeringConnection", "ec2:CreateVpcPeeringConnection", "ec2:DescribeVpcPeeringConnections", "ec2:DescribeVpcs" ], "Resource": "*" }] }' --profile account-b ``` **步骤 1.4 — 验证跨账户访问** ``` aws sts assume-role \ --role-arn arn:aws:iam::222222222222:role/AWSCloudFormationStackSetExecutionRole \ --role-session-name test-cross-account \ --profile account-a ``` 如果返回了临时凭证,则阶段 1 已完成。 ### 阶段 2:部署 RDS(账户 B — 222222222222) **步骤 2.1 — 部署 RDS stack** ``` aws cloudformation deploy \ --template-file rds-stack.yaml \ --stack-name whoami-rds \ --parameter-overrides \ DBMasterPassword=YourSecurePass123 \ PeerAccountId=111111111111 \ --capabilities CAPABILITY_NAMED_IAM \ --region us-east-1 \ --profile account-b ``` 这会创建: - 包含私有子网的 VPC (10.1.0.0/16) - PostgreSQL 16.13 RDS 实例(db.t3.micro,无备份,DeletionPolicy: Delete) - 带有 `password_encryption=md5` 的 DB Parameter Group(为了兼容 Lambda 所需) - 将 "AWS Rocks" 种子数据写入 `whoami` 表的 Lambda 函数(纯 Python,无外部 layer) - 用于 Lambda 访问互联网的 NAT Gateway(cfnresponse callback) - 允许来自 Web VPC CIDR 和 Lambda SG 的 PostgreSQL 流量的安全组 **步骤 2.2 — 记录输出** ``` aws cloudformation describe-stacks \ --stack-name whoami-rds \ --query 'Stacks[0].Outputs' \ --output table \ --region us-east-1 \ --profile account-b ``` 保存这些值以供阶段 3 使用: - `RDSEndpoint` — 例如 `production-whoami-db.xxxx.us-east-1.rds.amazonaws.com` - `VpcId` — 例如 `vpc-0abc123` - `PrivateRouteTableId` — 例如 `rtb-0def456` ### 阶段 3:部署 Web 服务器(账户 A — 111111111111) **步骤 3.1 — 查找或创建 EC2 密钥对** ``` # 列出现有密钥对 aws ec2 describe-key-pairs --query 'KeyPairs[*].KeyName' --output table \ --region us-east-1 --profile account-a # 或者创建一个新的 aws ec2 create-key-pair --key-name devops-agent-keypair \ --query 'KeyMaterial' --output text \ --region us-east-1 --profile account-a > ~/devops-agent-keypair.pem chmod 400 ~/devops-agent-keypair.pem ``` **步骤 3.2 — 部署 Web stack** ``` aws cloudformation deploy \ --template-file web-stack.yaml \ --stack-name whoami-web \ --parameter-overrides \ RDSEndpoint= \ DBPassword=YourSecurePass123 \ KeyPairName=devops-agent-keypair \ PeerVpcId= \ PeerAccountId=222222222222 \ PeerRoleArn=arn:aws:iam::222222222222:role/VPCPeeringRole \ DevOpsAgentEmail=your-email@example.com \ --capabilities CAPABILITY_NAMED_IAM \ --region us-east-1 \ --profile account-a ``` 这会创建: - 包含公有子网和 Internet Gateway 的 VPC (10.0.0.0/16) - 位于公有子网中带有 httpd 的 EC2 实例 (t3.small) - Elastic IP(稳定的公有地址) - 安全组:入向开放端口 80, 443, 22,来源为 0.0.0.0/0 - Application Load Balancer (面向互联网) - 到账户 B 的 VPC Peering 连接(使用 VPCPeeringRole) - CloudWatch Internet Monitor(监控到 VPC 的互联网路径质量) - 用于 Internet Monitor 日志的 S3 存储桶(DeletionPolicy: Delete,30天过期) - 8 个 CloudWatch Alarms → SNS topic(包含 EC2 Auto-Recovery 告警) - Route 53 Health Check - Incident Manager IAM 角色(遗留 — 响应计划已被注释掉,见下方注释) **步骤 3.3 — 记录输出** ``` aws cloudformation describe-stacks \ --stack-name whoami-web \ --query 'Stacks[0].Outputs' \ --output table \ --region us-east-1 \ --profile account-a ``` 保存: - `VPCPeeringConnectionId` — 例如 `pcx-0abc123` - `WebsiteURL` — 例如 `http://production-web-alb-xxxx.us-east-1.elb.amazonaws.com` - `WebServerPublicIP` — 例如 `54.x.x.x` - `WebServerDirectURL` — 例如 `http://54.x.x.x` ### 阶段 4:完成 VPC Peering(账户 B — 222222222222) **步骤 4.1 — 接受 VPC peering 连接** ``` aws ec2 accept-vpc-peering-connection \ --vpc-peering-connection-id \ --region us-east-1 \ --profile account-b ``` **步骤 4.2 — 部署 peering accepter stack(添加返回路由)** ``` aws cloudformation deploy \ --template-file vpc-peering-accepter.yaml \ --stack-name whoami-peering \ --parameter-overrides \ VPCPeeringConnectionId= \ RDSRouteTableId= \ --capabilities CAPABILITY_NAMED_IAM \ --region us-east-1 \ --profile account-b ``` **步骤 4.3 — 验证连通性** 通过 ALB 测试: ``` curl http:///health # 预期:OK curl http:/// # 预期:带有 "AWS Rocks" 的 HTML 页面 ``` 通过 EC2 公网 IP 直接测试: ``` curl http:///health # 预期:OK ``` ### 阶段 5:部署 DevOps Agent(两个账户) **步骤 5.1 — 在账户 B (222222222222) 中部署辅助账户角色** ``` aws cloudformation deploy \ --template-file devops-agent-service-account.yaml \ --stack-name DevOpsAgentServiceAccountStack \ --parameter-overrides \ MonitoringAccountId=111111111111 \ AgentSpaceArn='arn:aws:aidevops:us-east-1:111111111111:agentspace/*' \ --capabilities CAPABILITY_NAMED_IAM \ --region us-east-1 \ --profile account-b ``` 这会创建: - Resource Explorer LOCAL index(启用账户 B 中的资源发现) - 具有针对 RDS、VPC、Lambda、CloudWatch、CloudFormation、tags 权限的跨账户 IAM 角色 **步骤 5.2 — 在账户 A (111111111111) 中部署 DevOps Agent Space** ``` aws cloudformation deploy \ --template-file devops-agent-stack.yaml \ --stack-name DevOpsAgentStack \ --capabilities CAPABILITY_NAMED_IAM \ --region us-east-1 \ --profile account-a ``` 这会创建: - Resource Explorer AGGREGATOR index(集中资源发现) - 带有 Operator App 的 DevOps Agent Space - Monitor 关联(账户 A 资源) - Source 关联(账户 B 资源) - 具有对 EC2、ALB、CloudWatch、Route53、SSM、CloudFormation、SNS、Incident Manager、tags、Resource Explorer 完全读取权限的 IAM 角色 **步骤 5.3 — 记录 Agent Space 输出** ``` aws cloudformation describe-stacks \ --stack-name DevOpsAgentStack \ --query 'Stacks[0].Outputs' \ --output table \ --region us-east-1 \ --profile account-a ``` 保存: - `AgentSpaceId` - `AgentSpaceArn` **步骤 5.4 — (推荐)使用确切的 ARN 收紧账户 B 角色** ``` aws cloudformation deploy \ --template-file devops-agent-service-account.yaml \ --stack-name DevOpsAgentServiceAccountStack \ --parameter-overrides \ MonitoringAccountId=111111111111 \ AgentSpaceArn= \ --capabilities CAPABILITY_NAMED_IAM \ --region us-east-1 \ --profile account-b ``` **步骤 5.5 — 验证 DevOps Agent** ``` # 列出 agent 空间 aws devops-agent list-agent-spaces \ --region us-east-1 \ --profile account-a # 验证两个关联(monitor + source) aws devops-agent list-associations \ --agent-space-id \ --region us-east-1 \ --profile account-a ``` 您应该会看到两个关联: - `monitor` — 账户 A (111111111111) - `source` — 账户 B (222222222222) **步骤 5.6 — 访问 DevOps Agent Operator App** 在浏览器中打开: ``` https://us-east-1.console.aws.amazon.com/devops-agent/home?region=us-east-1 ``` Agent 的资源树应显示来自两个账户的资源: - 账户 A:EC2, ALB, Elastic IP, CloudWatch Alarms, Route53 Health Checks, SNS, Internet Monitor - 账户 B:RDS PostgreSQL, VPC, Lambda, NAT Gateway, DB Parameter Group ### 阶段 6:确认端到端连通性 **步骤 6.1 — 确认 SNS 订阅** 检查您的电子邮件以获取 SNS 订阅确认,并点击其中的链接。 **步骤 6.2 — 验证 Internet Monitor 是否在收集数据** ``` aws internetmonitor get-monitor \ --monitor-name production-httpd-internet-monitor \ --region us-east-1 \ --profile account-a ``` 状态应为 `ACTIVE`。数据收集将在 15-30 分钟内开始。 **步骤 6.3 — 测试告警(可选)** 停止 EC2 实例以触发告警: ``` INSTANCE_ID=$(aws cloudformation describe-stacks \ --stack-name whoami-web \ --query 'Stacks[0].Outputs[?OutputKey==`InstanceId`].OutputValue' \ --output text --region us-east-1 --profile account-a) aws ec2 stop-instances --instance-ids $INSTANCE_ID \ --region us-east-1 --profile account-a ``` 在 2-3 分钟内: 1. CloudWatch Alarms 转换为 ALARM 状态 2. Composite alarm 触发 → Lambda 调用 → DevOps Agent 调查开始 3. SNS 向您的电子邮件发送通知 4. EC2 Auto-Recovery 告警触发自动实例恢复(在系统状态检查失败时) 重启实例: ``` aws ec2 start-instances --instance-ids $INSTANCE_ID \ --region us-east-1 --profile account-a ``` ### 阶段 7(可选):部署 Webhook Lambda 用于自动 DevOps Agent 调查 此阶段部署一个 Lambda 函数和 Composite alarm,只要任何 httpd 告警触发,就会自动触发 DevOps Agent 调查。 **步骤 7.1 — 部署 Webhook Lambda Stack** ``` aws cloudformation deploy \ --template-file devops-agent-webhook-lambda.yaml \ --stack-name devops-agent-webhook \ --capabilities CAPABILITY_NAMED_IAM \ --region us-east-1 \ --profile account-a ``` 这会创建: - 接收告警事件并将 HMAC 签名的 payload 发送到 DevOps Agent Webhook 的 Lambda 函数 - 具有 CloudWatch 读取权限的 IAM 角色 - 允许 CloudWatch Alarms 调用它的 Lambda 权限 - 监控所有 8 个 httpd 告警并在任何一个进入 ALARM 状态时触发 Lambda 的 Composite alarm **步骤 7.2 — 验证 Composite alarm 是否存在** ``` aws cloudwatch describe-alarms \ --alarm-names production-devops-agent-investigation-trigger \ --region us-east-1 \ --profile account-a ``` **步骤 7.3 — 测试:触发告警并检查 DevOps Agent App** 当任何告警触发时,Composite alarm 触发 → Lambda 发送 Webhook → 调查任务在 1-2 分钟内出现在 DevOps Agent Operator App 中。 ## 文件参考 | 文件 | 部署至 | 阶段 | 用途 | |------|-----------|-------|---------| | `setup-cross-account-roles.sh` | 两者 | 1 | 用于 IAM 角色设置的交互式脚本(包含 VPCPeeringRole) | | `rds-stack.yaml` | 账户 B (222222222222) | 2 | PostgreSQL RDS 16.13 + whoami 表 ("AWS Rocks") + VPC + NAT + Parameter Group (MD5) | | `web-stack.yaml` | 账户 A (111111111111) | 3 | httpd EC2 + EIP + ALB + 8 个 Alarms + Internet Monitor + EC2 Auto-Recovery + Incident Manager IAM 角色(遗留) | | `vpc-peering-accepter.yaml` | 账户 B (222222222222) | 4 | 接受 peering + 返回路由 + VPCPeeringRole 定义 | | `devops-agent-service-account.yaml` | 账户 B (222222222222) | 5 | 跨账户角色 + DevOps Agent 的 Resource Explorer (LOCAL) | | `devops-agent-stack.yaml` | 账户 A (111111111111) | 5 | Agent Space + 关联 + Resource Explorer (AGGREGATOR) | | `devops-agent-webhook-lambda.yaml` | 账户 A (111111111111) | 7 | Lambda + Composite alarm,用于在告警时触发 DevOps Agent 调查 | | `stackset-deployment.yaml` | 管理账户 | 替代方案 | 替代方案:通过 StackSets 从一个账户进行部署 | ## 监控摘要 | # | 告警 | 监控内容 | 触发条件 | |---|-------|----------------|---------| | 1 | ALB Unhealthy Hosts | httpd 未响应 ALB health checks | > 0 个不健康,持续 2 分钟 | | 2 | ALB 5xx Errors | 来自 httpd 的服务器错误 | 5 分钟内 > 10 个错误 | | 3 | EC2 Status Check | 实例硬件/软件故障 | 任何故障持续 2 分钟 | | 4 | EC2 CPU | 资源耗尽 | > 80%,持续 10 分钟 | | 5 | Route53 Health Check | 外部 HTTP 可达性 | 连续 3 次失败 | | 6 | Internet Monitor Availability | 影响用户的 ISP/路由问题 | 得分 < 95%,持续 10 分钟 | | 7 | Internet Monitor Performance | 面向用户的延迟下降 | 得分 < 95%,持续 10 分钟 | | 8 | EC2 Auto-Recovery | 系统状态检查失败(硬件) | > 0,持续 2 × 60s | 所有告警 → SNS → 电子邮件通知 所有告警 → Composite alarm → Lambda → DevOps Agent Webhook → 自动调查 EC2 Auto-Recovery 告警 → 通过 `arn:aws:automate:REGION:ec2:recover` 自动恢复 EC2 ## 清理(反向顺序) ``` # 阶段 7 — Webhook Lambda(如果已部署) aws cloudformation delete-stack --stack-name devops-agent-webhook \ --region us-east-1 --profile account-a aws cloudformation wait stack-delete-complete --stack-name devops-agent-webhook \ --region us-east-1 --profile account-a # 阶段 5 — DevOps Agent aws cloudformation delete-stack --stack-name DevOpsAgentStack \ --region us-east-1 --profile account-a aws cloudformation wait stack-delete-complete --stack-name DevOpsAgentStack \ --region us-east-1 --profile account-a aws cloudformation delete-stack --stack-name DevOpsAgentServiceAccountStack \ --region us-east-1 --profile account-b aws cloudformation wait stack-delete-complete --stack-name DevOpsAgentServiceAccountStack \ --region us-east-1 --profile account-b # 阶段 4 — VPC Peering aws cloudformation delete-stack --stack-name whoami-peering \ --region us-east-1 --profile account-b aws cloudformation wait stack-delete-complete --stack-name whoami-peering \ --region us-east-1 --profile account-b # 阶段 3 — Web 服务器(删除 Elastic IP、Internet Monitor、S3 日志 bucket) aws cloudformation delete-stack --stack-name whoami-web \ --region us-east-1 --profile account-a aws cloudformation wait stack-delete-complete --stack-name whoami-web \ --region us-east-1 --profile account-a # 阶段 2 — RDS(无最终快照 — BackupRetentionPeriod=0、DeletionPolicy=Delete) aws cloudformation delete-stack --stack-name whoami-rds \ --region us-east-1 --profile account-b aws cloudformation wait stack-delete-complete --stack-name whoami-rds \ --region us-east-1 --profile account-b # 阶段 1 — IAM Roles(可选,手动清理) aws iam delete-role-policy --role-name VPCPeeringRole --policy-name AcceptVPCPeering --profile account-b aws iam delete-role --role-name VPCPeeringRole --profile account-b aws iam delete-role-policy --role-name AWSCloudFormationStackSetAdministrationRole --policy-name AssumeExecutionRole --profile account-a aws iam delete-role --role-name AWSCloudFormationStackSetAdministrationRole --profile account-a aws iam detach-role-policy --role-name AWSCloudFormationStackSetExecutionRole --policy-arn arn:aws:iam::aws:policy/AdministratorAccess --profile account-b aws iam delete-role --role-name AWSCloudFormationStackSetExecutionRole --profile account-b ``` ## DevOps Agent 支持的区域 us-east-1, us-west-2, ap-southeast-2, ap-northeast-1, eu-central-1, eu-west-1 ## 故障排除 | 问题 | 原因 | 修复 | |-------|-------|-----| | Web stack 失败:“VPCPeeringRole does not exist” | 在阶段 3 之前未创建 VPCPeeringRole | 在账户 B 中手动创建该角色(阶段 1,步骤 1.3) | | RDS Lambda 种子注入失败:“Unsupported auth type: 10” (SASL/SCRAM) | Parameter Group 未使用 MD5 | 已修复 — 模板包含 `password_encryption=md5` Parameter Group | | RDS Lambda 种子注入失败:“Unsupported auth type: 1397113172” | 在认证前未处理 SSL 协商 | 已修复 — Lambda 在启动消息之前发送 SSLRequest | | RDS Lambda 种注入超时 | Lambda 无法连接到 CloudWatch endpoint | 已修复 — 添加了 NAT Gateway 以供 Lambda 访问互联网 | | Lambda layer AccessDenied | 跨账户 layer 访问被拒绝 | 已修复 — 无外部 layer,纯 Python socket/ssl 实现 | | VPC peering 显示 “pending-acceptance” | 账户 B 中未接受 Peering | 运行阶段 4 步骤 4.1 进行接受 | | DevOps Agent 无法查看账户 B 资源 | 缺少 Resource Explorer index | 验证阶段 5.1 是否成功部署 | | 告警未触发 | SNS 订阅未确认 | 确认 SNS 订阅电子邮件(阶段 6.1) | | httpd 显示 “Error connecting to database” | VPC peering 未完成 | 完成阶段 4(接受 + 返回路由) | | 无法通过 IP 直接访问 EC2 | 安全组或 EIP 问题 | 检查 EC2 SG 是否允许来自 0.0.0.0/0 的 80/443 流量;验证 EIP 关联 | | Internet Monitor 显示无数据 | 刚创建 | 创建后等待 15-30 分钟进行初始数据收集 | | Web stack 重新部署失败:“already exists” | 资源上有显式的 Name/RoleName | 已修复 — ALB/角色不再具有显式的 Name 属性 | | Incident Manager 响应计划失败 | 没有 replication set | 对于新客户,Incident Manager 已弃用(2025年11月)。请改用 EC2 Auto-Recovery 告警。仅对在弃用前已在使用它的账户可用。 | | `whoami` 页面显示错误文本 | 种子数据不匹配 | 预期值为 “AWS Rocks” — 如有需要请重新部署 rds-stack |
标签:AWS, DPI, 云基础设施, 响应自动化, 自动化运维