Skip to Content

32f - DevOps Steering 规则与反模式

本文是《AI Agent 实战手册》第 32 章第 6 节。 上一节:32e-AI辅助监控与事件响应 | 下一节:33a-AI辅助移动端开发概览

概述

AI 编码助手正在深刻改变 DevOps 工程师的日常工作——从 Terraform 模块到 Kubernetes manifests,从 CI/CD 管线到监控配置,AI 可以在几秒内生成看似完美的基础设施代码。然而,2025 年的多项研究表明,AI 生成的基础设施代码中约 40-60% 存在安全或运维隐患:宽松的安全组规则(0.0.0.0/0 入站)、过度配置的资源(浪费 60% 以上的云预算)、缺失的健康检查(导致僵尸 Pod 无法自愈)、硬编码的密钥(直接暴露在 Git 历史中)。Steering 规则是解决这些问题的系统化方案:通过在 CLAUDE.md、Kiro Steering 和 Cursor Rules 中注入 DevOps 安全与运维约束,让 AI 在生成基础设施代码时自动遵循最佳实践。本节覆盖完整的 DevOps Steering 规则模板、十大 DevOps 反模式的识别与修复、CI/CD 管线安全、IaC 安全、容器与 Kubernetes 反模式,以及监控告警反模式。


1. DevOps Steering 规则概述

1.1 为什么 DevOps 需要专用 Steering 规则

AI 在生成 DevOps 配置时面临独特的挑战,与生成应用代码的问题截然不同:

  1. 安全默认值缺失:AI 倾向于生成”能工作”的配置,而非”安全的”配置——安全组默认开放所有端口、数据库默认无加密、密钥直接写在配置文件中
  2. 资源过度配置:AI 缺乏成本意识,倾向于分配过多的 CPU、内存和存储,导致云账单膨胀
  3. 运维可观测性不足:AI 生成的服务通常缺少健康检查、结构化日志、指标暴露等运维必需品
  4. 灾难恢复盲区:AI 很少主动考虑备份策略、故障转移、数据恢复等灾难恢复需求
  5. 环境差异忽视:AI 生成的配置通常不区分开发/测试/生产环境,导致生产环境使用开发级别的安全设置
  6. 合规性缺失:AI 不了解组织的合规要求(SOC 2、HIPAA、PCI DSS),生成的配置可能违反审计标准
  7. 密钥管理不当:AI 经常将 API 密钥、数据库密码等敏感信息直接写入配置文件或环境变量
  8. 网络隔离不足:AI 生成的网络配置通常过于扁平,缺少子网隔离、VPC 对等和网络策略

1.2 工具推荐

工具用途价格适用场景
Claude CodeAgentic 编码,CLAUDE.md DevOps 规则Max $100/月起(按 token 计费)复杂 IaC 生成与审查
KiroSpec-Driven 开发,分层 Steering免费(预览期)需求→基础设施的全链路追溯
CursorAI IDE,.cursorrules DevOps 规则免费 / Pro $20/月日常 DevOps 配置编写
GitHub CopilotIDE 内 YAML/HCL/JSON 补全Individual $10/月;Business $19/月日常配置文件编写
CheckovIaC 静态安全扫描免费(开源);Prisma Cloud 企业版联系销售Terraform/K8s/Docker 安全扫描
tfsec / TrivyTerraform / 容器安全扫描免费(开源)CI/CD 集成的安全门禁
OPA / Rego策略即代码引擎免费(开源)自定义合规策略执行
InfracostIaC 成本估算免费(开源);Cloud $50/月起PR 级别的成本预览
Snyk IaCIaC 安全扫描与修复建议免费层(有限额);Team $25/开发者/月开发者友好的安全扫描
GitGuardian密钥泄露检测免费(公共仓库);Business $34/开发者/月Git 历史中的密钥扫描
HashiCorp Vault密钥管理与动态凭证免费(开源);HCP Vault $0.03/小时起生产级密钥管理
Terraform SentinelHashiCorp 策略即代码Terraform Cloud Team & Governance $20/用户/月起Terraform 专用策略执行

2. 完整 DevOps Steering 规则模板

2.1 CLAUDE.md DevOps 规则模板

以下是一个适用于云原生项目的完整 CLAUDE.md DevOps 规则模板:

# CLAUDE.md — DevOps 规则 ## 基础设施技术栈 - IaC:Terraform 1.x + AWS Provider - 容器:Docker + Kubernetes 1.30+ - CI/CD:GitHub Actions - 监控:Prometheus + Grafana - 日志:Loki / CloudWatch - 密钥管理:AWS Secrets Manager / HashiCorp Vault ## DevOps 安全强制规则(最高优先级) ### 网络安全 - 禁止在安全组/防火墙规则中使用 0.0.0.0/0 作为入站源(除 80/443 的公共 ALB 外) - 禁止在安全组中开放 22(SSH)或 3389(RDP)端口到公网 - 所有数据库必须部署在私有子网,禁止分配公网 IP - 服务间通信必须使用安全组引用(security_group_id),禁止使用 CIDR 范围 - 所有 HTTPS 端点必须使用 TLS 1.2+,禁止 TLS 1.0/1.1 - Kubernetes 必须配置 NetworkPolicy,默认拒绝所有入站流量 ### 密钥管理 - 禁止在任何配置文件、环境变量定义或代码中硬编码密钥、密码、Token - 所有敏感值必须通过 Secrets Manager / Vault / Sealed Secrets 引用 - Terraform 中的敏感变量必须标记 sensitive = true - Docker 构建禁止通过 ARG/ENV 传递密钥,必须使用 BuildKit secrets - CI/CD 中的密钥必须使用平台原生的 secrets 机制(如 GitHub Secrets) - 禁止在日志中输出任何密钥或 Token 值 ### 资源配置 - 所有 Kubernetes 工作负载必须设置 resources.requests 和 resources.limits - 禁止将 CPU limit 设置为超过 4 核(除非有明确的性能需求文档) - 禁止将内存 limit 设置为超过 8Gi(除非有明确的性能需求文档) - EC2/VM 实例类型必须与工作负载匹配,禁止默认使用大型实例 - 数据库实例必须使用合适的实例类型,开发环境使用最小规格 - 所有资源必须添加 cost-center 和 environment 标签 ### 健康检查 - 所有 Kubernetes Pod 必须配置 livenessProbe 和 readinessProbe - 长启动服务必须配置 startupProbe - 健康检查端点必须检查关键依赖(数据库连接、缓存连接) - livenessProbe 不应检查外部依赖(避免级联重启) - readinessProbe 应检查服务是否真正可以处理请求 - Docker Compose 服务必须配置 healthcheck ### 日志与可观测性 - 所有服务必须使用结构化日志(JSON 格式) - 日志必须包含:timestamp、level、service、trace_id、message - 禁止使用 print/console.log 作为生产日志方式 - 所有 HTTP 服务必须暴露 /metrics 端点(Prometheus 格式) - 关键业务操作必须记录审计日志 - 错误日志必须包含堆栈跟踪和上下文信息 ### 备份与灾难恢复 - 所有数据库必须配置自动备份(至少每日一次) - 备份必须存储在不同的区域/可用区 - 必须定义 RTO(恢复时间目标)和 RPO(恢复点目标) - 有状态服务必须配置 PersistentVolumeClaim 的快照策略 - 关键配置必须版本化存储在 Git 中 - 备份恢复流程必须有文档化的运行手册 ### CI/CD 安全 - GitHub Actions 必须固定 action 版本到 SHA(禁止使用 @latest 或 @v1) - GITHUB_TOKEN 权限必须使用最小权限原则(permissions 字段显式声明) - 禁止在 CI 日志中输出密钥或敏感信息 - 所有部署必须通过 CI/CD 管线,禁止手动 kubectl apply 到生产环境 - Docker 镜像必须使用特定版本标签,禁止使用 :latest - 构建产物必须签名验证(Sigstore/cosign)

2.2 Kiro Steering DevOps 规则模板

Kiro 的分层 Steering 机制允许按文件类型精确匹配 DevOps 规则:

Terraform 文件规则

--- inclusion: auto globs: "**/*.tf,**/*.tfvars" --- # Terraform Steering 规则 ## 安全约束 - 安全组 ingress 规则禁止使用 cidr_blocks = ["0.0.0.0/0"](除公共 ALB 的 80/443 外) - 所有 aws_db_instance 必须设置 storage_encrypted = true - 所有 aws_s3_bucket 必须配置 server_side_encryption_configuration - 所有 aws_s3_bucket 必须设置 block_public_access = true - RDS 实例必须设置 deletion_protection = true(生产环境) - 所有敏感变量必须标记 sensitive = true ## 资源管理 - 每个资源必须包含 tags 块,至少包含:Name、Environment、Team、CostCenter - 使用 locals 块定义通用标签,避免重复 - 数据库实例类型必须通过变量控制,按环境区分 - 使用 terraform-aws-modules 官方模块,避免重复造轮子 ## 状态管理 - 远程状态必须使用 S3 + DynamoDB 锁定 - 状态文件必须加密(encrypt = true) - 禁止在本地存储 terraform.tfstate ## 代码组织 - 使用模块化结构:modules/ 目录存放可复用模块 - 每个环境使用独立的 tfvars 文件 - 输出值使用 output 块显式声明

Kubernetes 文件规则

--- inclusion: auto globs: "**/*.yaml,**/*.yml,**/k8s/**,**/kubernetes/**,**/manifests/**" --- # Kubernetes Manifest Steering 规则 ## Pod 安全 - 所有容器必须设置 securityContext.runAsNonRoot = true - 所有容器必须设置 securityContext.readOnlyRootFilesystem = true(除非需要写入) - 禁止设置 securityContext.privileged = true - 禁止使用 hostNetwork、hostPID、hostIPC - 镜像必须使用特定版本标签,禁止 :latest - 镜像必须来自可信仓库(私有 ECR/GCR/ACR 或 Docker Official) ## 资源管理 - 所有容器必须设置 resources.requests 和 resources.limits - requests 和 limits 的比例不应超过 1:2 - 使用 LimitRange 和 ResourceQuota 限制命名空间资源 ## 健康检查 - 所有 Deployment/StatefulSet 的容器必须配置 livenessProbe - 所有 Deployment/StatefulSet 的容器必须配置 readinessProbe - 启动时间超过 30 秒的服务必须配置 startupProbe - Probe 的 initialDelaySeconds 必须合理设置 ## 网络 - 每个命名空间必须有默认的 deny-all NetworkPolicy - Service 类型禁止使用 NodePort(生产环境),使用 ClusterIP + Ingress - Ingress 必须配置 TLS 终止

Dockerfile 规则

