Ansible 还是 Terraform:AI 平台基础设施即代码的选型复盘 📅 2026/7/25 3:37:04 Ansible 还是 TerraformAI 平台基础设施即代码的选型复盘一、基础设施即代码不是二选一而是工具维度的精准匹配AI 平台的基础设施有两个截然不同的管理层面底层云资源GPU 节点、网络 VPC、对象存储桶和上层软件配置Kubernetes 组件、NVIDIA 驱动、容器运行时的参数。这两个层面的管理语义完全不同——资源管理是声明式的我要 30 台 A100 机器软件配置是过程式的先装驱动再配内核参数再重启 kubelet。Ansible 和 Terraform 分别擅长这两个层面Terraform 管理基础设施资源的生命周期创建 → 更新 → 销毁Ansible 管理操作系统和中间件的配置状态。理论上两者可以互不冲突地协作但工程实践中的真实问题是当 GPU 节点被 Terraform 创建出来后Ansible 如何知道这台节点已经就绪并立即开始配置当 Terraform 需要销毁一台节点时如何通知 Ansible 先执行安全下线操作这就是选型复盘要回答的核心问题不是选哪个工具而是如何设计两者的交接面使得资源管理和配置管理形成一个无缝编排的闭环。二、两种工具的协同模式与交接面设计这种协同模式需要三个关键组件动态 Inventory。传统 Ansible 的主机清单是静态文件节点 IP 写死在里面。AI 平台的 GPU 节点是动态创建和销毁的IP 每次不同。解决方案是用 Terraform 的template_file或local_file资源在节点创建后动态生成 Inventory 文件再通过 Ansible 的-i参数传入。更标准的方式是通过 Terraform 的ansibleprovisioner 直接调用——但这个 provisioner 的局限是只在terraform apply时执行一次后续节点的配置变更无法通过它触发。失效安全的顺序编排。Terraform 和 Ansible 的交接点是最容易出问题的环节。节点创建完成 ≠ 节点可以执行 Ansible——SSH 服务可能需要 30 秒才能完全启动云平台的 UserData 脚本可能还在运行。如果 Ansible 在这个时间窗口内执行连接会超时Playbook 会失败。解决方案是在 Terraform 的remote-execprovisioner 中嵌入一个健康检查脚本循环等待 SSH 端口直到连接成功然后将节点标记为配置就绪。回滚的一致性。如果 Ansible 配置失败Terraform 应该如何响应直接销毁节点重建是最干净的做法但这要求 Terraform 能感知 Ansible 的执行结果。我们的做法是在节点创建后设置一个provisioning_status标签Ansible 成功后通过 API 将其更新为readyTerraform 在后续 Plan 中检查所有节点的状态标签对failed状态的节点自动触发taint → destroy → recreate流程。三、生产代码Terraform Ansible 交接面的工程实现# terraform/gpu_node_pool.tf # GPU 节点池定义 resource google_container_node_pool gpu_a100 { name gpu-a100-pool cluster google_container_cluster.ai_platform.name node_count var.gpu_node_count node_config { machine_type a2-highgpu-1g disk_size_gb 200 image_type UBUNTU_CONTAINERD guest_accelerator { type nvidia-tesla-a100 count 1 } # 节点标签用于 Ansible 动态分组 labels { role gpu-worker gpu_type a100 provisioned pending # 初始状态Ansible 完成后改为 ready } # 操作系统层面的 GPU 驱动依赖 metadata { install-nvidia-driver false # 由 Ansible 安装指定版本 } } lifecycle { create_before_destroy true ignore_changes [node_config[0].labels[provisioned]] } } # 健康检查确保节点 SSH 可达后再交接给 Ansible resource null_resource health_check { depends_on [google_container_node_pool.gpu_a100] count var.gpu_node_count connection { type ssh host element(google_compute_instance.gpu_nodes.*.network_interface.0.access_config.0.nat_ip, count.index) user ubuntu private_key file(var.ssh_private_key_path) timeout 2m } provisioner remote-exec { inline [ # 等待云初始化脚本完成 while [ ! -f /var/lib/cloud/instance/boot-finished ]; do sleep 5; done, # 验证 NVIDIA GPU 设备被识别 lspci | grep -i nvidia || echo GPU not detected yet, # 检查容器运行时是否安装如果镜像已预装 which containerd || apt-get update apt-get install -y containerd, ] } } # Ansible 配置触发使用 local-exec 调用 Ansible resource null_resource ansible_provision { depends_on [null_resource.health_check] count var.gpu_node_count provisioner local-exec { command -EOT ansible-playbook \ -i ${element(google_compute_instance.gpu_nodes.*.network_interface.0.access_config.0.nat_ip, count.index)}, \ -u ubuntu \ --private-key ${var.ssh_private_key_path} \ playbooks/gpu-node-setup.yml \ -e node_index${count.index} \ -e node_zone${var.zone} if [ $? -ne 0 ]; then echo Ansible playbook failed for node ${count.index} 2 # 标记节点为 failed 状态由下一轮 Terraform Plan 处理 exit 1 fi EOT } }这套代码的核心设计原则Terraform 做它擅长的事——计算期望和实际的差异Ansible 做它擅长的事——确保操作系统的配置达到声明状态。两者之间通过provisioned标签和health_check资源作为交接面不直接耦合。四、选型复盘两条路径的边界条件和代价如果放弃Terraform Ansible的协同架构走向极端选择单一工具呢纯 Terraform 路径。Terraform 可以通过remote-execprovisioner 直接执行 shell 命令来安装驱动和配置系统。代价是 Terraform 的 provisioner 不具备幂等性声明——它不知道驱动是否已经安装正确只能在apply时重新执行所有命令。结果就是每次terraform apply都会重新跑安装脚本初次创建 3 分钟的节点配置被拖到 12 分钟。纯 Ansible 路径。用 Ansible 的云模块如gcp_container_node_pool创建资源。问题是 Ansible 的云模块不如 Terraform 的 provider 完善资源间的依赖关系表达不清晰state文件的管理也不如 Terraform 成熟。销毁 30 个节点并清理关联的磁盘和 IP用 Terraform 只需要terraform destroy用 Ansible 需要仔细编排 playbook 的顺序和absent状态的管理。协同路径更繁琐但更稳定的趋势。维护两套配置.tf和.yml虽然增加了代码量但它将基础设施的两个维度解耦到了各自的最佳工具中。协同的关键是两个原则Terraform 负责创建什么Ansible 负责配置成什么这是最清晰的职责划分。状态交接只通过标签和 API不使用 provisioning script 的返回值作为状态判断依据——因为返回值只会反映 exit code不反应实际系统的运行状态。五、总结AI 平台基础设施即代码的选型核心是职责切割而非工具替代Terraform 管理基础设施资源GPU 节点、网络、负载均衡、存储——这些资源的生命周期是创建-更新-销毁天然适合声明式语言描述。Ansible 管理操作系统和中间件配置驱动版本、内核参数、运行时配置——这些是多步骤的过程式任务需要幂等性和可重复执行。交接面需要工程化设计动态 Inventory、健康检查等待、失败节点的状态回传——这三个组件不比基础设施本身简单值得投入工程资源打磨。基础设施不需要漂亮话。Terraform 和 Ansible 不是选哪个更酷的问题而是你的自动化流水线出了多少次节点创建成功但配置失败的告警之后才被迫去做的交接面设计。