引言
在现代云原生时代,基础设施即代码(Infrastructure as Code,IaC)已成为运维工程师的核心技能。面对复杂的多云环境和日益增长的基础设施需求,传统的手动配置方式已无法满足快速、可靠、可重复的部署要求。本文将深入探讨 Terraform 和 Ansible 这两大运维利器的核心差异,明确它们在配置管理和资源编排领域的分工边界,为运维工程师提供清晰的技术选型指导。
Terraform 基础介绍
Terraform 是 HashiCorp 公司开发的一款开源基础设施即代码工具,采用声明式语法,通过 HCL(HashiCorp Configuration Language)语言描述基础设施资源。它的核心优势在于跨云平台的资源编排能力,支持 AWS、Azure、Google Cloud、阿里云等主流云服务商。
Terraform 的核心特性
1. 声明式语法
Terraform 使用声明式语法,用户只需描述最终状态,而非实现过程。这种方式使得基础设施配置更加直观和易于维护。
2. 状态管理
Terraform 通过状态文件(terraform.tfstate)追踪基础设施资源的当前状态,确保实际环境与配置文件的一致性。
3. 计划与应用
在实际部署前,Terraform 会生成执行计划,展示将要进行的变更,提供了安全的变更预览机制。
Ansible 与 Terraform 的分工边界
技术定位差异
Terraform:资源编排专家
? 专注于基础设施资源的创建、修改和删除
? 管理云服务商的各种资源:虚拟机、网络、存储、数据库等
? 维护资源间的依赖关系和生命周期
Ansible:配置管理专家
? 专注于服务器内部的配置管理
? 软件安装、配置文件管理、服务启动等
? 应用程序部署和运行时配置
工作流程对比
典型的云基础设施部署流程中,两者的协作模式如下:
1.Terraform 阶段:创建云资源(VPC、子网、安全组、EC2实例等)
2.Ansible 阶段:配置服务器(安装软件、部署应用、配置服务等)
配置管理 vs 资源编排
资源编排(Infrastructure Orchestration)
资源编排关注的是基础设施资源的生命周期管理,包括:
? 资源创建的顺序和依赖关系
? 资源属性的定义和修改
? 资源的销毁和回收
? 跨云平台的资源统一管理
配置管理(Configuration Management)
配置管理专注于系统内部的状态管理,包括:
? 操作系统级别的配置
? 应用程序的安装和配置
? 服务的启动和运行状态管理
? 配置文件的模板化和动态生成
实际应用案例
案例一:使用 Terraform 创建 AWS 基础设施
# main.tf - AWS 基础设施资源编排 # 定义 Terraform 提供商和版本要求 terraform { required_version = ">= 1.0" required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } } } # 配置 AWS 提供商 provider "aws" { region = var.aws_region } # 定义变量 variable "aws_region" { description = "AWS 部署区域" type = string default = "us-west-2" } variable "environment" { description = "环境标识" type = string default = "production" } # 创建 VPC 网络 resource "aws_vpc" "main" { cidr_block = "10.0.0.0/16" enable_dns_hostnames = true enable_dns_support = true tags = { Name = "${var.environment}-vpc" Environment = var.environment } } # 创建公共子网 resource "aws_subnet" "public" { count = 2 vpc_id = aws_vpc.main.id cidr_block = "10.0.${count.index + 1}.0/24" availability_zone = data.aws_availability_zones.available.names[count.index] # 公共子网自动分配公网IP map_public_ip_on_launch = true tags = { Name = "${var.environment}-public-subnet-${count.index + 1}" Type = "public" } } # 创建私有子网 resource "aws_subnet" "private" { count = 2 vpc_id = aws_vpc.main.id cidr_block = "10.0.${count.index + 10}.0/24" availability_zone = data.aws_availability_zones.available.names[count.index] tags = { Name = "${var.environment}-private-subnet-${count.index + 1}" Type = "private" } } # 获取可用区信息 data "aws_availability_zones" "available" { state = "available" } # 创建互联网网关 resource "aws_internet_gateway" "main" { vpc_id = aws_vpc.main.id tags = { Name = "${var.environment}-igw" } } # 创建路由表 resource "aws_route_table" "public" { vpc_id = aws_vpc.main.id route { cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.main.id } tags = { Name = "${var.environment}-public-rt" } } # 关联公共子网到路由表 resource "aws_route_table_association" "public" { count = length(aws_subnet.public) subnet_id = aws_subnet.public[count.index].id route_table_id = aws_route_table.public.id } # 创建安全组 resource "aws_security_group" "web" { name = "${var.environment}-web-sg" description = "Web 服务器安全组" vpc_id = aws_vpc.main.id # 允许 HTTP 入站流量 ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } # 允许 HTTPS 入站流量 ingress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } # 允许 SSH 入站流量 ingress { from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } # 允许所有出站流量 egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "${var.environment}-web-sg" } } # 创建密钥对 resource "aws_key_pair" "main" { key_name = "${var.environment}-key" public_key = file("~/.ssh/id_rsa.pub") } # 创建 EC2 实例 resource "aws_instance" "web" { count = 2 ami = data.aws_ami.ubuntu.id instance_type = "t3.micro" key_name = aws_key_pair.main.key_name vpc_security_group_ids = [aws_security_group.web.id] subnet_id = aws_subnet.public[count.index].id # 实例启动时执行的脚本 user_data = <<-EOF ? ? #!/bin/bash ? ? apt-get update ? ? apt-get install -y python3 python3-pip ? ? pip3 install ansible ? EOF ? tags = { ? ? Name = "${var.environment}-web-${count.index + 1}" ? ? Role = "web-server" ? } } # 获取 Ubuntu AMI 信息 data "aws_ami" "ubuntu" { ? most_recent = true ? owners ? ? ?= ["099720109477"] # Canonical ? filter { ? ? name ? = "name" ? ? values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"] ? } ? filter { ? ? name ? = "virtualization-type" ? ? values = ["hvm"] ? } } # 输出关键信息 output "vpc_id" { ? description = "VPC ID" ? value ? ? ? = aws_vpc.main.id } output "public_subnet_ids" { ? description = "公共子网 ID 列表" ? value ? ? ? = aws_subnet.public[*].id } output "web_server_ips" { ? description = "Web 服务器公网 IP" ? value ? ? ? = aws_instance.web[*].public_ip }
案例二:使用 Ansible 进行服务器配置管理
# nginx-playbook.yml - Nginx 配置管理 --- -name:配置NginxWeb服务器 hosts:web_servers become:yes gather_facts:yes vars: nginx_user:"www-data" nginx_worker_processes:"auto" nginx_worker_connections:1024 nginx_keepalive_timeout:65 nginx_server_name:"{{ ansible_default_ipv4.address }}" tasks: # 更新软件包缓存 -name:更新apt软件包缓存 apt: update_cache:yes cache_valid_time:3600 tags:[packages] # 安装 Nginx -name:安装Nginx apt: name:nginx state:present notify:restartnginx tags:[packages] # 创建网站目录 -name:创建网站根目录 file: path:/var/www/html state:directory owner:"{{ nginx_user }}" group:"{{ nginx_user }}" mode:'0755' tags:[directories] # 配置 Nginx 主配置文件 -name:配置Nginx主配置文件 template: src:nginx.conf.j2 dest:/etc/nginx/nginx.conf owner:root group:root mode:'0644' backup:yes notify:reloadnginx tags:[config] # 配置虚拟主机 -name:配置默认虚拟主机 template: src:default.conf.j2 dest:/etc/nginx/sites-available/default owner:root group:root mode:'0644' backup:yes notify:reloadnginx tags:[config] # 创建自定义网页 -name:创建自定义首页 template: src:index.html.j2 dest:/var/www/html/index.html owner:"{{ nginx_user }}" group:"{{ nginx_user }}" mode:'0644' tags:[content] # 启动并启用 Nginx 服务 -name:启动并启用Nginx服务 systemd: name:nginx state:started enabled:yes tags:[service] # 配置防火墙规则 -name:配置UFW防火墙规则 ufw: rule:allow port:"{{ item }}" proto:tcp loop: -'80' -'443' tags:[firewall] # 安装 SSL 证书工具 -name:安装Certbot apt: name: -certbot -python3-certbot-nginx state:present tags:[ssl] handlers: # 重启 Nginx 服务 -name:restartnginx systemd: name:nginx state:restarted # 重新加载 Nginx 配置 -name:reloadnginx systemd: name:nginx state:reloaded
{# templates/nginx.conf.j2 - Nginx 主配置模板 #} # Nginx 主配置文件 # 由 Ansible 自动生成,请勿手动修改 user {{ nginx_user }}; worker_processes {{ nginx_worker_processes }}; pid /run/nginx.pid; events { worker_connections {{ nginx_worker_connections }}; use epoll; multi_accept on; } http { # 基础设置 sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout {{ nginx_keepalive_timeout }}; types_hash_max_size 2048; server_tokens off; # MIME 类型 include /etc/nginx/mime.types; default_type application/octet-stream; # 日志格式 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; # 访问日志 access_log /var/log/nginx/access.log main; error_log /var/log/nginx/error.log; # Gzip 压缩 gzip on; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss application/atom+xml image/svg+xml; # 包含虚拟主机配置 include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; }
案例三:集成 Terraform 和 Ansible 的自动化部署
# inventory/hosts.yml - 动态主机清单 --- all: children: web_servers: hosts: # 这些IP将从 Terraform 输出中动态获取 web-1: ansible_host:"{{ terraform_outputs.web_server_ips[0] }}" web-2: ansible_host:"{{ terraform_outputs.web_server_ips[1] }}" vars: ansible_user:ubuntu ansible_ssh_private_key_file:~/.ssh/id_rsa ansible_ssh_common_args:'-o StrictHostKeyChecking=no'
#!/bin/bash # deploy.sh - 完整部署脚本 # 集成 Terraform 和 Ansible 的自动化部署流程 set-e # 颜色定义 RED='?33[0;31m' GREEN='?33[0;32m' YELLOW='?33[1;33m' NC='?33[0m'# No Color # 日志函数 log_info() { echo-e"${GREEN}[INFO]${NC}$1" } log_warn() { echo-e"${YELLOW}[WARN]${NC}$1" } log_error() { echo-e"${RED}[ERROR]${NC}$1" } # 检查依赖工具 check_dependencies() { log_info"检查依赖工具..." if!command-v terraform &> /dev/null;then log_error"Terraform 未安装" exit1 fi if!command-v ansible &> /dev/null;then log_error"Ansible 未安装" exit1 fi log_info"依赖工具检查完成" } # Terraform 部署 terraform_deploy() { log_info"开始 Terraform 基础设施部署..." # 初始化 Terraform terraform init # 生成执行计划 terraform plan -out=tfplan # 应用配置 terraform apply tfplan # 获取输出信息 terraform output -json > terraform_outputs.json log_info"Terraform 部署完成" } # 等待实例就绪 wait_for_instances() { log_info"等待 EC2 实例就绪..." # 从 Terraform 输出获取 IP 地址 IPS=$(terraform output -json | jq -r'.web_server_ips.value[]') foripin$IPS;do log_info"等待$ip就绪..." while! ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no ubuntu@$ip'echo "ready"'&>/dev/null;do log_warn"等待$ip响应..." sleep10 done log_info"$ip已就绪" done } # Ansible 配置 ansible_configure() { log_info"开始 Ansible 配置管理..." # 生成动态主机清单 python3 generate_inventory.py # 测试连接 ansible all -i inventory/hosts.yml -m ping # 执行配置 ansible-playbook -i inventory/hosts.yml nginx-playbook.yml log_info"Ansible 配置完成" } # 验证部署 verify_deployment() { log_info"验证部署结果..." IPS=$(terraform output -json | jq -r'.web_server_ips.value[]') foripin$IPS;do log_info"测试$ip的 Web 服务..." ifcurl -s -o /dev/null -w"%{http_code}"http://$ip| grep -q"200";then log_info"$ipWeb 服务正常" else log_error"$ipWeb 服务异常" fi done } # 主函数 main() { log_info"开始自动化部署流程..." check_dependencies terraform_deploy wait_for_instances ansible_configure verify_deployment log_info"部署完成!" log_info"访问地址:" terraform output web_server_ips } # 清理资源 cleanup() { log_warn"清理 Terraform 资源..." terraform destroy -auto-approve rm-f terraform_outputs.json rm-f tfplan log_info"资源清理完成" } # 参数处理 case"${1:-deploy}"in "deploy") main ;; "cleanup") cleanup ;; *) echo"使用方法:$0[deploy|cleanup]" exit1 ;; esac
最佳实践与建议
1. 技术选型原则
使用 Terraform 的场景:
? 需要创建和管理云资源
? 跨云平台的资源编排
? 基础设施版本控制和协作
? 资源依赖关系复杂的场景
使用 Ansible 的场景:
? 服务器配置管理
? 应用程序部署
? 运行时配置更新
? 批量运维操作
2. 协作模式
串行协作模式:先用 Terraform 创建基础设施,再用 Ansible 配置服务器。这是最常见的模式,适用于大多数场景。
并行协作模式:在某些场景下,可以同时使用两个工具管理不同层面的资源,但需要做好状态同步。
3. 状态管理
Terraform 状态管理:
? 使用远程状态存储(如 S3、Azure Blob)
? 启用状态锁定机制
? 定期备份状态文件
Ansible 状态管理:
? 使用幂等性任务设计
? 合理使用 handlers 和 tags
? 建立回滚机制
4. 安全考虑
凭证管理:
? 使用 IAM 角色而非硬编码密钥
? 利用 HashiCorp Vault 或 AWS Secrets Manager
? 实施最小权限原则
网络安全:
? 合理配置安全组规则
? 使用 VPN 或堡垒机访问内网资源
? 启用日志审计
总结
Terraform 和 Ansible 在现代运维体系中扮演着不同但互补的角色。Terraform 专注于基础设施资源的声明式编排,提供了强大的跨云平台能力和状态管理机制;Ansible 则专注于配置管理和应用部署,提供了灵活的任务执行和丰富的模块生态。
理解两者的分工边界,合理地将资源编排和配置管理分离,能够构建更加健壮、可维护的基础设施自动化体系。在实际应用中,建议采用 Terraform 负责基础设施层面的资源管理,Ansible 负责应用层面的配置管理,通过标准化的接口和流程实现两者的无缝协作。
随着云原生技术的发展,运维工程师需要不断学习和实践这些工具,构建适合自己组织需求的自动化运维体系。通过合理的技术选型和最佳实践,能够显著提升运维效率,降低运维风险,为业务发展提供坚实的基础设施保障。
-
开源
+关注
关注
3文章
3754浏览量
43981 -
代码
+关注
关注
30文章
4905浏览量
70988 -
Azure
+关注
关注
1文章
127浏览量
13352 -
云原生
+关注
关注
0文章
262浏览量
8295
原文标题:一文搞定IaC核心技术栈:Terraform+Ansible让运维效率提升300%
文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
【深圳】诚聘运维开发工程师
配电自动化实用化运维指标研究
如何区分Puppet,Ansible,Saltstack的作用特点?
Ansible企业级自动化运维探索的详细资料说明

一文详解Ansible的自动化运维

城域网是什么,其生命周期和自动化运维应用有哪些特点
使用Ansible的OpenStack自动化

评论