--- inclusion: auto globs: "**/Dockerfile,**/Dockerfile.*,**/*.dockerfile" --- # Dockerfile Steering 规则 ## 安全 - 必须使用多阶段构建,最终镜像使用 distroless 或 alpine - 禁止使用 root 用户运行应用(必须有 USER 指令) - 禁止通过 ARG 或 ENV 传递密钥 - 基础镜像必须使用特定版本标签(如 node:20.18-alpine),禁止 :latest - 禁止安装不必要的包(如 vim、curl、wget 等调试工具在生产镜像中) ## 优化 - 合理排列 COPY 指令顺序,利用构建缓存(依赖文件先复制) - 使用 .dockerignore 排除不必要的文件 - 最终镜像大小应控制在合理范围内(Go < 50MB,Node.js < 200MB,Python < 300MB) - 使用 HEALTHCHECK 指令定义健康检查 ## 最佳实践 - 每个 RUN 指令合并相关命令,减少层数 - 使用 COPY 而非 ADD(除非需要解压) - 设置合理的 EXPOSE 端口 - 使用 ENTRYPOINT + CMD 组合

CI/CD 文件规则

--- inclusion: auto globs: "**/.github/workflows/*.yml,**/.github/workflows/*.yaml,**/.gitlab-ci.yml" --- # CI/CD Pipeline Steering 规则 ## 安全 - GitHub Actions 必须固定到 commit SHA:uses: actions/checkout@<sha> - 禁止使用 @latest、@main、@master 引用 action - GITHUB_TOKEN 必须显式声明最小权限: permissions: contents: read pull-requests: write - 密钥必须使用 ${{ secrets.XXX }},禁止硬编码 - 禁止在 run 步骤中 echo 密钥值 - 第三方 action 必须审查源码或使用可信发布者 ## 质量门禁 - PR 合并前必须通过:lint、test、security scan - Docker 镜像构建后必须运行 Trivy/Snyk 扫描 - Terraform plan 必须在 PR 中显示变更预览 - IaC 变更必须通过 Checkov/tfsec 安全扫描 - 部署到生产环境必须有人工审批步骤 ## 最佳实践 - 使用矩阵策略测试多版本/多平台 - 缓存依赖以加速构建(actions/cache) - 使用 concurrency 避免重复运行 - 失败时发送通知(Slack/邮件)

2.3 Cursor Rules DevOps 规则模板

--- description: DevOps 配置文件的代码生成规则 globs: "**/*.tf,**/*.tfvars,**/Dockerfile,**/*.yaml,**/*.yml,**/.github/**" --- # DevOps 代码生成规则 ## 核心原则 1. 安全优先——默认最小权限,显式开放 2. 成本意识——资源配置匹配实际需求 3. 可观测性——每个服务必须可监控、可追踪、可调试 4. 灾难恢复——数据必须有备份,服务必须可恢复 ## 生成 DevOps 配置时的检查清单 - [ ] 安全组/防火墙是否遵循最小权限? - [ ] 是否有硬编码的密钥或密码? - [ ] 资源配置是否合理(不过度也不不足)? - [ ] 是否配置了健康检查? - [ ] 是否有结构化日志和指标暴露? - [ ] 是否配置了备份策略? - [ ] 是否区分了环境(dev/staging/prod)? - [ ] Docker 镜像是否使用了特定版本标签? - [ ] CI/CD action 是否固定到 SHA? - [ ] 是否有网络隔离(私有子网、NetworkPolicy)? ## 禁止事项 - 禁止生成包含 0.0.0.0/0 入站规则的安全组(除公共 LB 的 80/443) - 禁止在配置中硬编码任何密钥、密码、Token - 禁止使用 :latest 镜像标签 - 禁止生成没有 resource limits 的 K8s 工作负载 - 禁止生成没有健康检查的容器服务 - 禁止使用 privileged 容器 - 禁止在 CI 中使用 @latest 引用 action

操作步骤

步骤 1:评估项目 DevOps 技术栈

在创建 Steering 规则之前,先明确项目的 DevOps 技术栈:

请分析当前项目的 DevOps 技术栈,帮我确定需要哪些 Steering 规则: ## 项目信息 - 云平台:[AWS / GCP / Azure / 多云] - IaC 工具:[Terraform / Pulumi / CDK / CloudFormation] - 容器编排:[Kubernetes / ECS / Docker Compose / Nomad] - CI/CD 平台:[GitHub Actions / GitLab CI / CircleCI / Jenkins] - 监控栈:[Prometheus+Grafana / Datadog / New Relic / CloudWatch] - 密钥管理:[Vault / AWS SM / GCP SM / Azure KV / 无] ## 合规要求 - [SOC 2 / HIPAA / PCI DSS / GDPR / 无特殊要求] ## 团队规模 - DevOps 工程师:[人数] - 开发者:[人数] 请推荐需要创建的 Steering 规则文件列表和优先级。

步骤 2:生成定制化规则

根据技术栈生成定制化的 Steering 规则:

请根据以下项目信息,生成完整的 DevOps Steering 规则: ## 技术栈 - 云平台:AWS - IaC:Terraform 1.9 - 容器:EKS (Kubernetes 1.30) - CI/CD:GitHub Actions - 监控:Prometheus + Grafana + Loki - 密钥:AWS Secrets Manager ## AI 编码工具 [Claude Code / Kiro / Cursor] ## 要求 1. 覆盖网络安全、密钥管理、资源配置、健康检查、日志、备份六大领域 2. 每条规则必须包含"禁止"和"应该"两个方面 3. 规则必须可执行(不是模糊的建议,而是具体的约束) 4. 包含至少 3 个 ❌ 错误示例和 ✅ 正确示例 请按 [CLAUDE.md / Kiro Steering / Cursor Rules] 格式输出。

步骤 3:集成安全扫描到 CI/CD

将 Steering 规则与自动化安全扫描结合,形成双重保障:

# .github/workflows/devops-quality-gate.yml name: DevOps Quality Gate on: pull_request: paths: - '**/*.tf' - '**/*.tfvars' - '**/Dockerfile' - '**/k8s/**' - '.github/workflows/**' jobs: iac-security: runs-on: ubuntu-latest permissions: contents: read pull-requests: write steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Checkov IaC Scan uses: bridgecrewio/checkov-action@48a1bff0e498dd66e3bacb0631ec3ce7e4537346 # v12.2964.0 with: directory: terraform/ framework: terraform output_format: sarif soft_fail: false - name: tfsec Scan uses: aquasecurity/tfsec-action@b842aa4d7a21afa3e3ac44b10a5a3a0e3b334998 # v1.0.3 with: working_directory: terraform/ - name: Trivy Container Scan uses: aquasecurity/trivy-action@18f2510ee396bbf400402947e0f18c8ea63fd80e # v0.28.0 with: scan-type: 'config' scan-ref: '.' severity: 'CRITICAL,HIGH' exit-code: '1' - name: Infracost uses: infracost/actions/setup@3e3e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e # v3 with: api-key: ${{ secrets.INFRACOST_API_KEY }} - name: GitGuardian Secret Scan uses: GitGuardian/ggshield-action@8fefef5e6a0f092e1a50a010a1a3a0b0b0b0b0b0 # v1.32.0 env: GITHUB_PUSH_BEFORE_SHA: ${{ github.event.before }} GITHUB_PUSH_BASE_SHA: ${{ github.event.base }} GITHUB_DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} GITGUARDIAN_API_KEY: ${{ secrets.GITGUARDIAN_API_KEY }}

提示词模板

模板 1:DevOps Steering 规则审查

请审查以下 DevOps 配置文件,检查是否违反了安全和运维最佳实践: ## 配置文件 [粘贴 Terraform/K8s/Docker/CI 配置] ## 检查维度 1. 网络安全:是否有过度开放的安全组/防火墙规则? 2. 密钥管理:是否有硬编码的密钥或敏感信息? 3. 资源配置:资源分配是否合理? 4. 健康检查:是否配置了适当的健康检查? 5. 日志与监控:是否有结构化日志和指标暴露? 6. 备份策略:是否配置了数据备份? 7. 容器安全:是否遵循了容器安全最佳实践? 8. CI/CD 安全:是否固定了 action 版本?权限是否最小化? 对每个发现的问题,请提供: - 问题类型和严重程度(🔴 高 / 🟡 中 / 🟢 低) - 具体位置 - 修复建议和修正后的代码

模板 2:生成安全的 DevOps 配置

请为以下服务生成完整的 DevOps 配置,必须遵循安全最佳实践: ## 服务信息 - 服务名称:[服务名] - 技术栈:[语言/框架] - 部署目标:[AWS EKS / GCP GKE / Azure AKS] - 环境:[dev / staging / prod] ## 需要生成的配置 1. Dockerfile(多阶段构建,非 root 用户) 2. Kubernetes manifests(Deployment + Service + Ingress + NetworkPolicy) 3. Terraform 模块(网络 + 计算 + 数据库) 4. GitHub Actions 工作流(构建 + 测试 + 部署) ## 安全要求 - 所有密钥通过 Secrets Manager 管理 - 网络遵循最小权限原则 - 容器以非 root 用户运行 - 所有资源有合理的 limits - 配置健康检查和结构化日志 - 数据库有自动备份 请确保生成的配置可以通过 Checkov 和 tfsec 扫描。

3. DevOps 反模式总览

在深入每个反模式之前,先了解 AI 生成 DevOps 配置的系统性问题:

3.1 AI 生成 DevOps 配置的典型问题分类

问题类别表现根因检测方法
安全漏洞安全组全开、密钥硬编码、无加密AI 优先”能工作”而非”安全”Checkov / tfsec / Trivy
资源浪费过度配置 CPU/内存/存储AI 缺乏成本意识Infracost / 云账单分析
运维盲区无健康检查、无日志、无监控AI 不考虑运维需求K8s 审计 / 手动审查
灾难风险无备份、无恢复计划、单点故障AI 不考虑故障场景DR 演练 / 架构审查
环境混淆开发配置用于生产AI 不区分环境环境标签检查
合规违规不满足 SOC 2/HIPAA 要求AI 不了解合规标准合规扫描工具

3.2 DevOps 反模式严重程度矩阵

发生频率 低 高 ┌──────────┬──────────┐ 高 │ 🔴 密钥暴露 │ 🔴 宽松安全组│ 影响程度 │ (立即修复) │ (立即修复) │ ├──────────┼──────────┤ 低 │ 🟢 缺少备份 │ 🟡 过度配置 │ │ (计划修复) │ (优化改进) │ └──────────┴──────────┘

💡 核心原则:DevOps 反模式的修复优先级应基于”影响程度 × 发生频率”。安全类问题(密钥暴露、宽松安全组)必须立即修复,资源优化类问题可以计划性改进。


