Terraform入门:基础设施即代码
Terraform入门:基础设施即代码
什么是Terraform
Terraform是HashiCorp开发的开源基础设施即代码(IaC)工具,允许你使用声明式配置文件来定义、部署和管理云基础设施。它支持多云环境,通过状态管理实现基础设施的版本控制。
安装Terraform
Linux安装
# 下载安装
wget https://releases.hashicorp.com/terraform/1.6.0/terraform_1.6.0_linux_amd64.zip
unzip terraform_1.6.0_linux_amd64.zip
sudo mv terraform /usr/local/bin/
# 验证安装
terraform version
使用包管理器
# Ubuntu/Debian
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install terraform
# macOS
brew install terraform
基础语法
HCL配置文件
# main.tf - AWS EC2实例配置
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
required_version = ">= 1.0"
}
provider "aws" {
region = "us-west-2"
}
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "web-server"
Environment = "production"
}
vpc_security_group_ids = [aws_security_group.web.id]
subnet_id = aws_subnet.main.id
}
resource "aws_security_group" "web" {
name = "web-sg"
description = "Allow HTTP and SSH"
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
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"]
}
}
变量定义
# variables.tf
variable "region" {
description = "AWS区域"
type = string
default = "us-west-2"
}
variable "instance_type" {
description = "EC2实例类型"
type = string
default = "t2.micro"
validation {
condition = can(regex("^t[23]\\..*$", var.instance_type))
error_message = "实例类型必须是t2或t3系列"
}
}
variable "environment" {
description = "环境标识"
type = string
validation {
condition = contains(["dev", "staging", "production"], var.environment)
error_message = "环境必须是dev、staging或production"
}
}
variable "tags" {
description = "资源标签"
type = map(string)
default = {
ManagedBy = "terraform"
}
}
输出定义
# outputs.tf
output "instance_id" {
description = "EC2实例ID"
value = aws_instance.web.id
}
output "public_ip" {
description = "实例公网IP"
value = aws_instance.web.public_ip
}
output "public_dns" {
description = "实例公网DNS"
value = aws_instance.web.public_dns
}
核心命令
初始化
# 初始化工作目录,下载Provider插件
terraform init
# 从特定配置初始化
terraform init -from-module=module.example
# 使用特定后端配置
terraform init -backend-config=backend.hcl
格式化和验证
# 格式化配置文件
terraform fmt -recursive
# 验证配置语法
terraform validate
# 获取Provider插件
terraform providers
计划和应用
# 预览变更
terraform plan
# 应用变更
terraform apply
# 自动批准变更
terraform apply -auto-approve
# 销毁资源
terraform destroy
# 只销毁特定资源
terraform destroy -target=aws_instance.web
状态管理
# 查看状态
terraform state list
terraform state show aws_instance.web
# 移动资源
terraform state mv aws_instance.old aws_instance.new
# 移除资源(不销毁)
terraform state rm aws_instance.web
# 导入现有资源
terraform import aws_instance.web i-1234567890abcdef0
工作目录结构
project/
├── main.tf # 主配置文件
├── variables.tf # 变量定义
├── outputs.tf # 输出定义
├── providers.tf # Provider配置
├── versions.tf # 版本约束
├── terraform.tfvars # 变量值文件
├── backend.hcl # 后端配置
├── modules/ # 可复用模块
│ └── vpc/
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
└── environments/ # 环境配置
├── dev/
├── staging/
└── production/
远程状态存储
# 使用S3存储状态
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "prod/terraform.tfstate"
region = "us-west-2"
dynamodb_table = "terraform-locks"
encrypt = true
}
}
# 创建S3存储桶和锁表
aws s3 mb s3://my-terraform-state --region us-west-2
aws dynamodb create-table \
--table-name terraform-locks \
--attribute-definitions AttributeName=LockID,AttributeType=S \
--key-schema AttributeName=LockID,KeyType=HASH \
--billing-mode PAY_PER_REQUEST \
--region us-west-2
最佳实践
- 模块化:将可复用资源打包为模块
- 环境隔离:使用独立的后端存储每个环境的状态
- 版本锁定:锁定Provider和Terraform版本
- 代码审查:对plan输出进行代码审查
- 状态备份:启用状态文件的版本控制和备份