引言
在現(xiàn)代云原生時(shí)代,基礎(chǔ)設(shè)施即代碼(Infrastructure as Code,IaC)已成為運(yùn)維工程師的核心技能。面對(duì)復(fù)雜的多云環(huán)境和日益增長(zhǎng)的基礎(chǔ)設(shè)施需求,傳統(tǒng)的手動(dòng)配置方式已無法滿足快速、可靠、可重復(fù)的部署要求。本文將深入探討 Terraform 和 Ansible 這兩大運(yùn)維利器的核心差異,明確它們?cè)谂渲霉芾砗唾Y源編排領(lǐng)域的分工邊界,為運(yùn)維工程師提供清晰的技術(shù)選型指導(dǎo)。
Terraform 基礎(chǔ)介紹
Terraform 是 HashiCorp 公司開發(fā)的一款開源基礎(chǔ)設(shè)施即代碼工具,采用聲明式語法,通過 HCL(HashiCorp Configuration Language)語言描述基礎(chǔ)設(shè)施資源。它的核心優(yōu)勢(shì)在于跨云平臺(tái)的資源編排能力,支持 AWS、Azure、Google Cloud、阿里云等主流云服務(wù)商。
Terraform 的核心特性
1. 聲明式語法
Terraform 使用聲明式語法,用戶只需描述最終狀態(tài),而非實(shí)現(xiàn)過程。這種方式使得基礎(chǔ)設(shè)施配置更加直觀和易于維護(hù)。
2. 狀態(tài)管理
Terraform 通過狀態(tài)文件(terraform.tfstate)追蹤基礎(chǔ)設(shè)施資源的當(dāng)前狀態(tài),確保實(shí)際環(huán)境與配置文件的一致性。
3. 計(jì)劃與應(yīng)用
在實(shí)際部署前,Terraform 會(huì)生成執(zhí)行計(jì)劃,展示將要進(jìn)行的變更,提供了安全的變更預(yù)覽機(jī)制。
Ansible 與 Terraform 的分工邊界
技術(shù)定位差異
Terraform:資源編排專家
? 專注于基礎(chǔ)設(shè)施資源的創(chuàng)建、修改和刪除
? 管理云服務(wù)商的各種資源:虛擬機(jī)、網(wǎng)絡(luò)、存儲(chǔ)、數(shù)據(jù)庫等
? 維護(hù)資源間的依賴關(guān)系和生命周期
Ansible:配置管理專家
? 專注于服務(wù)器內(nèi)部的配置管理
? 軟件安裝、配置文件管理、服務(wù)啟動(dòng)等
? 應(yīng)用程序部署和運(yùn)行時(shí)配置
工作流程對(duì)比
典型的云基礎(chǔ)設(shè)施部署流程中,兩者的協(xié)作模式如下:
1.Terraform 階段:創(chuàng)建云資源(VPC、子網(wǎng)、安全組、EC2實(shí)例等)
2.Ansible 階段:配置服務(wù)器(安裝軟件、部署應(yīng)用、配置服務(wù)等)
配置管理 vs 資源編排
資源編排(Infrastructure Orchestration)
資源編排關(guān)注的是基礎(chǔ)設(shè)施資源的生命周期管理,包括:
? 資源創(chuàng)建的順序和依賴關(guān)系
? 資源屬性的定義和修改
? 資源的銷毀和回收
? 跨云平臺(tái)的資源統(tǒng)一管理
配置管理(Configuration Management)
配置管理專注于系統(tǒng)內(nèi)部的狀態(tài)管理,包括:
? 操作系統(tǒng)級(jí)別的配置
? 應(yīng)用程序的安裝和配置
? 服務(wù)的啟動(dòng)和運(yùn)行狀態(tài)管理
? 配置文件的模板化和動(dòng)態(tài)生成
實(shí)際應(yīng)用案例
案例一:使用 Terraform 創(chuàng)建 AWS 基礎(chǔ)設(shè)施
# main.tf - AWS 基礎(chǔ)設(shè)施資源編排 # 定義 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 部署區(qū)域" type = string default = "us-west-2" } variable "environment" { description = "環(huán)境標(biāo)識(shí)" type = string default = "production" } # 創(chuàng)建 VPC 網(wǎng)絡(luò) 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 } } # 創(chuàng)建公共子網(wǎng) 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] # 公共子網(wǎng)自動(dòng)分配公網(wǎng)IP map_public_ip_on_launch = true tags = { Name = "${var.environment}-public-subnet-${count.index + 1}" Type = "public" } } # 創(chuàng)建私有子網(wǎng) 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" } } # 獲取可用區(qū)信息 data "aws_availability_zones" "available" { state = "available" } # 創(chuàng)建互聯(lián)網(wǎng)網(wǎng)關(guān) resource "aws_internet_gateway" "main" { vpc_id = aws_vpc.main.id tags = { Name = "${var.environment}-igw" } } # 創(chuàng)建路由表 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" } } # 關(guān)聯(lián)公共子網(wǎng)到路由表 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 } # 創(chuàng)建安全組 resource "aws_security_group" "web" { name = "${var.environment}-web-sg" description = "Web 服務(wù)器安全組" 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" } } # 創(chuàng)建密鑰對(duì) resource "aws_key_pair" "main" { key_name = "${var.environment}-key" public_key = file("~/.ssh/id_rsa.pub") } # 創(chuàng)建 EC2 實(shí)例 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 # 實(shí)例啟動(dòng)時(shí)執(zhí)行的腳本 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"] ? } } # 輸出關(guān)鍵信息 output "vpc_id" { ? description = "VPC ID" ? value ? ? ? = aws_vpc.main.id } output "public_subnet_ids" { ? description = "公共子網(wǎng) ID 列表" ? value ? ? ? = aws_subnet.public[*].id } output "web_server_ips" { ? description = "Web 服務(wù)器公網(wǎng) IP" ? value ? ? ? = aws_instance.web[*].public_ip }
案例二:使用 Ansible 進(jìn)行服務(wù)器配置管理
# nginx-playbook.yml - Nginx 配置管理 --- -name:配置NginxWeb服務(wù)器 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] # 創(chuàng)建網(wǎng)站目錄 -name:創(chuàng)建網(wǎng)站根目錄 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] # 配置虛擬主機(jī) -name:配置默認(rèn)虛擬主機(jī) template: src:default.conf.j2 dest:/etc/nginx/sites-available/default owner:root group:root mode:'0644' backup:yes notify:reloadnginx tags:[config] # 創(chuàng)建自定義網(wǎng)頁 -name:創(chuàng)建自定義首頁 template: src:index.html.j2 dest:/var/www/html/index.html owner:"{{ nginx_user }}" group:"{{ nginx_user }}" mode:'0644' tags:[content] # 啟動(dòng)并啟用 Nginx 服務(wù) -name:啟動(dòng)并啟用Nginx服務(wù) systemd: name:nginx state:started enabled:yes tags:[service] # 配置防火墻規(guī)則 -name:配置UFW防火墻規(guī)則 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 服務(wù) -name:restartnginx systemd: name:nginx state:restarted # 重新加載 Nginx 配置 -name:reloadnginx systemd: name:nginx state:reloaded
{# templates/nginx.conf.j2 - Nginx 主配置模板 #} # Nginx 主配置文件 # 由 Ansible 自動(dòng)生成,請(qǐng)勿手動(dòng)修改 user {{ nginx_user }}; worker_processes {{ nginx_worker_processes }}; pid /run/nginx.pid; events { worker_connections {{ nginx_worker_connections }}; use epoll; multi_accept on; } http { # 基礎(chǔ)設(shè)置 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; # 包含虛擬主機(jī)配置 include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; }
案例三:集成 Terraform 和 Ansible 的自動(dòng)化部署
# inventory/hosts.yml - 動(dòng)態(tài)主機(jī)清單 --- all: children: web_servers: hosts: # 這些IP將從 Terraform 輸出中動(dòng)態(tài)獲取 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 的自動(dòng)化部署流程 set-e # 顏色定義 RED='?33[0;31m' GREEN='?33[0;32m' YELLOW='?33[1;33m' NC='?33[0m'# No Color # 日志函數(shù) 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 基礎(chǔ)設(shè)施部署..." # 初始化 Terraform terraform init # 生成執(zhí)行計(jì)劃 terraform plan -out=tfplan # 應(yīng)用配置 terraform apply tfplan # 獲取輸出信息 terraform output -json > terraform_outputs.json log_info"Terraform 部署完成" } # 等待實(shí)例就緒 wait_for_instances() { log_info"等待 EC2 實(shí)例就緒..." # 從 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響應(yīng)..." sleep10 done log_info"$ip已就緒" done } # Ansible 配置 ansible_configure() { log_info"開始 Ansible 配置管理..." # 生成動(dòng)態(tài)主機(jī)清單 python3 generate_inventory.py # 測(cè)試連接 ansible all -i inventory/hosts.yml -m ping # 執(zhí)行配置 ansible-playbook -i inventory/hosts.yml nginx-playbook.yml log_info"Ansible 配置完成" } # 驗(yàn)證部署 verify_deployment() { log_info"驗(yàn)證部署結(jié)果..." IPS=$(terraform output -json | jq -r'.web_server_ips.value[]') foripin$IPS;do log_info"測(cè)試$ip的 Web 服務(wù)..." ifcurl -s -o /dev/null -w"%{http_code}"http://$ip| grep -q"200";then log_info"$ipWeb 服務(wù)正常" else log_error"$ipWeb 服務(wù)異常" fi done } # 主函數(shù) main() { log_info"開始自動(dòng)化部署流程..." 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"資源清理完成" } # 參數(shù)處理 case"${1:-deploy}"in "deploy") main ;; "cleanup") cleanup ;; *) echo"使用方法:$0[deploy|cleanup]" exit1 ;; esac
最佳實(shí)踐與建議
1. 技術(shù)選型原則
使用 Terraform 的場(chǎng)景:
? 需要?jiǎng)?chuàng)建和管理云資源
? 跨云平臺(tái)的資源編排
? 基礎(chǔ)設(shè)施版本控制和協(xié)作
? 資源依賴關(guān)系復(fù)雜的場(chǎng)景
使用 Ansible 的場(chǎng)景:
? 服務(wù)器配置管理
? 應(yīng)用程序部署
? 運(yùn)行時(shí)配置更新
? 批量運(yùn)維操作
2. 協(xié)作模式
串行協(xié)作模式:先用 Terraform 創(chuàng)建基礎(chǔ)設(shè)施,再用 Ansible 配置服務(wù)器。這是最常見的模式,適用于大多數(shù)場(chǎng)景。
并行協(xié)作模式:在某些場(chǎng)景下,可以同時(shí)使用兩個(gè)工具管理不同層面的資源,但需要做好狀態(tài)同步。
3. 狀態(tài)管理
Terraform 狀態(tài)管理:
? 使用遠(yuǎn)程狀態(tài)存儲(chǔ)(如 S3、Azure Blob)
? 啟用狀態(tài)鎖定機(jī)制
? 定期備份狀態(tài)文件
Ansible 狀態(tài)管理:
? 使用冪等性任務(wù)設(shè)計(jì)
? 合理使用 handlers 和 tags
? 建立回滾機(jī)制
4. 安全考慮
憑證管理:
? 使用 IAM 角色而非硬編碼密鑰
? 利用 HashiCorp Vault 或 AWS Secrets Manager
? 實(shí)施最小權(quán)限原則
網(wǎng)絡(luò)安全:
? 合理配置安全組規(guī)則
? 使用 VPN 或堡壘機(jī)訪問內(nèi)網(wǎng)資源
? 啟用日志審計(jì)
總結(jié)
Terraform 和 Ansible 在現(xiàn)代運(yùn)維體系中扮演著不同但互補(bǔ)的角色。Terraform 專注于基礎(chǔ)設(shè)施資源的聲明式編排,提供了強(qiáng)大的跨云平臺(tái)能力和狀態(tài)管理機(jī)制;Ansible 則專注于配置管理和應(yīng)用部署,提供了靈活的任務(wù)執(zhí)行和豐富的模塊生態(tài)。
理解兩者的分工邊界,合理地將資源編排和配置管理分離,能夠構(gòu)建更加健壯、可維護(hù)的基礎(chǔ)設(shè)施自動(dòng)化體系。在實(shí)際應(yīng)用中,建議采用 Terraform 負(fù)責(zé)基礎(chǔ)設(shè)施層面的資源管理,Ansible 負(fù)責(zé)應(yīng)用層面的配置管理,通過標(biāo)準(zhǔn)化的接口和流程實(shí)現(xiàn)兩者的無縫協(xié)作。
隨著云原生技術(shù)的發(fā)展,運(yùn)維工程師需要不斷學(xué)習(xí)和實(shí)踐這些工具,構(gòu)建適合自己組織需求的自動(dòng)化運(yùn)維體系。通過合理的技術(shù)選型和最佳實(shí)踐,能夠顯著提升運(yùn)維效率,降低運(yùn)維風(fēng)險(xiǎn),為業(yè)務(wù)發(fā)展提供堅(jiān)實(shí)的基礎(chǔ)設(shè)施保障。
-
開源
+關(guān)注
關(guān)注
3文章
3690瀏覽量
43840 -
代碼
+關(guān)注
關(guān)注
30文章
4900瀏覽量
70772 -
Azure
+關(guān)注
關(guān)注
1文章
127瀏覽量
13322 -
云原生
+關(guān)注
關(guān)注
0文章
261瀏覽量
8278
原文標(biāo)題:一文搞定IaC核心技術(shù)棧:Terraform+Ansible讓運(yùn)維效率提升300%
文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
誠(chéng)聘高級(jí)運(yùn)維自動(dòng)化工程師
【深圳】誠(chéng)聘運(yùn)維開發(fā)工程師
ansible-first-book 自動(dòng)化運(yùn)維工具
配電自動(dòng)化實(shí)用化運(yùn)維指標(biāo)研究
厲害了!山東電力運(yùn)維自動(dòng)化平臺(tái)正式投運(yùn)
如何區(qū)分Puppet,Ansible,Saltstack的作用特點(diǎn)?
Ansible企業(yè)級(jí)自動(dòng)化運(yùn)維探索的詳細(xì)資料說明

一文詳解Ansible的自動(dòng)化運(yùn)維

城域網(wǎng)是什么,其生命周期和自動(dòng)化運(yùn)維應(yīng)用有哪些特點(diǎn)
使用Ansible的OpenStack自動(dòng)化

什么是Ansible
為什么需要用Ansible管理crontab呢?
利用Ansible批量100臺(tái)服務(wù)器添加Crontab
網(wǎng)絡(luò)設(shè)備自動(dòng)化運(yùn)維工具—ansible入門筆記介紹

評(píng)論