4. 反模式 1:宽松安全组(Overly Permissive Security Groups)

问题描述

AI 生成的安全组/防火墙规则几乎总是过度开放。最常见的问题是使用 0.0.0.0/0(允许所有 IP)作为入站源,以及开放不必要的端口。AI 这样做是因为它优先确保”配置能工作”,而最简单的方式就是允许所有流量。

2025 年 Cloud Security Alliance 的研究表明,AI 生成的 IaC 代码中约 62% 包含安全设计缺陷,其中网络配置过度开放是最常见的问题之一。

危害等级:🔴 严重

  • 数据库端口暴露到公网,可被扫描和攻击
  • SSH/RDP 端口开放,可被暴力破解
  • 内部服务暴露,扩大攻击面
  • 违反 SOC 2、PCI DSS 等合规要求
  • 一旦被利用,可能导致数据泄露和系统被控制

❌ 错误示例

Terraform — 过度开放的安全组

# ❌ 反模式:所有端口对所有 IP 开放 resource "aws_security_group" "app" { name = "app-sg" description = "Application security group" vpc_id = var.vpc_id # ❌ SSH 对全网开放——任何人都可以尝试暴力破解 ingress { from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] description = "SSH access" } # ❌ 应用端口对全网开放——应该只允许负载均衡器访问 ingress { from_port = 8080 to_port = 8080 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] description = "Application port" } # ❌ 出站全开——应该限制到必要的目标 egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } } # ❌ 数据库安全组也对全网开放 resource "aws_security_group" "db" { name = "db-sg" vpc_id = var.vpc_id # ❌ 数据库端口对全网开放——这是最危险的配置之一 ingress { from_port = 5432 to_port = 5432 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] description = "PostgreSQL" } }

Kubernetes — 缺少 NetworkPolicy

# ❌ 反模式:没有 NetworkPolicy,所有 Pod 可以互相通信 apiVersion: apps/v1 kind: Deployment metadata: name: payment-service spec: replicas: 3 selector: matchLabels: app: payment-service template: metadata: labels: app: payment-service spec: containers: - name: payment image: myapp/payment:v1.2.3 ports: - containerPort: 8080 # ❌ 没有 NetworkPolicy——任何 Pod 都可以访问支付服务 # ❌ 没有限制出站流量——被入侵后可以自由外联

✅ 正确示例

Terraform — 最小权限安全组

# ✅ 正确:最小权限原则 resource "aws_security_group" "alb" { name = "${var.project}-alb-sg" description = "ALB security group - public facing" vpc_id = var.vpc_id # ✅ 只有 ALB 允许公网访问,且仅限 HTTP/HTTPS ingress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] description = "HTTPS from internet" } ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] description = "HTTP from internet (redirect to HTTPS)" } egress { from_port = 8080 to_port = 8080 protocol = "tcp" security_groups = [aws_security_group.app.id] description = "To application instances" } tags = local.common_tags } resource "aws_security_group" "app" { name = "${var.project}-app-sg" description = "Application security group - private" vpc_id = var.vpc_id # ✅ 应用只接受来自 ALB 的流量(通过安全组引用) ingress { from_port = 8080 to_port = 8080 protocol = "tcp" security_groups = [aws_security_group.alb.id] description = "From ALB only" } # ✅ 出站限制到必要的目标 egress { from_port = 5432 to_port = 5432 protocol = "tcp" security_groups = [aws_security_group.db.id] description = "To PostgreSQL" } egress { from_port = 6379 to_port = 6379 protocol = "tcp" security_groups = [aws_security_group.redis.id] description = "To Redis" } egress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] description = "HTTPS to external APIs" } tags = local.common_tags } resource "aws_security_group" "db" { name = "${var.project}-db-sg" description = "Database security group - private only" vpc_id = var.vpc_id # ✅ 数据库只接受来自应用的流量 ingress { from_port = 5432 to_port = 5432 protocol = "tcp" security_groups = [aws_security_group.app.id] description = "From application only" } # ✅ 数据库不需要出站访问 # 不定义 egress 规则 tags = local.common_tags }

Kubernetes — 严格的 NetworkPolicy

# ✅ 正确:默认拒绝 + 显式允许 --- # 默认拒绝所有入站流量 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-ingress namespace: production spec: podSelector: {} policyTypes: - Ingress --- # 只允许 Ingress Controller 访问 payment-service apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-ingress-to-payment namespace: production spec: podSelector: matchLabels: app: payment-service policyTypes: - Ingress - Egress ingress: - from: - namespaceSelector: matchLabels: name: ingress-nginx podSelector: matchLabels: app.kubernetes.io/name: ingress-nginx ports: - protocol: TCP port: 8080 egress: # 允许访问数据库 - to: - podSelector: matchLabels: app: postgresql ports: - protocol: TCP port: 5432 # 允许 DNS 解析 - to: - namespaceSelector: {} podSelector: matchLabels: k8s-app: kube-dns ports: - protocol: UDP port: 53

检测方法

# Checkov 扫描 Terraform 安全组 checkov -d terraform/ --check CKV_AWS_24,CKV_AWS_25,CKV_AWS_260 # tfsec 扫描 tfsec terraform/ --include-passed # OPA/Rego 自定义策略 # policy/security_group.rego package terraform.security_group deny[msg] { resource := input.resource.aws_security_group[name] ingress := resource.ingress[_] ingress.cidr_blocks[_] == "0.0.0.0/0" ingress.from_port != 80 ingress.from_port != 443 msg := sprintf("Security group '%s' allows 0.0.0.0/0 on port %d", [name, ingress.from_port]) }

Steering 规则

## 网络安全规则 - 禁止 cidr_blocks = ["0.0.0.0/0"] 用于非 80/443 端口的入站规则 - 服务间通信必须使用 security_groups 引用,禁止 CIDR - 数据库安全组禁止任何公网入站规则 - SSH 访问必须通过 VPN 或 SSM Session Manager,禁止直接公网 SSH - 每个安全组规则必须有 description 字段 - Kubernetes 每个命名空间必须有 default-deny NetworkPolicy

5. 反模式 2:过度配置(Over-Provisioning)

问题描述

AI 生成的资源配置几乎总是过度分配。当你让 AI 生成 Kubernetes Deployment 时,它可能默认分配 2 核 CPU 和 4Gi 内存给一个简单的 API 服务;当你让它生成 Terraform EC2 实例时,它可能选择 m5.xlarge 而实际只需要 t3.small。AI 这样做是因为它倾向于”安全”地分配更多资源以避免性能问题,但这直接导致云账单膨胀。

Flexera 2025 年云状态报告显示,企业平均浪费约 28-35% 的云支出,而 AI 生成的配置可能进一步加剧这一问题。

危害等级:🟡 中高

  • 云账单膨胀 2-5 倍
  • 资源利用率低于 20%,浪费严重
  • 开发环境使用生产级别的资源规格
  • 自动扩缩容配置不合理,最小副本数过高
  • 存储过度分配且无法缩减(EBS 卷只能扩不能缩)

❌ 错误示例

Kubernetes — 过度配置的资源

# ❌ 反模式:一个简单的 API 服务分配了过多资源 apiVersion: apps/v1 kind: Deployment metadata: name: user-api spec: # ❌ 最小 5 个副本——对于低流量服务完全不必要 replicas: 5 selector: matchLabels: app: user-api template: metadata: labels: app: user-api spec: containers: - name: user-api image: myapp/user-api:v1.0.0 resources: requests: # ❌ 请求 2 核 CPU——一个简单 CRUD API 通常只需 100-250m cpu: "2" # ❌ 请求 4Gi 内存——Node.js/Go API 通常只需 128-512Mi memory: "4Gi" limits: # ❌ 限制 4 核——过度分配 cpu: "4" # ❌ 限制 8Gi——过度分配 memory: "8Gi"

Terraform — 过度配置的实例

# ❌ 反模式:开发环境使用生产级别的实例 resource "aws_instance" "dev_app" { # ❌ m5.2xlarge(8 vCPU, 32GB RAM)用于开发环境 instance_type = "m5.2xlarge" ami = var.ami_id subnet_id = var.subnet_id root_block_device { # ❌ 500GB gp3 用于开发——通常 20-50GB 足够 volume_size = 500 volume_type = "gp3" # ❌ 高 IOPS 用于开发环境 iops = 10000 throughput = 500 } tags = { Name = "dev-app-server" } } # ❌ 开发环境的 RDS 使用生产级别配置 resource "aws_db_instance" "dev_db" { # ❌ db.r6g.xlarge(4 vCPU, 32GB RAM)用于开发 instance_class = "db.r6g.xlarge" allocated_storage = 500 # ❌ 500GB 用于开发 max_allocated_storage = 1000 multi_az = true # ❌ 开发环境不需要多可用区 # ❌ 没有按环境区分配置 }

✅ 正确示例

Kubernetes — 合理的资源配置

# ✅ 正确:根据实际负载合理配置资源 apiVersion: apps/v1 kind: Deployment metadata: name: user-api spec: # ✅ 开发环境 1 个副本,生产环境通过 HPA 自动扩缩 replicas: 2 selector: matchLabels: app: user-api template: metadata: labels: app: user-api spec: containers: - name: user-api image: myapp/user-api:v1.0.0 resources: requests: # ✅ 合理的请求值——基于实际观测的 P95 使用量 cpu: "100m" memory: "256Mi" limits: # ✅ limits 是 requests 的 2 倍——允许突发但有上限 cpu: "200m" memory: "512Mi" --- # ✅ 使用 HPA 自动扩缩容 apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: user-api-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: user-api minReplicas: 2 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 70 - type: Resource resource: name: memory target: type: Utilization averageUtilization: 80

Terraform — 按环境区分的资源配置

# ✅ 正确:按环境区分资源配置 locals { instance_config = { dev = { instance_type = "t3.small" # 2 vCPU, 2GB — 开发足够 volume_size = 30 volume_iops = 3000 # gp3 默认值 db_class = "db.t4g.micro" # 最小规格 db_storage = 20 db_multi_az = false } staging = { instance_type = "t3.medium" # 2 vCPU, 4GB volume_size = 50 volume_iops = 3000 db_class = "db.t4g.small" db_storage = 50 db_multi_az = false } prod = { instance_type = "m6i.large" # 2 vCPU, 8GB — 生产合理起步 volume_size = 100 volume_iops = 6000 db_class = "db.r6g.large" db_storage = 100 db_multi_az = true } } config = local.instance_config[var.environment] } resource "aws_instance" "app" { instance_type = local.config.instance_type ami = var.ami_id subnet_id = var.subnet_id root_block_device { volume_size = local.config.volume_size volume_type = "gp3" iops = local.config.volume_iops } tags = merge(local.common_tags, { Name = "${var.project}-${var.environment}-app" }) } resource "aws_db_instance" "main" { instance_class = local.config.db_class allocated_storage = local.config.db_storage max_allocated_storage = local.config.db_storage * 2 multi_az = local.config.db_multi_az storage_encrypted = true tags = local.common_tags }

