Terraform 基础设施即代码

2026-06-22 · 6 阅读 · 541字
CI/CDDocker

Terraform 基础设施即代码

概述

Terraform 是 HashiCorp 公司开发的开源基础设施即代码 (IaC) 工具,使用声明式语言 HCL 定义和预配基础设施。

核心优势

  • 多云管理:统一管理 AWS、Azure、GCP 等多云资源
  • 声明式配置:描述期望状态,Terraform 自动达成
  • 状态管理:跟踪资源状态,增量更新
  • 模块化:复用基础设施代码

安装与入门

# 安装 Terraform(Ubuntu)
wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /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

工作流

terraform init     → 初始化项目,下载 Provider
terraform plan     → 预览变更
terraform apply    → 执行变更
terraform destroy  → 销毁资源

HCL 语法基础

# 指定 Provider 和版本
terraform {
  required_version = ">= 1.6"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

# Provider 配置
provider "aws" {
  region = "ap-northeast-1"
}

# 资源定义
resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"

  tags = {
    Name = "web-server"
    Env  = "production"
  }
}

# 数据源:查询已有资源
data "aws_vpc" "default" {
  default = true
}

变量与输出

# variables.tf
variable "environment" {
  description = "部署环境"
  type        = string
  default     = "dev"
}

variable "instance_count" {
  type    = number
  default = 2
}

variable "tags" {
  type = map(string)
  default = {
    Project = "MyApp"
    Managed = "Terraform"
  }
}

# 使用变量
resource "aws_instance" "app" {
  count = var.instance_count
  tags  = var.tags
}

# outputs.tf
output "instance_ips" {
  description = "实例 IP 地址列表"
  value       = aws_instance.app[*].public_ip
}

output "vpc_id" {
  value = data.aws_vpc.default.id
}

状态管理

远程状态 (S3)

# backend.tf
terraform {
  backend "s3" {
    bucket = "my-terraform-state"
    key    = "production/terraform.tfstate"
    region = "ap-northeast-1"

    # 状态文件锁
    dynamodb_table = "terraform-locks"
  }
}

状态操作

# 查看当前状态
terraform state list
terraform state show aws_instance.web

# 移动资源
terraform state mv aws_instance.web aws_instance.web_new

# 从状态移除(不销毁资源)
terraform state rm aws_instance.old

# 导入已有资源
terraform import aws_instance.web i-1234567890abcdef0

模块化

# modules/vpc/main.tf
variable "vpc_cidr" {
  type = string
}

resource "aws_vpc" "main" {
  cidr_block = var.vpc_cidr
}

# 使用模块
module "vpc" {
  source   = "./modules/vpc"
  vpc_cidr = "10.0.0.0/16"
}

module "ecs" {
  source = "terraform-aws-modules/ecs/aws"
  version = "~> 5.0"

  cluster_name = "production"
  vpc_id       = module.vpc.vpc_id
}

常用 Provider 示例

阿里云

provider "alicloud" {
  region = "cn-hangzhou"
}

resource "alicloud_instance" "server" {
  image_id      = "ubuntu_22_04_x64_20G_alibase_2023"
  instance_type = "ecs.g6.large"
  system_disk_category = "cloud_essd"
  security_groups = [alicloud_security_group.web.id]
}

Kubernetes

provider "kubernetes" {
  config_path = "~/.kube/config"
}

resource "kubernetes_namespace" "app" {
  metadata {
    name = "production"
  }
}

resource "kubernetes_deployment" "app" {
  metadata {
    name      = "web-app"
    namespace = kubernetes_namespace.app.metadata[0].name
  }
  spec {
    replicas = 3
    selector {
      match_labels = {
        app = "web"
      }
    }
    template {
      metadata {
        labels = {
          app = "web"
        }
      }
      spec {
        container {
          image = "nginx:latest"
          name  = "nginx"
          port {
            container_port = 80
          }
        }
      }
    }
  }
}

最佳实践

目录结构

terraform/
├── environments/
│   ├── dev/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   └── terraform.tfvars
│   ├── staging/
│   └── production/
└── modules/
    ├── vpc/
    ├── compute/
    └── database/

代码规范

  • 使用 _ 命名资源(而不是 -
  • 为所有资源添加 Name 标签
  • 使用 terraform fmt 格式化代码
  • 对敏感信息使用 sensitive = true

安全最佳实践

  1. 远程状态必须加密
  2. 使用 DynamoDB 实现状态锁
  3. 不要在代码中硬编码密钥
  4. 使用最小权限原则配置 Provider
  5. 定期审核状态文件

总结

Terraform 将基础设施管理从手动操作转变为代码化、版本化的工程实践。通过模块化设计和远程状态管理,团队可以安全、高效地管理云计算资源。建议从简单的单云环境开始,逐步过渡到多云和模块化管理。