slug: cloud-ops-orchestrator name: cloud-ops-orchestrator version: "1.0.0" displayName: 云运维编排器 summary: 用 Terraform+Ansible 编排多云基础设施,内置漂移检测、变更预演与安全销毁,杜绝误删。 license: MIT description: |- 云运维编排器为 AI Agent 提供以基础设施即代码(IaC)为核心的多云运维能力。它明确划分 Terraform(资源生命周期)与 Ansible(系统配置)的职责边界,覆盖 AWS、GCP、Azure 三大云,并内置状态漂移检测、变更预演(plan)、安全销毁(带保护期)、凭证隔离与回滚机制。
核心能力:多云资源编排(Terraform)、批量配置管理(Ansible)、CloudFormation 模板、状态漂移检测与自动修正、变更预演与审批门禁、分环境(dev/staging/prod)隔离、安全销毁保护期、凭证 vault 集成。
适用场景:多环境交付、灾备切换、扩缩容演练、合规基线对齐、成本优化清理、一人公司 DevOps 自动化。
差异化:相比只罗列命令的原始方案,本技能新增职责边界红线(Terraform 管什么/Ansible 管什么)、漂移检测工作流(plan-diff-apply 三段式)、销毁保护期(prod 环境强制 72 小时锁定与二次确认)、环境隔离矩阵、以及变更预演报告生成。所有销毁类操作默认 dry-run,需显式 --confirm 才执行。
触发关键词:云, 基础设施, 编排, terraform, ansible, aws, gcp, azure, drift, 销毁, 部署, cloud, infra, provision tags: - 自动化 - 云运维 - 基础设施即代码 tools: - read - exec
用声明式代码管理多云基础设施,把"手动点控制台"变成"可审计、可回滚、可预演"的工程化流程。本技能解决五个核心痛点:职责混淆(Terraform/Ansible 用错地方)、状态漂移(线上与代码不一致)、误删灾难(destroy 不可逆)、凭证泄露(明文 AK/SK)、环境串味(dev 改动影响 prod)。
这是最常出错的地方。明确分工:
| 维度 | Terraform 负责 | Ansible 负责 |
|---|---|---|
| 对象 | 云资源生命周期 | 主机内配置 |
| 操作 | 创建/修改/销毁资源 | 安装软件/改配置/启服务 |
| 状态 | 有状态(state 文件) | 无状态(幂等剧本) |
| 典型 | VPC、EC2、RDS、LB | Nginx 配置、应用部署、用户管理 |
| 禁止 | ❌ 不要用 TF 装软件 | ❌ 不要用 Ansible 建云资源 |
一句话原则:Terraform 声明"有什么",Ansible 声明"里面跑什么"。两者通过 Terraform 输出的主机清单(inventory)衔接。
# 验证工具链
terraform version # >= 1.5
ansible --version # >= 2.15
aws --version # 或 gcloud / az 版本
# 验证凭证(不要把凭证写进代码)
aws sts get-caller-identity # AWS
gcloud auth list # GCP
az account show # Azure
./cloud-ops.sh init aws prod # 初始化 prod 环境后端
./cloud-ops.sh plan prod # 预演变更,生成报告
./cloud-ops.sh review prod # 人工/Agent 审查 plan 输出
./cloud-ops.sh apply prod # 执行变更(需 --confirm)
./cloud-ops.sh destroy prod # 默认 dry-run,只列出将删除的资源
./cloud-ops.sh destroy prod --confirm # 二次确认后才真正销毁
prod 环境强制 72 小时保护期:距离上次 apply 不足 72 小时的资源拒绝销毁,除非加 --override-lock。
cloud-ops.sh <command> <env> [options]
命令:
init 初始化工作目录与 Terraform 后端
plan 预演变更(dry-run)
review 生成人类可读的变更摘要
apply 执行变更(需 --confirm)
destroy 销毁资源(默认 dry-run,需 --confirm,prod 有保护期)
drift 检测状态漂移
reconcile 修正漂移(apply 差异)
config 运行 Ansible 配置
output 导出主机清单给 Ansible
cost 估算资源成本
环境: dev | staging | prod
通用选项: --confirm, --dry-run, --module <name>, --override-lock
infra/
├── cloud-ops.sh # 编排入口
├── envs/
│ ├── dev/ # 开发环境
│ │ ├── backend.tf # 状态后端
│ │ ├── terraform.tfvars # 环境变量
│ │ └── providers.tf
│ ├── staging/
│ └── prod/
├── modules/ # 可复用模块
│ ├── web-app/
│ ├── database/
│ ├── k8s-cluster/
│ └── serverless/
├── ansible/
│ ├── inventories/ # 由 terraform output 生成
│ ├── playbooks/
│ └── roles/
└── policies/ # 策略与守卫
├── destroy-guard.json
└── drift-baseline.json
漂移(drift)指线上实际资源与 Terraform state 不一致,常因手动改控制台引起。
# 检测漂移(只读,不改任何东西)
./cloud-ops.sh drift prod
输出示例:
DRIFT REPORT - prod (2026-07-18 09:00)
──────────────────────────────────────
[CHANGED] aws_security_group.web
ingress[0].from_port: 443 → 8443 (手动修改)
[MISSING] aws_s3_bucket.logs
资源在 state 中但云上不存在(可能被手动删除)
[EXTRA] aws_instance.bastion-2
云上存在但 state 中无(手动创建未纳入 IaC)
建议:
- reconcile: 用代码覆盖线上(推荐用于配置类漂移)
- import: 把手动资源纳入 IaC(推荐用于未纳管资源)
- ignore: 标记为已知例外
# 修正漂移(把线上拉回代码定义)
./cloud-ops.sh reconcile prod --confirm
# 或反过来:把手动资源纳入 IaC
./cloud-ops.sh import prod aws_instance.bastion-2 i-xxxxx
plan 命令不仅输出 Terraform 原始日志,还生成结构化摘要,供 Agent 或人审:
./cloud-ops.sh plan prod
{
"env": "prod",
"summary": {
"add": 3,
"change": 1,
"destroy": 0
},
"resources": [
{"action": "create", "type": "aws_rds_instance", "name": "primary", "risk": "medium"},
{"action": "create", "type": "aws_security_group", "name": "db", "risk": "low"},
{"action": "update", "type": "aws_lb_listener", "name": "https", "risk": "high", "note": "修改监听端口将导致短暂中断"}
],
"cost_delta": "+$340/月",
"requires_confirm": true
}
risk 字段帮助 Agent 决定是否需要人工确认。high 风险变更默认拒绝自动 apply。
| 环境 | 后端 | 凭证 | 保护期 | 自动 apply |
|---|---|---|---|---|
| dev | 本地文件 | 个人 IAM | 无 | 允许 |
| staging | S3+锁 | CI IAM | 2 小时 | 允许(CI 触发) |
| prod | S3+DynamoDB 锁 | 专用 IAM(最小权限) | 72 小时 | 禁止,必须人工确认 |
环境之间通过独立的 state 后端和 IAM 角色物理隔离,避免 dev 的 plan 误读 prod 的 state。
绝对禁止:把 AWS_ACCESS_KEY_ID 写进 .tf 文件或提交到 Git。
推荐方式(按优先级):
export AWS_PROFILE=prod-admin
# 或
export AWS_ACCESS_KEY_ID=xxx
export AWS_SECRET_ACCESS_KEY=xxx
# CI 通过 OIDC 临时获取凭证,无需存储 AK/SK
provider "aws" {
# 凭证由 CI 运行时注入
}
export AWS_ACCESS_KEY_ID=$(vault read -field=access_key secret/cloud/prod)
.gitignore 必须包含:
*.tfvars.local
*.tfstate
*.tfstate.*
.cr-credentials/
module "web_app" {
source = "./modules/web-app"
name = "api"
env = "prod"
instance_count = 3
min_size = 2
max_size = 6
health_check_path = "/health"
vpc_id = module.network.vpc_id
subnets = module.network.private_subnets
}
module "database" {
source = "./modules/database"
engine = "postgres"
version = "15"
instance_class = "db.r6g.large"
allocated_storage = 200
backup_retention = 30
multi_az = true
read_replica_count = 1
}
module "k8s" {
source = "./modules/k8s-cluster"
kubernetes_version = "1.28"
node_groups = {
general = { instance_type = "t3.large", desired = 3, min = 2, max = 5 }
spot = { instance_type = "t3.medium", desired = 2, min = 0, max = 10, capacity_type = "spot" }
}
}
module "serverless" {
source = "./modules/serverless"
runtime = "python3.11"
memory = 512
timeout = 30
log_retention = 14
}
Terraform 建好主机后,输出 inventory 给 Ansible:
# 1. Terraform 输出主机信息
./cloud-ops.sh output prod > ansible/inventories/prod.yml
# 2. Ansible 配置主机
./cloud-ops.sh config prod --playbook site.yml
inventory 生成模板:
all:
children:
web:
hosts:
web-0: { ansible_host: 10.0.1.10, ansible_user: ec2-user }
web-1: { ansible_host: 10.0.1.11, ansible_user: ec2-user }
db:
hosts:
db-primary: { ansible_host: 10.0.2.10 }
./cloud-ops.sh init aws dev
./cloud-ops.sh plan dev --module web-app
./cloud-ops.sh apply dev --confirm
./cloud-ops.sh output dev
./cloud-ops.sh config dev --playbook bootstrap.yml
# 修改 terraform.tfvars: instance_count = 5
./cloud-ops.sh plan prod # 确认只增不减
./cloud-ops.sh review prod # 检查风险等级
./cloud-ops.sh apply prod --confirm # 执行
# 识别闲置资源
./cloud-ops.sh cost dev --idle
# 销毁(dev 无保护期)
./cloud-ops.sh destroy dev --confirm
# 提升只读副本为主
./cloud-ops.sh plan prod --module database --promote-replica
./cloud-ops.sh apply prod --confirm
# 切换 DNS
./cloud-ops.sh config prod --playbook failover.yml
destroy 命令的多层防护:
--confirm 只列出将删除的资源,不执行。policies/destroy-guard.json 标记的关键资源(如生产数据库)强制要求 --override-lock。// policies/destroy-guard.json
{
"protected_resources": [
{"type": "aws_rds_instance", "pattern": "prod-*", "reason": "生产数据库"},
{"type": "aws_s3_bucket", "pattern": "backup-*", "reason": "备份桶"}
],
"prod_lock_hours": 72,
"require_override": ["prod"]
}
Q:Terraform state 文件放哪?
A:dev 用本地文件;staging/prod 用 S3+DynamoDB 锁,禁止本地存 prod state。init 命令会按环境矩阵自动配置后端。
Q:plan 显示要删一个资源但我没动它?
A:常见于 state 漂移或代码被他人修改。先 git diff 看 .tf 改动,再 drift 检查线上。不要盲目 apply。
Q:Ansible 和 Terraform 谁先执行?
A:Terraform 先建资源,output 生成 inventory,Ansible 后配置。变更时顺序相反:先 Ansible 下线应用,再 Terraform 改资源。
Q:如何回滚?
A:IaC 的回滚 = git revert + apply。把代码回退到上一个版本重新 apply。前提是 state 没被破坏性修改。
Q:多云混用怎么管凭证?
A:每个 provider 用独立的 profile/项目,通过 alias 区分。不要在一个 provider 块里塞多个云的凭证。
Q:CI 里怎么跑? A:用 OIDC 短期凭证,CI 只对 staging 有 apply 权限,prod 必须人工触发。参考环境隔离矩阵。
| 症状 | 可能原因 | 处置 |
|---|---|---|
Error acquiring the state lock |
上次执行中断未释放锁 | force-unlock 谨慎使用,先确认无其他进程在跑 |
plan 显示全部重建 |
state 文件丢失或后端配置变 | 检查 backend.tf,必要时 import 恢复 |
Provider produced inconsistent result |
provider 版本 bug | 锁定 provider 版本,升级到稳定版 |
| Ansible 连接超时 | 安全组未放行 22/SSH 端口 | 检查 Terraform 创建的 security group |
destroy 报 resource not empty |
S3 桶/DB 有数据 | 按策略先清空或确认后再加 --force |
凭证报 InvalidClientTokenId |
AK/SK 过期或权限不足 | 轮换密钥,检查 IAM 策略 |
-parallelism=20 可调高(小心 API 限流)。fact_caching=redis 避免每次采集。-target 只 plan 变更模块,但注意不要长期依赖 target(会掩盖漂移)。| 依赖项 | 类型 | 是否必需 | 获取方式 |
|---|---|---|---|
| Terraform | CLI | 必需 | >= 1.5,brew install terraform 或官方下载 |
| Ansible | CLI | 必需 | >= 2.15,pip install ansible |
| AWS CLI | CLI | AWS 必需 | brew install awscli |
| GCP CLI (gcloud) | CLI | GCP 必需 | 官方安装 |
| Azure CLI (az) | CLI | Azure 必需 | brew install azure-cli |
| jq | CLI | 必需(报告解析) | apt install jq |
| LLM API | API | 必需 | 由 Agent 内置 LLM 提供 |
AWS_PROFILE 或 AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY,建议 OIDC。GOOGLE_APPLICATION_CREDENTIALS 指向服务账号 JSON。az login 或 ARM_CLIENT_ID/ARM_CLIENT_SECRET/ARM_TENANT_ID/ARM_SUBSCRIPTION_ID。小葱技能7w4.net有完整的技能分类。
cloud-ops.sh 编排底层工具链,负责策略判断、风险审查与人工确认触发。这个 Skill 的内容框架不错,涵盖了云基础设施管理的多个重要场景,但实际质量有待提升。优点是功能覆盖较全面,有详细的使用指南和最佳实践;主要不足是文档中有很多重复内容和不完整句子,看起来像是初稿未经整理。最关键的是,它只提供了文字说明而没有可执行的脚本工具,对于想直接使用的用户来说帮助有限。如果后续能补充完整的工具脚本并优化文档质量,会更加实用。