检测方法

# Infracost 估算成本 infracost breakdown --path terraform/ # Infracost 对比 PR 变更的成本影响 infracost diff --path terraform/ --compare-to infracost-base.json # Kubernetes 资源使用率分析 kubectl top pods -n production --sort-by=cpu kubectl top pods -n production --sort-by=memory # 使用 Kubecost 分析集群成本 # https://www.kubecost.com/

Steering 规则

## 资源配置规则 - Kubernetes requests/limits 必须基于实际观测数据,而非猜测 - 简单 API 服务的默认 requests:cpu 100m, memory 256Mi - limits 不应超过 requests 的 2-3 倍 - 开发环境必须使用最小规格实例(t3.small / db.t4g.micro) - 所有资源必须按环境(dev/staging/prod)参数化配置 - 使用 HPA 自动扩缩容,而非固定高副本数 - 所有资源必须添加 cost-center 和 environment 标签 - PR 中必须包含 Infracost 成本预估

6. 反模式 3:缺少健康检查(Missing Health Checks)

问题描述

AI 生成的容器和服务配置经常缺少健康检查(Health Checks)。没有健康检查的服务就像没有体检的员工——看起来在工作,但可能已经处于不健康状态:进程在运行但无法处理请求(僵尸进程)、数据库连接池耗尽但 Pod 仍然接收流量、内存泄漏导致响应越来越慢但 Kubernetes 不知道需要重启。

2026 年 OneUptime 的研究指出,混淆 liveness 和 readiness 探针是最常见的 Kubernetes 健康检查错误——liveness 失败会杀死容器,readiness 失败只是停止发送流量,混用会导致级联重启。

危害等级:🔴 高

  • 僵尸 Pod 持续接收流量,导致用户请求失败
  • 服务无法自愈,需要人工干预重启
  • 滚动更新时新版本未就绪就接收流量,导致短暂不可用
  • 依赖服务故障时,上游服务不知道下游已不可用
  • Docker Compose 环境中服务启动顺序混乱

❌ 错误示例

Kubernetes — 无健康检查

# ❌ 反模式:完全没有健康检查 apiVersion: apps/v1 kind: Deployment metadata: name: order-service spec: replicas: 3 selector: matchLabels: app: order-service template: metadata: labels: app: order-service spec: containers: - name: order-service image: myapp/order-service:v2.1.0 ports: - containerPort: 8080 # ❌ 没有 livenessProbe——进程死锁时不会被重启 # ❌ 没有 readinessProbe——启动中就接收流量 # ❌ 没有 startupProbe——慢启动服务可能被 liveness 杀死

Kubernetes — 错误的健康检查配置

# ❌ 反模式:健康检查配置错误 apiVersion: apps/v1 kind: Deployment metadata: name: payment-service spec: replicas: 3 selector: matchLabels: app: payment-service template: metadata: labels: app: payment-service spec: containers: - name: payment-service image: myapp/payment:v1.5.0 ports: - containerPort: 8080 # ❌ liveness 检查外部依赖——数据库故障会导致所有 Pod 被杀死(级联重启) livenessProbe: httpGet: path: /health/full # 这个端点检查数据库、Redis、Kafka port: 8080 initialDelaySeconds: 5 periodSeconds: 5 # ❌ failureThreshold 太低——一次网络抖动就重启 failureThreshold: 1 # ❌ readiness 和 liveness 使用相同的端点和配置 readinessProbe: httpGet: path: /health/full port: 8080 initialDelaySeconds: 5 periodSeconds: 5 failureThreshold: 1

Docker Compose — 无健康检查

# ❌ 反模式:Docker Compose 无健康检查 version: '3.8' services: app: image: myapp:latest ports: - "8080:8080" depends_on: # ❌ 只等待容器启动,不等待服务就绪 - postgres - redis postgres: image: postgres:16 # ❌ 没有 healthcheck——app 可能在 postgres 未就绪时就尝试连接 redis: image: redis:7 # ❌ 没有 healthcheck

✅ 正确示例

Kubernetes — 正确的健康检查配置

# ✅ 正确:分层健康检查 apiVersion: apps/v1 kind: Deployment metadata: name: payment-service spec: replicas: 3 selector: matchLabels: app: payment-service template: metadata: labels: app: payment-service spec: containers: - name: payment-service image: myapp/payment:v1.5.0 ports: - containerPort: 8080 # ✅ startupProbe:处理慢启动(如 JVM 预热、数据库迁移) startupProbe: httpGet: path: /health/startup port: 8080 # 最多等待 5 * 60 = 300 秒启动 periodSeconds: 5 failureThreshold: 60 # ✅ livenessProbe:只检查进程本身是否健康(不检查外部依赖) livenessProbe: httpGet: path: /health/live # 只检查进程存活,不检查 DB/Redis port: 8080 periodSeconds: 10 failureThreshold: 3 # 连续 3 次失败才重启 timeoutSeconds: 5 # ✅ readinessProbe:检查服务是否可以处理请求(包括关键依赖) readinessProbe: httpGet: path: /health/ready # 检查 DB 连接池、Redis 连接等 port: 8080 periodSeconds: 5 failureThreshold: 3 successThreshold: 1 timeoutSeconds: 3

健康检查端点实现示例(Go)

// ✅ 正确:分层健康检查端点 package health import ( "context" "net/http" "time" "encoding/json" ) type HealthChecker struct { db *sql.DB redis *redis.Client } // /health/live — liveness:只检查进程存活 func (h *HealthChecker) LiveHandler(w http.ResponseWriter, r *http.Request) { // ✅ 不检查外部依赖,只确认进程能响应 w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(map[string]string{"status": "alive"}) } // /health/ready — readiness:检查是否可以处理请求 func (h *HealthChecker) ReadyHandler(w http.ResponseWriter, r *http.Request) { ctx, cancel := context.WithTimeout(r.Context(), 2*time.Second) defer cancel() checks := map[string]string{} healthy := true // ✅ 检查数据库连接 if err := h.db.PingContext(ctx); err != nil { checks["database"] = "unhealthy: " + err.Error() healthy = false } else { checks["database"] = "healthy" } // ✅ 检查 Redis 连接 if err := h.redis.Ping(ctx).Err(); err != nil { checks["redis"] = "unhealthy: " + err.Error() healthy = false } else { checks["redis"] = "healthy" } if healthy { w.WriteHeader(http.StatusOK) } else { w.WriteHeader(http.StatusServiceUnavailable) } json.NewEncoder(w).Encode(checks) } // /health/startup — startup:检查初始化是否完成 func (h *HealthChecker) StartupHandler(w http.ResponseWriter, r *http.Request) { // ✅ 检查数据库迁移是否完成、缓存是否预热等 if !h.initialized { w.WriteHeader(http.StatusServiceUnavailable) return } w.WriteHeader(http.StatusOK) }

Docker Compose — 正确的健康检查

# ✅ 正确:Docker Compose 带健康检查 version: '3.8' services: app: image: myapp:v1.0.0 ports: - "8080:8080" depends_on: postgres: # ✅ 等待 postgres 健康检查通过后再启动 condition: service_healthy redis: condition: service_healthy healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/health/ready"] interval: 10s timeout: 5s retries: 3 start_period: 30s postgres: image: postgres:16-alpine healthcheck: # ✅ 使用 pg_isready 检查 PostgreSQL 是否就绪 test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] interval: 5s timeout: 3s retries: 5 start_period: 10s redis: image: redis:7-alpine healthcheck: # ✅ 使用 redis-cli ping 检查 Redis 是否就绪 test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 3s retries: 5

检测方法

# 检查 Kubernetes 中没有健康检查的 Deployment kubectl get deployments -A -o json | jq -r ' .items[] | select(.spec.template.spec.containers[].livenessProbe == null) | "\(.metadata.namespace)/\(.metadata.name): 缺少 livenessProbe" ' # Checkov 检查 checkov -d k8s/ --check CKV_K8S_8,CKV_K8S_9 # livenessProbe, readinessProbe # OPA 策略 # policy/health_check.rego package kubernetes.health_check deny[msg] { container := input.spec.template.spec.containers[_] not container.livenessProbe msg := sprintf("Container '%s' missing livenessProbe", [container.name]) } deny[msg] { container := input.spec.template.spec.containers[_] not container.readinessProbe msg := sprintf("Container '%s' missing readinessProbe", [container.name]) }

Steering 规则

## 健康检查规则 - 所有 K8s Deployment/StatefulSet 必须配置 livenessProbe 和 readinessProbe - livenessProbe 只检查进程存活,禁止检查外部依赖(避免级联重启) - readinessProbe 检查服务是否可以处理请求(包括关键依赖连接) - 启动时间超过 30 秒的服务必须配置 startupProbe - failureThreshold 至少设置为 3(避免网络抖动导致误重启) - Docker Compose 的 depends_on 必须使用 condition: service_healthy - 所有数据库和缓存服务必须配置 healthcheck

7. 反模式 4:日志不足(Insufficient Logging)

问题描述

AI 生成的服务代码通常使用最基本的日志方式——console.logprintfmt.Println——输出非结构化的纯文本日志。这些日志在开发环境中看起来没问题,但在生产环境中几乎无法使用:无法被日志聚合系统(Loki、ELK、CloudWatch)有效解析、缺少关键上下文(请求 ID、用户 ID、trace ID)、没有日志级别区分、敏感信息可能被意外记录。

危害等级:🟡 中高

  • 生产事件排查困难——无法通过日志定位问题
  • 日志聚合系统无法解析非结构化日志
  • 缺少 trace ID 导致无法跨服务追踪请求
  • 缺少审计日志导致合规审计失败
  • 敏感信息(密码、Token)被记录到日志中
  • 日志量过大或过小,无法有效监控

❌ 错误示例

Node.js — 非结构化日志

// ❌ 反模式:使用 console.log 输出非结构化日志 app.post('/api/orders', async (req, res) => { try { // ❌ 非结构化日志——无法被日志系统解析 console.log('Creating order for user: ' + req.body.userId); const order = await orderService.create(req.body); // ❌ 日志中包含敏感信息 console.log('Order created:', JSON.stringify(order)); // ❌ 可能包含信用卡号、地址等敏感数据 res.json(order); } catch (error) { // ❌ 只记录错误消息,没有堆栈跟踪和上下文 console.log('Error creating order: ' + error.message); // ❌ 没有请求 ID、用户 ID 等上下文 // ❌ 没有日志级别区分 res.status(500).json({ error: 'Internal error' }); } });

