4. 自动化环境部署:使用 Terraform 与 Ansible 实现服务目录平台的一键部署与配置
服务目录平台的上线往往涉及多云基础设施、中间件集群、应用配置与安全策略的协同。手动部署不仅耗时且极易出错,尤其在环境晋级(开发→测试→预发→生产)过程中,配置漂移是导致故障的首要原因。本章将演示如何通过 Terraform 完成基础设施即代码(IaC)的声明式编排,再通过 Ansible 完成配置管理与应用交付,最终实现从裸云资源到可用服务目录平台的“一键部署”。
核心目标: 一次编写,环境无关;版本控制,可审计;幂等执行,消除漂移。
4.1 工具选型与分工矩阵
Terraform 与 Ansible 并非竞争关系,而是互补工具。下表明确了二者在自动化流水线中的职责边界:
| 维度 | Terraform | Ansible |
|---|---|---|
| 核心定位 | 基础设施编排(IaC) | 配置管理与应用部署 |
| 状态管理 | 有状态(.tfstate 文件) | 无状态(幂等执行) |
| 执行模型 | 声明式(期望状态) | 过程式(Playbook 步骤) |
| 主要操作对象 | 云资源(VPC、ECS、RDS、SLB) | 操作系统、中间件、应用文件 |
| 变更粒度 | 资源级(创建/销毁/替换) | 包/服务/文件/模板级 |
| 典型交付物 | 基础设施拓扑 | 可运行的应用系统 |
最佳实践: 使用 Terraform 输出(Output)将云资源 IP、连接串等动态信息直接注入 Ansible 的 Inventory 或 Extra Vars,实现两阶段无缝衔接。
4.2 整体自动化流程架构
下图展示了从代码提交到服务目录平台可用的完整自动化链路。Terraform 负责“建楼”,Ansible 负责“精装”。
4.3 Terraform 核心配置示例
以下是一个精简的 Terraform 配置,用于创建服务目录平台所需的 VPC、ECS 实例和 RDS 数据库。所有资源通过变量(Variable)实现环境差异化。
# main.tf - 服务目录平台基础设施定义
terraform {
required_version = ">= 1.5"
backend "s3" {
bucket = "catalog-tfstate-${var.env}"
key = "catalog-platform/terraform.tfstate"
region = "cn-north-1"
}
}
provider "aws" {
region = var.region
}
# 1. 网络层
resource "aws_vpc" "catalog_vpc" {
cidr_block = var.vpc_cidr
tags = { Name = "catalog-vpc-${var.env}" }
}
resource "aws_subnet" "public" {
count = 2
vpc_id = aws_vpc.catalog_vpc.id
cidr_block = cidrsubnet(var.vpc_cidr, 8, count.index)
availability_zone = data.aws_availability_zones.available.names[count.index]
tags = { Name = "catalog-public-${var.env}-${count.index}" }
}
# 2. 计算层 - ECS 实例
resource "aws_instance" "catalog_app" {
count = var.app_instance_count
ami = data.aws_ami.centos8.id
instance_type = var.app_instance_type
subnet_id = aws_subnet.public[count.index % 2].id
tags = { Name = "catalog-app-${var.env}-${count.index}" }
}
# 3. 数据层 - RDS
resource "aws_db_instance" "catalog_db" {
engine = "mysql"
engine_version = "8.0"
instance_class = var.db_instance_class
db_name = "catalogdb"
username = var.db_username
password = var.db_password
skip_final_snapshot = true
tags = { Name = "catalog-db-${var.env}" }
}
# 4. 输出 - 供 Ansible 使用
output "app_server_ips" {
value = aws_instance.catalog_app[*].public_ip
}
output "db_endpoint" {
value = aws_db_instance.catalog_db.endpoint
}
环境晋级技巧: 通过
terraform workspace 管理 dev/staging/prod 环境,每个工作区拥有独立的 state 文件和变量值,避免资源冲突。
4.4 Ansible Playbook 配置与部署
在 Terraform 完成资源创建后,Ansible 接管剩余工作。以下 Playbook 演示了如何安装 Java 环境、部署应用包并修改数据库连接配置。
---
# deploy-catalog.yml - 服务目录平台应用部署
- name: 部署服务目录平台应用
hosts: catalog_servers
gather_facts: yes
vars:
app_version: "{{ lookup('env', 'APP_VERSION') | default('1.2.0', true) }}"
db_host: "{{ hostvars['localhost']['db_endpoint'] }}"
tasks:
- name: 安装 JDK 11
yum:
name: java-11-openjdk-devel
state: present
- name: 创建应用目录
file:
path: /opt/catalog
state: directory
mode: '0755'
- name: 从制品库下载应用包
get_url:
url: "http://artifactory.example.com/catalog/{{ app_version }}/catalog.war"
dest: /opt/catalog/catalog.war
checksum: "sha256:{{ lookup('url', 'http://artifactory.example.com/catalog/{{ app_version }}/catalog.war.sha256') }}"
- name: 注入数据库连接配置
template:
src: application-prod.properties.j2
dest: /opt/catalog/application-prod.properties
notify: restart catalog service
- name: 启动服务目录平台
systemd:
name: catalog
state: started
enabled: yes
handlers:
- name: restart catalog service
systemd:
name: catalog
state: restarted
4.5 一键部署执行流程
将上述两个工具串联后,运维人员只需执行一条命令即可完成全流程部署。下表列出了标准执行步骤与关键检查点:
| 步骤 | 命令/操作 | 关键检查点 |
|---|---|---|
| 1. 初始化 Terraform | terraform init |
后端存储连接正常,Provider 版本锁定 |
| 2. 预览基础设施变更 | terraform plan -out=tfplan |
确认资源增删改与预期一致 |
| 3. 应用基础设施 | terraform apply tfplan |
资源创建成功,Output 输出 IP 与连接串 |
| 4. 生成 Ansible Inventory | terraform output -json | jq ... > inventory.json |
Inventory 包含正确的 IP 列表与变量 |
| 5. 执行 Ansible Playbook | ansible-playbook -i inventory.json deploy-catalog.yml |
所有 Task 显示 OK,无 Failed 任务 |
| 6. 健康检查 | curl http://<slb_dns>/catalog/health |
返回 HTTP 200 及 JSON 状态 |
常见陷阱: Terraform state 文件必须远程存储(如 S3 + DynamoDB 锁),避免多人操作时 state 冲突导致资源被意外删除。Ansible Playbook 应始终使用
--check 模式在预发环境验证后再执行生产部署。
4.6 环境晋级差异化配置
不同环境(开发、测试、预发、生产)在资源规格、副本数、数据库密码等方面存在差异。通过 Terraform 变量文件与 Ansible 的 Group Vars 实现环境隔离:
4.7 幂等性与故障回滚
自动化部署的核心要求是幂等性——无论执行多少次,结果一致。Terraform 通过 state 文件确保资源状态收敛;Ansible 通过模块的幂等设计(如 yum、template、systemd)保证重复执行不产生副作用。
- Terraform 回滚: 执行
terraform destroy销毁当前环境资源,或通过terraform apply恢复上一个 state 版本。 - Ansible 回滚: 在 Playbook 中定义
rollback标签,通过--tags rollback触发回滚操作,如替换旧版本包、恢复配置文件。 - 版本控制: 所有 Terraform 配置、Ansible Playbook 和变量文件均纳入 Git 仓库,每次部署对应一个 Git Commit,支持快速回溯。
生产级建议: 在 CI/CD 流水线中集成
terraform plan 与 ansible-playbook --syntax-check 作为门禁,只有通过静态检查的代码才能进入部署阶段。同时,为每个环境保留最近 5 次部署的 state 备份,用于紧急恢复。