← 返回首页
🔧

Terraform入门:基础设施即代码

📂 devops ⏱ 3 min 462 words

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

最佳实践

  1. 模块化:将可复用资源打包为模块
  2. 环境隔离:使用独立的后端存储每个环境的状态
  3. 版本锁定:锁定Provider和Terraform版本
  4. 代码审查:对plan输出进行代码审查
  5. 状态备份:启用状态文件的版本控制和备份