Go — 缺少上下文的日志

// ❌ 反模式:使用 fmt.Println 和 log.Println func (h *OrderHandler) CreateOrder(w http.ResponseWriter, r *http.Request) { // ❌ 非结构化日志 fmt.Println("Received create order request") var req CreateOrderRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { // ❌ 没有请求上下文(request ID、user ID) log.Println("Failed to decode request:", err) http.Error(w, "Bad request", http.StatusBadRequest) return } order, err := h.service.Create(r.Context(), req) if err != nil { // ❌ 没有结构化字段,无法在日志系统中过滤 log.Printf("Failed to create order: %v", err) http.Error(w, "Internal error", http.StatusInternalServerError) return } // ❌ 日志中可能包含敏感的订单数据 log.Printf("Order created: %+v", order) }

✅ 正确示例

Node.js — 结构化日志(使用 Pino)

// ✅ 正确:结构化日志 + 上下文 + 脱敏 import pino from 'pino'; const logger = pino({ level: process.env.LOG_LEVEL || 'info', // ✅ 结构化 JSON 输出 formatters: { level: (label) => ({ level: label }), }, // ✅ 自动脱敏敏感字段 redact: { paths: ['req.headers.authorization', 'req.body.password', 'req.body.creditCard', '*.token', '*.secret'], censor: '[REDACTED]', }, // ✅ 添加服务元数据 base: { service: 'order-service', version: process.env.APP_VERSION || 'unknown', environment: process.env.NODE_ENV || 'development', }, }); // ✅ 请求级别的日志中间件 app.use((req, res, next) => { // ✅ 为每个请求生成唯一 ID req.requestId = req.headers['x-request-id'] || crypto.randomUUID(); // ✅ 创建带上下文的子 logger req.log = logger.child({ requestId: req.requestId, method: req.method, path: req.path, userId: req.user?.id, }); next(); }); app.post('/api/orders', async (req, res) => { try { // ✅ 结构化日志 + 上下文 req.log.info({ itemCount: req.body.items?.length }, 'Creating order'); const order = await orderService.create(req.body); // ✅ 只记录必要的非敏感信息 req.log.info( { orderId: order.id, total: order.total, itemCount: order.items.length }, 'Order created successfully' ); res.json(order); } catch (error) { // ✅ 错误日志包含完整上下文和堆栈跟踪 req.log.error( { err: error, stack: error.stack, orderData: { itemCount: req.body.items?.length }, }, 'Failed to create order' ); res.status(500).json({ error: 'Internal error', requestId: req.requestId }); } });

Go — 结构化日志(使用 slog)

// ✅ 正确:使用 Go 1.21+ 标准库 slog package main import ( "context" "log/slog" "net/http" "os" ) func setupLogger() *slog.Logger { // ✅ JSON 格式输出,适合日志聚合系统 handler := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{ Level: slog.LevelInfo, // ✅ 自动脱敏敏感字段 ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr { if a.Key == "password" || a.Key == "token" || a.Key == "secret" { a.Value = slog.StringValue("[REDACTED]") } return a }, }) return slog.New(handler).With( slog.String("service", "order-service"), slog.String("version", os.Getenv("APP_VERSION")), slog.String("environment", os.Getenv("ENVIRONMENT")), ) } // ✅ 中间件:为每个请求注入上下文 func loggingMiddleware(logger *slog.Logger) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { requestID := r.Header.Get("X-Request-ID") if requestID == "" { requestID = uuid.New().String() } // ✅ 创建带请求上下文的 logger reqLogger := logger.With( slog.String("request_id", requestID), slog.String("method", r.Method), slog.String("path", r.URL.Path), slog.String("remote_addr", r.RemoteAddr), ) ctx := context.WithValue(r.Context(), "logger", reqLogger) next.ServeHTTP(w, r.WithContext(ctx)) }) } } func (h *OrderHandler) CreateOrder(w http.ResponseWriter, r *http.Request) { logger := r.Context().Value("logger").(*slog.Logger) // ✅ 结构化日志 + 上下文 logger.Info("Creating order", slog.Int("item_count", len(req.Items)), slog.String("user_id", req.UserID), ) order, err := h.service.Create(r.Context(), req) if err != nil { // ✅ 错误日志包含完整上下文 logger.Error("Failed to create order", slog.String("error", err.Error()), slog.String("user_id", req.UserID), slog.Int("item_count", len(req.Items)), ) http.Error(w, "Internal error", http.StatusInternalServerError) return } logger.Info("Order created", slog.String("order_id", order.ID), slog.Float64("total", order.Total), ) }

检测方法

# 搜索代码中的非结构化日志 grep -rn "console\.log\|console\.error\|fmt\.Print\|log\.Print" src/ --include="*.ts" --include="*.go" # 检查日志输出是否为 JSON 格式 kubectl logs deployment/order-service -n production --tail=10 | jq . 2>/dev/null || echo "⚠️ 日志不是 JSON 格式" # 检查日志是否包含必要字段 kubectl logs deployment/order-service -n production --tail=100 | \ jq -r 'select(.request_id == null) | .msg' | head -5 # 如果有输出,说明有日志缺少 request_id

Steering 规则

## 日志规则 - 生产代码禁止使用 console.log / fmt.Println / print 作为日志方式 - 必须使用结构化日志库(Pino/Winston/slog/zerolog/structlog) - 日志必须为 JSON 格式,包含:timestamp、level、service、message - 每个请求的日志必须包含 request_id(用于跨服务追踪) - 错误日志必须包含堆栈跟踪和上下文信息 - 禁止在日志中记录密码、Token、信用卡号等敏感信息 - 必须配置日志脱敏(redact)规则 - 关键业务操作(创建、更新、删除)必须记录审计日志 - 日志级别使用规范:DEBUG(调试)、INFO(正常操作)、WARN(异常但可恢复)、ERROR(错误需关注)

8. 反模式 5:密钥暴露(Secret Exposure)

问题描述

密钥暴露是 AI 生成代码中最危险的安全问题之一。AI 在生成配置示例时,经常直接在代码中写入示例密钥、API Key、数据库密码等敏感信息。更糟糕的是,开发者可能直接使用这些”示例”值,或者用真实密钥替换后忘记从 Git 历史中清除。

2025 年 GitGuardian 的报告显示,公共 GitHub 仓库中每年新增数百万个泄露的密钥,而 AI 辅助编码正在加速这一趋势。Pixee.ai 的研究发现,AI 辅助的 PR 中密码处理不当的问题比非 AI PR 高出 1.88 倍。

危害等级:🔴 严重

  • 数据库被未授权访问,数据泄露
  • 云账户被接管,产生巨额账单
  • API 密钥被滥用,服务被攻击
  • 即使删除文件,密钥仍存在于 Git 历史中
  • 违反 SOC 2、PCI DSS、HIPAA 等合规要求
  • 一旦泄露,修复成本极高(需要轮换所有相关密钥)

❌ 错误示例

Terraform — 硬编码密钥

# ❌ 反模式:密钥直接写在 Terraform 配置中 resource "aws_db_instance" "main" { engine = "postgres" engine_version = "16.3" instance_class = "db.t4g.medium" # ❌ 数据库密码硬编码——会被提交到 Git username = "admin" password = "SuperSecret123!" # ❌ 严重安全问题 tags = { Name = "production-db" } } # ❌ API 密钥硬编码 resource "aws_ssm_parameter" "api_key" { name = "/app/api-key" type = "String" # ❌ 应该用 SecureString value = "sk-proj-abc123def456ghi789" # ❌ 真实 API 密钥 } # ❌ Provider 配置中硬编码凭证 provider "aws" { region = "us-east-1" access_key = "AKIAIOSFODNN7EXAMPLE" # ❌ 严重安全问题 secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" # ❌ 严重安全问题 }

Docker / Docker Compose — 密钥泄露

# ❌ 反模式:Dockerfile 中的密钥 FROM node:20-alpine WORKDIR /app COPY . . # ❌ 通过 ARG 传递密钥——会被记录在镜像层中 ARG DATABASE_URL=postgres://admin:password123@db:5432/myapp ARG API_KEY=sk-proj-abc123 # ❌ 通过 ENV 设置密钥——会被记录在镜像元数据中 ENV DATABASE_URL=$DATABASE_URL ENV API_KEY=$API_KEY RUN npm install CMD ["node", "server.js"]
# ❌ 反模式:docker-compose.yml 中硬编码密钥 version: '3.8' services: app: image: myapp:latest environment: # ❌ 密钥直接写在 compose 文件中 DATABASE_URL: "postgres://admin:SuperSecret123!@postgres:5432/myapp" JWT_SECRET: "my-super-secret-jwt-key-12345" STRIPE_SECRET_KEY: "sk_live_abc123def456" AWS_ACCESS_KEY_ID: "AKIAIOSFODNN7EXAMPLE" AWS_SECRET_ACCESS_KEY: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"

GitHub Actions — 密钥泄露

# ❌ 反模式:CI/CD 中的密钥问题 name: Deploy on: push jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 # ❌ 密钥硬编码在工作流文件中 - name: Configure AWS run: | aws configure set aws_access_key_id AKIAIOSFODNN7EXAMPLE aws configure set aws_secret_access_key wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY # ❌ 在日志中输出密钥 - name: Debug run: | echo "Using API key: ${{ secrets.API_KEY }}" # ❌ 虽然用了 secrets,但 echo 会在日志中显示

✅ 正确示例

Terraform — 安全的密钥管理

# ✅ 正确:使用 Secrets Manager + 动态引用 # 密码由 Secrets Manager 自动生成和管理 resource "random_password" "db_password" { length = 32 special = true } resource "aws_secretsmanager_secret" "db_password" { name = "${var.project}/${var.environment}/db-password" recovery_window_in_days = 7 tags = local.common_tags } resource "aws_secretsmanager_secret_version" "db_password" { secret_id = aws_secretsmanager_secret.db_password.id secret_string = random_password.db_password.result } resource "aws_db_instance" "main" { engine = "postgres" engine_version = "16.3" instance_class = local.config.db_class # ✅ 用户名通过变量传入 username = var.db_username # ✅ 密码从 Secrets Manager 引用 password = random_password.db_password.result # ✅ 标记为敏感值,不在 plan 输出中显示 lifecycle { ignore_changes = [password] } tags = local.common_tags } # ✅ 敏感变量标记 variable "db_username" { type = string sensitive = true } # ✅ 输出也标记为敏感 output "db_endpoint" { value = aws_db_instance.main.endpoint sensitive = false } output "db_password_secret_arn" { value = aws_secretsmanager_secret.db_password.arn sensitive = true }

