Terraform 核心概念
深入理解 Terraform 的核心概念,是掌握 IaC 的关键。
一、Providers(提供者)
1.1 Provider 是什么
Provider 是 Terraform 与云平台、SaaS 服务交互的插件。
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.0"
}
}
}
provider "aws" {
region = "us-west-2"
}
provider "azurerm" {
features {}
}
1.2 常用 Providers
| Provider | 用途 | 资源数量 |
|---|---|---|
| AWS | Amazon Web Services | 1000+ |
| Azure | Microsoft Azure | 800+ |
| Google Cloud Platform | 500+ | |
| Kubernetes | K8s 集群管理 | 200+ |
| Docker | 容器管理 | 20+ |
| GitHub | 代码仓库管理 | 50+ |
1.3 Provider 配置
# AWS Provider 配置
provider "aws" {
region = var.aws_region
access_key = var.aws_access_key
secret_key = var.aws_secret_key
# 默认标签
default_tags {
tags = {
Environment = "Production"
ManagedBy = "Terraform"
}
}
}
# 多区域配置
provider "aws" {
alias = "us-east"
region = "us-east-1"
}
provider "aws" {
alias = "us-west"
region = "us-west-2"
}
二、Resources(资源)
2.1 资源定义
资源是 Terraform 管理的基础设施对象。
resource "aws_instance" "web_server" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "WebServer"
}
}
resource "aws_s3_bucket" "data" {
bucket = "my-app-data-${random_id.bucket_id.hex}"
tags = {
Name = "DataBucket"
}
}
2.2 资源依赖
# 隐式依赖(通过引用)
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id # 隐式依赖
cidr_block = "10.0.1.0/24"
}
# 显式依赖
resource "aws_instance" "app" {
ami = "ami-xxx"
instance_type = "t2.micro"
depends_on = [
aws_db_instance.database
]
}
2.3 资源生命周期
resource "aws_instance" "example" {
ami = "ami-xxx"
instance_type = "t2.micro"
lifecycle {
create_before_destroy = true # 先创建新资源
prevent_destroy = false # 允许删除
ignore_changes = [ # 忽略这些字段的变化
tags,
user_data,
]
}
}
三、Variables(变量)
3.1 输入变量
# variables.tf
variable "instance_type" {
description = "EC2 实例类型"
type = string
default = "t2.micro"
}
variable "availability_zones" {
description = "可用区列表"
type = list(string)
default = ["us-west-2a", "us-west-2b"]
}
variable "environment" {
description = "环境名称"
type = string
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "环境必须是 dev、staging 或 prod。"
}
}
3.2 使用变量
resource "aws_instance" "app" {
ami = "ami-xxx"
instance_type = var.instance_type
tags = {
Environment = var.environment
}
}
3.3 变量传递方式
# 1. 命令行
terraform apply -var="instance_type=t2.small"
# 2. 变量文件
terraform apply -var-file="prod.tfvars"
# 3. 环境变量
export TF_VAR_instance_type=t2.small
terraform apply
# 4. 自动加载的 .tfvars 文件
# terraform.tfvars 或 *.auto.tfvars
prod.tfvars 示例:
instance_type = "t2.large"
availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]
environment = "prod"
四、Outputs(输出)
4.1 定义输出
# outputs.tf
output "instance_public_ip" {
description = "EC2 实例的公网 IP"
value = aws_instance.app.public_ip
}
output "database_endpoint" {
description = "数据库连接端点"
value = aws_db_instance.main.endpoint
sensitive = true # 标记为敏感信息
}
output "vpc_details" {
description = "VPC 详细信息"
value = {
id = aws_vpc.main.id
cidr_block = aws_vpc.main.cidr_block
region = var.aws_region
}
}
4.2 查看输出
# 查看所有输出
terraform output
# 查看特定输出
terraform output instance_public_ip
# JSON 格式输出
terraform output -json
4.3 输出用途
# 模块间传递数据
module "vpc" {
source = "./modules/vpc"
}
module "app" {
source = "./modules/app"
vpc_id = module.vpc.vpc_id # 使用其他模块的输出
}
五、Data Sources(数据源)
5.1 读取现有资源
# 查询最新的 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-*"]
}
}
# 使用数据源
resource "aws_instance" "app" {
ami = data.aws_ami.ubuntu.id
instance_type = "t2.micro"
}
5.2 常用数据源
# 获取当前账户信息
data "aws_caller_identity" "current" {}
output "account_id" {
value = data.aws_caller_identity.current.account_id
}
# 获取可用区
data "aws_availability_zones" "available" {
state = "available"
}
# 获取现有 VPC
data "aws_vpc" "existing" {
filter {
name = "tag:Name"
values = ["Production-VPC"]
}
}
六、State(状态)
6.1 状态文件
Terraform 使用状态文件追踪资源的实际状态。
# 状态文件位置
./terraform.tfstate # 本地状态
./terraform.tfstate.backup # 备份
6.2 远程状态
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "prod/terraform.tfstate"
region = "us-west-2"
encrypt = true
dynamodb_table = "terraform-locks"
}
}
6.3 状态管理命令
# 查看状态
terraform state list
terraform state show aws_instance.app
# 移动资源
terraform state mv aws_instance.old aws_instance.new
# 删除资源(仅从状态中删除)
terraform state rm aws_instance.temp
# 导入现有资源
terraform import aws_instance.app i-1234567890abcdef0
七、Modules(模块)
7.1 模块结构
modules/
├── vpc/
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
└── app/
├── main.tf
├── variables.tf
└── outputs.tf
7.2 使用模块
module "vpc" {
source = "./modules/vpc"
cidr_block = "10.0.0.0/16"
environment = "production"
}
module "app" {
source = "./modules/app"
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnet_ids
}
7.3 公共模块
# 使用 Terraform Registry 的模块
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.0.0"
name = "my-vpc"
cidr = "10.0.0.0/16"
azs = ["us-west-2a", "us-west-2b"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24"]
}
八、核心概念关系图
┌─────────────────────────────────────────────┐
│ Terraform 配置文件 │
├─────────────────────────────────────────────┤
│ Providers ←──→ Resources │
│ ↓ ↓ │
│ Variables Data Sources │
│ ↓ ↓ │
│ Modules ←────→ State │
│ ↓ │
│ Outputs │
└─────────────────────────────────────────────┘
九、最佳实践
9.1 文件组织
project/
├── main.tf # 主要资源定义
├── variables.tf # 输入变量
├── outputs.tf # 输出值
├── versions.tf # Provider 版本约束
├── terraform.tfvars # 变量值(不提交到 Git)
└── modules/ # 自定义模块
9.2 命名规范
# 使用下划线分隔,描述性命名
resource "aws_instance" "web_server" {}
variable "vpc_cidr_block" {}
output "instance_public_ip" {}
# 避免
resource "aws_instance" "ws" {} # ❌ 太简短
variable "x" {} # ❌ 无意义
9.3 代码复用
# 使用 locals 减少重复
locals {
common_tags = {
Environment = var.environment
ManagedBy = "Terraform"
Project = "MyApp"
}
}
resource "aws_instance" "app" {
# ...
tags = merge(
local.common_tags,
{
Name = "AppServer"
}
)
}
小结
理解这些核心概念是使用 Terraform 的基础:
- Providers: 连接云平台的桥梁
- Resources: 需要管理的基础设施
- Variables: 使配置灵活可复用
- Outputs: 导出重要信息
- Data Sources: 读取现有资源
- State: 追踪资源实际状态
- Modules: 组织和复用代码
下一章我们将学习 Terraform 的工作流程和常用命令。