Docker — 安全的密钥处理

# ✅ 正确:多阶段构建 + BuildKit secrets FROM node:20-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci --production COPY . . RUN npm run build # ✅ 最终镜像不包含任何密钥 FROM node:20-alpine AS runtime RUN addgroup -g 1001 -S appgroup && \ adduser -S appuser -u 1001 -G appgroup WORKDIR /app COPY --from=builder /app/dist ./dist COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/package.json ./ # ✅ 不在镜像中设置任何密钥环境变量 # 密钥在运行时通过 Secrets Manager / Vault 注入 USER appuser EXPOSE 8080 HEALTHCHECK --interval=30s --timeout=3s --retries=3 \ CMD wget -qO- http://localhost:8080/health/live || exit 1 CMD ["node", "dist/server.js"]
# ✅ 正确:docker-compose 使用 secrets 和 .env version: '3.8' services: app: image: myapp:v1.0.0 environment: # ✅ 非敏感配置可以直接设置 NODE_ENV: production PORT: "8080" # ✅ 敏感值通过 secrets 挂载 secrets: - db_password - jwt_secret - stripe_key # ✅ secrets 从外部文件或 Docker Swarm secrets 加载 secrets: db_password: file: ./secrets/db_password.txt # ✅ 此文件在 .gitignore 中 jwt_secret: file: ./secrets/jwt_secret.txt stripe_key: file: ./secrets/stripe_key.txt

GitHub Actions — 安全的密钥使用

# ✅ 正确:安全的 CI/CD 密钥管理 name: Deploy on: push: branches: [main] # ✅ 最小权限原则 permissions: contents: read id-token: write # 用于 OIDC 认证 jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 # ✅ 使用 OIDC 联合认证,无需长期凭证 - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 with: role-to-assume: ${{ secrets.AWS_ROLE_ARN }} aws-region: us-east-1 # ✅ 使用 OIDC,不需要 access key # ✅ 密钥通过 GitHub Secrets 注入,不在日志中显示 - name: Deploy env: DATABASE_URL: ${{ secrets.DATABASE_URL }} run: | # ✅ 不 echo 密钥值 echo "Deploying to production..." ./deploy.sh # ✅ 使用 GitGuardian 扫描密钥泄露 - name: Secret Scan uses: GitGuardian/ggshield-action@8fefef5e6a0f092e1a50a010a1a3a0b0b0b0b0b0 # v1.32.0 env: GITGUARDIAN_API_KEY: ${{ secrets.GITGUARDIAN_API_KEY }}

检测方法

# GitGuardian 扫描 Git 历史 ggshield secret scan repo . # Trivy 扫描密钥 trivy fs --scanners secret . # gitleaks 扫描 gitleaks detect --source . --verbose # 检查 Terraform 中的硬编码密钥 grep -rn "password\s*=\s*\"" terraform/ --include="*.tf" | grep -v "var\." | grep -v "random_password" grep -rn "secret_key\s*=\s*\"" terraform/ --include="*.tf" grep -rn "access_key\s*=\s*\"" terraform/ --include="*.tf" # 检查 Docker 镜像中的密钥 docker history myapp:latest --no-trunc | grep -i "secret\|password\|key\|token"

Steering 规则

## 密钥管理规则 - 禁止在任何文件中硬编码密钥、密码、Token、API Key - Terraform 密码必须使用 random_password + Secrets Manager - Terraform 敏感变量必须标记 sensitive = true - Docker 构建禁止通过 ARG/ENV 传递密钥 - docker-compose 敏感值必须使用 secrets 机制或 .env 文件(.env 在 .gitignore 中) - CI/CD 密钥必须使用平台原生 secrets(GitHub Secrets / GitLab CI Variables) - 优先使用 OIDC 联合认证,避免长期凭证 - 所有仓库必须配置 pre-commit hook 运行密钥扫描(gitleaks/ggshield) - 发现密钥泄露后必须立即轮换,不能仅删除文件(Git 历史仍保留)

9. 反模式 6:缺少备份(Missing Backups)

问题描述

AI 生成的基础设施配置几乎从不包含备份策略。当你让 AI 生成一个 RDS 实例或 PostgreSQL 部署时,它会配置好连接参数、性能设置,但很少主动添加自动备份、跨区域复制、快照策略或恢复测试计划。AI 不会主动思考”如果数据丢失了怎么办”——它只关注”如何让服务运行起来”。

危害等级:🔴 严重

  • 数据库故障导致数据永久丢失
  • 勒索软件攻击后无法恢复
  • 误操作(如 DROP TABLE)无法回滚
  • 灾难恢复时间远超业务容忍度
  • 违反数据保留合规要求
  • 备份存在但从未测试过恢复流程,关键时刻发现备份损坏

❌ 错误示例

Terraform — 无备份的数据库

# ❌ 反模式:数据库没有备份配置 resource "aws_db_instance" "main" { identifier = "production-db" engine = "postgres" engine_version = "16.3" instance_class = "db.r6g.large" allocated_storage = 100 storage_type = "gp3" username = var.db_username password = random_password.db.result # ❌ 没有设置备份保留期——默认可能为 0(无备份) # ❌ 没有设置备份窗口 # ❌ 没有启用删除保护 # ❌ 没有配置跨区域只读副本 # ❌ 没有设置最终快照 # ❌ 允许直接删除,不创建最终快照 skip_final_snapshot = true tags = { Name = "production-db" } } # ❌ S3 存储桶没有版本控制 resource "aws_s3_bucket" "data" { bucket = "my-important-data" # ❌ 没有启用版本控制——误删除无法恢复 # ❌ 没有配置生命周期规则 # ❌ 没有跨区域复制 }

Kubernetes — 无备份的有状态服务

# ❌ 反模式:StatefulSet 没有备份策略 apiVersion: apps/v1 kind: StatefulSet metadata: name: postgresql spec: serviceName: postgresql replicas: 1 # ❌ 单副本,无高可用 selector: matchLabels: app: postgresql template: metadata: labels: app: postgresql spec: containers: - name: postgresql image: postgres:16 volumeMounts: - name: data mountPath: /var/lib/postgresql/data volumeClaimTemplates: - metadata: name: data spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: 100Gi # ❌ 没有配置 VolumeSnapshot 策略 # ❌ 没有 CronJob 定期备份 # ❌ 没有备份到外部存储(S3/GCS)

✅ 正确示例

Terraform — 完整的备份策略

# ✅ 正确:完整的数据库备份策略 resource "aws_db_instance" "main" { identifier = "${var.project}-${var.environment}-db" engine = "postgres" engine_version = "16.3" instance_class = local.config.db_class allocated_storage = local.config.db_storage max_allocated_storage = local.config.db_storage * 2 storage_type = "gp3" storage_encrypted = true kms_key_id = aws_kms_key.db.arn username = var.db_username password = random_password.db.result # ✅ 自动备份配置 backup_retention_period = var.environment == "prod" ? 30 : 7 # 生产 30 天,其他 7 天 backup_window = "03:00-04:00" # UTC 凌晨备份 maintenance_window = "Mon:04:00-Mon:05:00" # 维护窗口在备份之后 # ✅ 删除保护 deletion_protection = var.environment == "prod" ? true : false skip_final_snapshot = var.environment == "prod" ? false : true final_snapshot_identifier = var.environment == "prod" ? "${var.project}-final-${formatdate("YYYY-MM-DD", timestamp())}" : null # ✅ 多可用区(生产环境) multi_az = var.environment == "prod" ? true : false # ✅ 启用性能洞察(帮助诊断问题) performance_insights_enabled = true performance_insights_retention_period = 7 # ✅ 启用增强监控 monitoring_interval = 60 monitoring_role_arn = aws_iam_role.rds_monitoring.arn tags = merge(local.common_tags, { BackupRetention = var.environment == "prod" ? "30days" : "7days" RPO = var.environment == "prod" ? "1hour" : "24hours" RTO = var.environment == "prod" ? "4hours" : "24hours" }) } # ✅ 跨区域只读副本(生产环境灾难恢复) resource "aws_db_instance" "replica" { count = var.environment == "prod" ? 1 : 0 identifier = "${var.project}-prod-db-replica" replicate_source_db = aws_db_instance.main.identifier instance_class = "db.r6g.large" storage_encrypted = true # ✅ 副本也有自己的备份 backup_retention_period = 7 tags = merge(local.common_tags, { Role = "read-replica" }) } # ✅ S3 存储桶带版本控制和跨区域复制 resource "aws_s3_bucket" "data" { bucket = "${var.project}-${var.environment}-data" tags = local.common_tags } resource "aws_s3_bucket_versioning" "data" { bucket = aws_s3_bucket.data.id versioning_configuration { status = "Enabled" # ✅ 启用版本控制 } } resource "aws_s3_bucket_lifecycle_configuration" "data" { bucket = aws_s3_bucket.data.id rule { id = "archive-old-versions" status = "Enabled" # ✅ 旧版本 30 天后转到 Glacier noncurrent_version_transition { noncurrent_days = 30 storage_class = "GLACIER" } # ✅ 旧版本 365 天后删除 noncurrent_version_expiration { noncurrent_days = 365 } } }

Kubernetes — 完整的备份策略

# ✅ 正确:使用 CronJob 定期备份 PostgreSQL 到 S3 apiVersion: batch/v1 kind: CronJob metadata: name: postgresql-backup namespace: production spec: # ✅ 每天凌晨 3 点备份 schedule: "0 3 * * *" concurrencyPolicy: Forbid successfulJobsHistoryLimit: 7 failedJobsHistoryLimit: 3 jobTemplate: spec: backupLimit: 1 template: spec: restartPolicy: OnFailure containers: - name: backup image: postgres:16-alpine command: - /bin/sh - -c - | set -e TIMESTAMP=$(date +%Y%m%d_%H%M%S) BACKUP_FILE="/tmp/backup_${TIMESTAMP}.sql.gz" echo "Starting backup at ${TIMESTAMP}..." # ✅ 使用 pg_dump 创建备份 PGPASSWORD="${DB_PASSWORD}" pg_dump \ -h "${DB_HOST}" \ -U "${DB_USER}" \ -d "${DB_NAME}" \ --format=custom \ --compress=9 \ -f "${BACKUP_FILE}" # ✅ 上传到 S3 aws s3 cp "${BACKUP_FILE}" \ "s3://${BACKUP_BUCKET}/postgresql/${TIMESTAMP}.sql.gz" \ --storage-class STANDARD_IA # ✅ 验证备份文件 aws s3 ls "s3://${BACKUP_BUCKET}/postgresql/${TIMESTAMP}.sql.gz" echo "Backup completed: ${BACKUP_FILE}" # ✅ 清理本地临时文件 rm -f "${BACKUP_FILE}" env: - name: DB_HOST value: "postgresql.production.svc.cluster.local" - name: DB_USER valueFrom: secretKeyRef: name: postgresql-credentials key: username - name: DB_PASSWORD valueFrom: secretKeyRef: name: postgresql-credentials key: password - name: DB_NAME value: "myapp" - name: BACKUP_BUCKET value: "myapp-prod-backups" resources: requests: cpu: "100m" memory: "256Mi" limits: cpu: "500m" memory: "512Mi" serviceAccountName: backup-sa # ✅ 使用 IRSA 访问 S3 --- # ✅ VolumeSnapshot 定期快照 apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshot metadata: name: postgresql-snapshot namespace: production spec: volumeSnapshotClassName: csi-aws-ebs source: persistentVolumeClaimName: data-postgresql-0

检测方法

# 检查 RDS 实例的备份配置 aws rds describe-db-instances --query \ 'DBInstances[*].{ID:DBInstanceIdentifier,Backup:BackupRetentionPeriod,MultiAZ:MultiAZ,Encrypted:StorageEncrypted}' \ --output table # 检查 S3 存储桶版本控制 aws s3api get-bucket-versioning --bucket my-bucket # Checkov 检查备份配置 checkov -d terraform/ --check CKV_AWS_16,CKV_AWS_17,CKV_AWS_133 # CKV_AWS_16: RDS 加密 # CKV_AWS_17: RDS 备份保留期 # CKV_AWS_133: RDS 删除保护 # 检查 Kubernetes 中是否有备份 CronJob kubectl get cronjobs -A | grep -i backup

Steering 规则

## 备份与灾难恢复规则 - 所有数据库必须配置自动备份,生产环境保留至少 30 天 - RDS 必须设置 backup_retention_period > 0 - 生产数据库必须设置 deletion_protection = true - 生产数据库必须设置 skip_final_snapshot = false - S3 存储桶必须启用版本控制(versioning) - 关键数据必须有跨区域复制或备份 - 必须定义 RTO 和 RPO 并在资源标签中标注 - Kubernetes 有状态服务必须有 CronJob 备份或 VolumeSnapshot 策略 - 备份恢复流程必须有文档化的运行手册 - 每季度至少进行一次备份恢复演练

10. 其他 DevOps 反模式

除了上述六大核心反模式外,以下是 AI 生成 DevOps 配置中常见的其他问题:

10.1 CI/CD 管线反模式

反模式:未固定 Action 版本

# ❌ 使用标签引用——可能被供应链攻击篡改 - uses: actions/checkout@v4 - uses: docker/build-push-action@latest # ✅ 固定到 commit SHA - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0

反模式:过度权限的 GITHUB_TOKEN

# ❌ 默认权限过大 # 不声明 permissions 意味着使用仓库默认权限(通常是 write-all) # ✅ 最小权限原则 permissions: contents: read pull-requests: write packages: write

反模式:单体管线

# ❌ 所有步骤在一个 job 中,失败后全部重跑 jobs: everything: runs-on: ubuntu-latest steps: - run: npm install # 5 分钟 - run: npm test # 10 分钟 - run: npm run build # 5 分钟 - run: docker build # 5 分钟 - run: docker push # 3 分钟 - run: kubectl apply # 1 分钟 # 如果 kubectl apply 失败,需要重跑全部 29 分钟 # ✅ 分阶段管线,支持部分重跑 jobs: test: runs-on: ubuntu-latest steps: - run: npm install && npm test build: needs: test runs-on: ubuntu-latest steps: - run: npm run build && docker build && docker push deploy: needs: build runs-on: ubuntu-latest environment: production # ✅ 需要人工审批 steps: - run: kubectl apply

10.2 Infrastructure as Code 反模式

反模式:状态文件不安全

# ❌ 本地状态文件——团队无法协作,状态可能丢失 # 没有配置 backend # ✅ 远程状态 + 加密 + 锁定 terraform { backend "s3" { bucket = "myproject-terraform-state" key = "prod/terraform.tfstate" region = "us-east-1" encrypt = true dynamodb_table = "terraform-locks" # ✅ 状态文件加密存储 # ✅ DynamoDB 防止并发修改 } }

反模式:缺少标签

# ❌ 资源没有标签——无法追踪成本和所有权 resource "aws_instance" "app" { instance_type = "t3.medium" ami = var.ami_id } # ✅ 统一标签策略 locals { common_tags = { Project = var.project Environment = var.environment Team = var.team CostCenter = var.cost_center ManagedBy = "terraform" CreatedAt = timestamp() } } resource "aws_instance" "app" { instance_type = "t3.medium" ami = var.ami_id tags = merge(local.common_tags, { Name = "${var.project}-app" }) }

10.3 容器与 Kubernetes 反模式

反模式:以 root 运行容器

# ❌ 默认以 root 运行 FROM node:20 WORKDIR /app COPY . . RUN npm install CMD ["node", "server.js"] # 容器内进程以 root 运行——被入侵后攻击者获得 root 权限 # ✅ 非 root 用户 FROM node:20-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci --production COPY . . RUN npm run build FROM node:20-alpine RUN addgroup -g 1001 -S appgroup && \ adduser -S appuser -u 1001 -G appgroup WORKDIR /app COPY --from=builder --chown=appuser:appgroup /app/dist ./dist COPY --from=builder --chown=appuser:appgroup /app/node_modules ./node_modules USER appuser EXPOSE 8080 CMD ["node", "dist/server.js"]

反模式:使用 :latest 标签

# ❌ 使用 :latest——不可重现,可能导致意外更新 containers: - name: app image: myapp:latest # ✅ 使用特定版本标签或 SHA containers: - name: app image: myapp:v1.2.3 # 或使用 SHA digest # image: myapp@sha256:abc123...

反模式:缺少 Pod 安全上下文

# ❌ 没有安全上下文 spec: containers: - name: app image: myapp:v1.0.0 # ✅ 完整的安全上下文 spec: securityContext: runAsNonRoot: true runAsUser: 1001 fsGroup: 1001 seccompProfile: type: RuntimeDefault containers: - name: app image: myapp:v1.0.0 securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: - ALL

10.4 监控与告警反模式

反模式:告警疲劳

# ❌ 阈值过低,导致大量误报 - alert: HighCPU expr: node_cpu_usage > 50 # ❌ 50% CPU 就告警——太敏感 for: 1m # ❌ 1 分钟就触发——太短 labels: severity: critical # ❌ 全部标为 critical——无法区分优先级 # ✅ 合理的告警配置 - alert: HighCPU expr: | 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85 for: 10m # ✅ 持续 10 分钟才触发 labels: severity: warning # ✅ 合理的严重级别 annotations: summary: "CPU 使用率持续偏高 - {{ $labels.instance }}" runbook_url: "https://wiki.example.com/runbooks/high-cpu"

反模式:缺少 SLO 驱动的告警

# ❌ 只有基础设施告警,没有业务 SLO 告警 # 知道 CPU 高但不知道用户是否受影响 # ✅ SLO 驱动的告警(错误预算消耗速率) - alert: SLOErrorBudgetBurnRate expr: | ( sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) ) > (14.4 * 0.001) # 14.4x burn rate for 99.9% SLO for: 2m labels: severity: page annotations: summary: "错误预算快速消耗,用户正在受到影响"

11. Steering 规则文件实战示例

11.1 完整的 CLAUDE.md DevOps 章节示例

以下是一个真实项目中 CLAUDE.md 的 DevOps 章节完整示例:

# CLAUDE.md ## 项目概述 SaaS 电商平台,部署在 AWS EKS 上,使用 Terraform 管理基础设施。 ## DevOps 规则 ### 基础设施 - IaC 工具:Terraform 1.9 + AWS Provider 5.x - 所有基础设施变更必须通过 Terraform,禁止手动操作 AWS Console - 状态文件存储在 s3://myproject-tfstate/,使用 DynamoDB 锁定 - 模块化结构:terraform/modules/ 存放可复用模块 ### 安全红线(违反即阻止合并) 1. 禁止 0.0.0.0/0 入站规则(除 ALB 的 80/443) 2. 禁止硬编码任何密钥、密码、Token 3. 禁止 :latest 镜像标签 4. 禁止 privileged 容器 5. 禁止未加密的数据库和 S3 存储桶 6. 禁止未固定版本的 GitHub Actions ### 资源配置标准 | 环境 | EC2 | RDS | EKS Node | |------|-----|-----|----------| | dev | t3.small | db.t4g.micro | t3.medium | | staging | t3.medium | db.t4g.small | t3.large | | prod | m6i.large | db.r6g.large | m6i.xlarge | ### 必需配置清单 - [ ] 所有 K8s 工作负载有 livenessProbe + readinessProbe - [ ] 所有容器有 resources.requests + resources.limits - [ ] 所有资源有 common_tags(Project, Environment, Team, CostCenter) - [ ] 数据库有自动备份(生产 30 天,其他 7 天) - [ ] 所有服务使用结构化 JSON 日志 - [ ] 每个命名空间有 default-deny NetworkPolicy

11.2 完整的 Kiro Steering 目录结构

.kiro/ ├── steering/ │ ├── devops-terraform.md # Terraform 专用规则 │ ├── devops-kubernetes.md # Kubernetes 专用规则 │ ├── devops-docker.md # Dockerfile 专用规则 │ ├── devops-cicd.md # CI/CD 专用规则 │ └── devops-security.md # 安全通用规则

11.3 完整的 .cursorrules DevOps 示例

--- description: DevOps 和基础设施配置的代码生成规则 globs: "**/*.tf,**/*.tfvars,**/Dockerfile,**/*.yaml,**/*.yml,**/.github/**" --- # DevOps 代码生成规则 ## 安全默认值 生成任何 DevOps 配置时,必须默认包含以下安全措施: - 网络:最小权限,默认拒绝 - 密钥:通过 Secrets Manager 引用,永不硬编码 - 容器:非 root 用户,只读文件系统 - 加密:所有存储和传输加密 - 标签:所有资源必须有标签 ## 生成 Terraform 时 - 使用 terraform-aws-modules 官方模块 - 所有变量有 description 和 type - 敏感变量标记 sensitive = true - 输出值有 description - 使用 locals 定义通用标签 ## 生成 Kubernetes 时 - 所有 Pod 有 securityContext(runAsNonRoot, readOnlyRootFilesystem) - 所有容器有 resources(requests + limits) - 所有 Deployment 有 livenessProbe + readinessProbe - 使用 Kustomize 或 Helm 管理环境差异 ## 生成 Dockerfile 时 - 多阶段构建 - 非 root 用户(USER 指令) - 特定版本基础镜像(禁止 :latest) - HEALTHCHECK 指令 - .dockerignore 文件 ## 生成 CI/CD 时 - Action 固定到 SHA - 最小权限 permissions - 密钥使用 ${{ secrets.XXX }} - 安全扫描步骤(Trivy/Checkov)

12. DevOps Prompt 工程技巧

12.1 DevOps 专用 Prompt 模式

模式 1:安全审查 Prompt

你是一位资深 DevOps 安全工程师。请审查以下基础设施配置, 按 OWASP Infrastructure Security 标准检查安全问题。 ## 配置文件 [粘贴配置] ## 审查维度 1. 网络安全(安全组、防火墙、网络隔离) 2. 身份与访问(IAM、RBAC、最小权限) 3. 数据保护(加密、备份、密钥管理) 4. 日志与监控(审计日志、告警、可追溯性) 5. 合规性([SOC 2 / HIPAA / PCI DSS]) ## 输出格式 对每个发现的问题: - 严重程度:🔴 高 / 🟡 中 / 🟢 低 - 问题描述 - 影响分析 - 修复代码 - 对应的 CIS Benchmark 或 Checkov 检查 ID

模式 2:成本优化 Prompt

你是一位云成本优化专家。请分析以下基础设施配置的成本效率, 并提供优化建议。 ## 当前配置 [粘贴 Terraform/K8s 配置] ## 环境信息 - 环境类型:[dev / staging / prod] - 预期流量:[描述] - 预算限制:[月度预算] ## 请提供 1. 当前配置的预估月度成本 2. 过度配置的资源列表 3. 具体的降配建议(保持性能的前提下) 4. 预估优化后的月度成本 5. 优化后的配置代码

模式 3:灾难恢复规划 Prompt

你是一位 SRE 专家。请为以下系统设计灾难恢复策略。 ## 系统架构 [描述系统架构和关键组件] ## 业务要求 - RTO(恢复时间目标):[例如:4 小时] - RPO(恢复点目标):[例如:1 小时] - 数据保留要求:[例如:7 年] ## 请提供 1. 备份策略(频率、存储位置、保留期) 2. 故障转移方案(自动/手动、跨区域/跨可用区) 3. 恢复流程运行手册 4. 恢复测试计划(频率、范围、验证标准) 5. 完整的 Terraform/K8s 配置代码

12.2 AI 辅助 DevOps 配置审查工作流

┌─────────────────────────────────────────────────────────────┐ │ AI 辅助 DevOps 配置审查工作流 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 步骤 1: AI 生成配置 │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ 需求描述 │───▶│ AI 生成 │───▶│ 初始配置 │ │ │ │ + Steering│ │ 配置代码 │ │ 文件 │ │ │ └──────────┘ └──────────┘ └──────────┘ │ │ │ │ │ 步骤 2: 自动化安全扫描 │ │ ┌──────────┐ ┌──────────┐ ┌────▼─────┐ │ │ │ Checkov │ │ tfsec │ │ Trivy │ │ │ │ 扫描 │ │ 扫描 │ │ 扫描 │ │ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │ └───────────────┼───────────────┘ │ │ ▼ │ │ 步骤 3: AI 修复扫描发现 │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ 扫描报告 │───▶│ AI 分析 │───▶│ 修复后 │ │ │ │ + 配置 │ │ 并修复 │ │ 配置 │ │ │ └──────────┘ └──────────┘ └──────────┘ │ │ │ │ │ 步骤 4: 人工审查 │ │ ┌──────────┐ ┌──────────┐ ┌────▼─────┐ │ │ │ 安全审查 │ │ 成本审查 │ │ 架构审查 │ │ │ │ (安全组) │ │(Infracost)│ │ (设计) │ │ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │ └───────────────┼───────────────┘ │ │ ▼ │ │ 步骤 5: 合并与部署 │ │ ┌──────────────────────────────────────┐ │ │ │ PR 合并 → CI/CD 管线 → 部署到目标环境 │ │ │ └──────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘

实战案例:从零构建安全的 DevOps 配置

案例背景

一个电商 SaaS 项目需要部署到 AWS EKS,包含以下组件:

  • Web API(Node.js)
  • 后台任务处理(Go)
  • PostgreSQL 数据库
  • Redis 缓存
  • GitHub Actions CI/CD

案例流程

第一步:创建 Steering 规则

在项目根目录创建 .kiro/steering/devops.md(或 CLAUDE.md 中添加 DevOps 章节),包含本文第 2 节中的完整规则模板。

第二步:让 AI 生成基础设施配置

使用以下 Prompt:

请为电商 SaaS 项目生成完整的 AWS EKS 基础设施配置。 ## 组件 - Web API(Node.js 20,3 个副本) - Worker(Go 1.22,2 个副本) - PostgreSQL 16(RDS) - Redis 7(ElastiCache) ## 环境 - 当前生成 production 环境配置 - 必须支持 dev/staging/prod 三个环境参数化 ## 安全要求 遵循项目 Steering 规则中的所有安全约束。 ## 请生成 1. Terraform 模块(VPC + EKS + RDS + ElastiCache + IAM) 2. Kubernetes manifests(Deployment + Service + Ingress + NetworkPolicy + HPA) 3. Dockerfile(多阶段构建) 4. GitHub Actions 工作流(构建 + 测试 + 安全扫描 + 部署)

第三步:运行安全扫描

# Terraform 安全扫描 checkov -d terraform/ --output cli --compact # Kubernetes 安全扫描 checkov -d k8s/ --framework kubernetes --output cli # Dockerfile 安全扫描 trivy config Dockerfile # 密钥扫描 gitleaks detect --source . --verbose

第四步:AI 修复扫描发现的问题

将扫描报告反馈给 AI:

以下是 Checkov 扫描报告,请修复所有 FAILED 的检查项: [粘贴 Checkov 输出] 请逐一修复,并解释每个修复的原因。

第五步:成本审查

# 生成成本报告 infracost breakdown --path terraform/ --format html --out-file cost-report.html

案例分析

通过 Steering 规则 + AI 生成 + 自动化扫描 + 人工审查的四层防护,可以显著提高 AI 生成 DevOps 配置的质量:

  1. Steering 规则:在 AI 生成阶段就注入安全约束,减少 60-70% 的安全问题
  2. 自动化扫描:捕获 Steering 规则未覆盖的问题,如特定云服务的安全配置
  3. AI 修复:快速修复扫描发现的问题,减少人工修复时间
  4. 人工审查:最终的质量把关,确保架构合理性和业务适配性

避坑指南

❌ 常见错误

  1. 只依赖 Steering 规则而不做安全扫描

    • 问题:Steering 规则是”建议”,AI 可能不完全遵守;且规则无法覆盖所有安全场景
    • 正确做法:Steering 规则 + 自动化扫描(Checkov/tfsec/Trivy)双重保障
  2. 在 Git 中提交了密钥后只删除文件

    • 问题:Git 历史中仍然保留密钥,任何人都可以通过 git log 查看
    • 正确做法:立即轮换泄露的密钥,使用 git filter-branch 或 BFG Repo-Cleaner 清理历史,配置 pre-commit hook 防止再次发生
  3. 开发环境和生产环境使用相同的安全配置

    • 问题:开发环境的宽松配置被复制到生产环境
    • 正确做法:使用环境变量或 tfvars 文件区分环境,生产环境使用更严格的安全设置
  4. liveness 探针检查外部依赖

    • 问题:数据库故障时所有 Pod 被杀死,导致级联故障
    • 正确做法:liveness 只检查进程存活,readiness 检查外部依赖
  5. 备份从未测试过恢复

    • 问题:关键时刻发现备份损坏或恢复流程不可用
    • 正确做法:每季度进行备份恢复演练,验证 RTO 和 RPO 是否满足要求
  6. CI/CD 使用 @latest 引用 Action

    • 问题:供应链攻击可以通过篡改 Action 代码注入恶意代码
    • 正确做法:固定到 commit SHA,定期审查和更新
  7. 所有告警都标为 critical

    • 问题:告警疲劳,团队开始忽略告警
    • 正确做法:分级告警(info/warning/critical/page),只有真正影响用户的问题才 page
  8. Docker 镜像使用 :latest 标签

    • 问题:部署不可重现,可能意外引入破坏性变更
    • 正确做法:使用语义化版本标签(v1.2.3)或 SHA digest

✅ 最佳实践

  1. 安全左移:在 AI 生成阶段就通过 Steering 规则注入安全约束,而非事后修复
  2. 自动化门禁:CI/CD 中集成 Checkov、tfsec、Trivy、GitGuardian 等扫描工具,不通过不合并
  3. 环境参数化:所有配置通过变量区分环境,禁止硬编码环境特定值
  4. 最小权限原则:网络、IAM、容器权限都遵循最小权限,显式开放而非默认开放
  5. 可观测性优先:每个服务必须有结构化日志、健康检查和 Prometheus 指标
  6. 备份即代码:备份策略写在 Terraform/K8s 配置中,与基础设施一起版本化管理
  7. 定期演练:每季度进行灾难恢复演练和安全审计
  8. 成本可见:每个 PR 都显示成本影响(Infracost),让成本成为审查的一部分

相关资源与延伸阅读

  1. Checkov — IaC 静态分析工具 :开源的 IaC 安全扫描工具,支持 Terraform、Kubernetes、Docker 等,内置 2000+ 安全策略
  2. tfsec — Terraform 安全扫描 :专注于 Terraform 的安全扫描工具,现已集成到 Trivy
  3. Infracost — IaC 成本估算 :在 PR 中显示基础设施变更的成本影响,支持 Terraform 和 OpenTofu
  4. GitGuardian — 密钥泄露检测 :扫描 Git 仓库中的密钥泄露,支持 pre-commit hook 和 CI/CD 集成
  5. OPA/Rego — 策略即代码 :通用策略引擎,可用于 Kubernetes 准入控制、Terraform 策略执行等
  6. Kubernetes Security Best Practices — OWASP :OWASP Kubernetes 安全速查表
  7. CIS Benchmarks :CIS 安全基准,覆盖 AWS、Kubernetes、Docker 等平台的安全配置标准
  8. HashiCorp Well-Architected Framework — CI/CD Anti-Patterns :HashiCorp 关于 CI/CD 密钥管理反模式的官方指南
  9. Cloud Security Alliance — AI and Deterministic Security for Infra :CSA 关于 AI 生成 IaC 代码安全性的研究报告(2025)
  10. Endor Labs — Design Flaws in AI Generated Code :AI 生成代码中的设计缺陷分析(2025)

参考来源


📖 返回 总览与导航 | 上一节:32e-AI辅助监控与事件响应 | 下一节:33a-AI辅助移动端开发概览

Last updated on