3. Terraform安装与多云网络Provider配置
在真正开始用 Terraform 描述企业网络之前,必须先解决两件事:一是让 Terraform 本体在受控环境中可用,二是让 Terraform 能够以正确的身份、正确的版本、正确的区域去调用 AWS、Azure、GCP、阿里云的 API。前者决定“命令能不能跑”,后者决定“资源能不能被创建到正确的云和账号里”。本节围绕安装、Provider 声明、认证方式与版本约束四条主线展开,并给出可直接参考的配置骨架。
一、安装 Terraform:选对版本与安装方式
Terraform 是单个二进制文件,安装本身并不复杂,但企业环境里真正需要关注的是版本一致性与可重复性。Terraform 的版本号遵循语义化版本,例如 1.7.5,其中主版本变化可能带来配置语法或状态格式的不兼容。团队协作时,如果 A 同学用 1.6、B 同学用 1.8,同一份配置可能在不同机器上产生不同的 plan 结果,因此建议在项目根目录用 required_version 锁定范围。
常见安装方式有三种:包管理器(如 apt、brew、choco)、官方二进制包、以及版本管理工具 tfenv。在 CI/CD 流水线中,推荐使用官方二进制或 tfenv,避免包管理器仓库版本滞后。以 Linux 为例,下载并校验后放入 PATH:
# 示例:下载 Terraform 1.7.5 并校验
curl -O https://releases.hashicorp.com/terraform/1.7.5/terraform_1.7.5_linux_amd64.zip
curl -O https://releases.hashicorp.com/terraform/1.7.5/terraform_1.7.5_SHA256SUMS
sha256sum -c terraform_1.7.5_SHA256SUMS --ignore-missing
unzip terraform_1.7.5_linux_amd64.zip -d /usr/local/bin/
terraform version
执行 terraform version 后应看到类似 Terraform v1.7.5 的输出。若同时安装了多个版本,可用 tfenv install 1.7.5 && tfenv use 1.7.5 切换。安装完成后,建议立即在项目里写入版本约束,而不是等到报错再补。
二、Provider 是什么:Terraform 与云 API 的适配层
Provider 是 Terraform 与具体云平台之间的插件。Terraform 核心只负责解析配置、构建依赖图、管理状态;真正调用 AWS EC2 API、Azure 虚拟网络 API、GCP VPC API、阿里云 VPC API 的动作,都由对应 Provider 完成。每个 Provider 有自己的资源类型、数据源、认证参数和版本节奏,因此“多云网络”本质上就是在一份配置里同时声明多个 Provider,并让每个资源明确归属到某个 Provider。
Provider 通过 required_providers 声明来源与版本,通过 provider 块配置认证与默认区域。下面这张图展示了 Terraform 核心、四个云 Provider 与各自认证入口之间的关系,以及版本约束所处的位置。
三、声明 Provider 与版本约束
在 Terraform 0.13 之后,Provider 必须显式声明来源。推荐把 required_version 与 required_providers 放在同一个 terraform 块中,形成项目级的“版本契约”。下面是一份多云网络项目的示例骨架:
terraform {
required_version = ">= 1.6.0, < 2.0.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.40"
}
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.95"
}
google = {
source = "hashicorp/google"
version = "~> 5.20"
}
alicloud = {
source = "aliyun/alicloud"
version = "~> 1.220"
}
}
}
这里的 ~> 5.40 表示允许 5.40 到 5.x 之间的补丁与次版本升级,但不跨到 6.0。这样既能获得安全修复,又不会因为主版本升级导致资源参数被重命名。执行 terraform init 时,Terraform 会读取该约束,从 Registry 下载匹配的 Provider 并写入 .terraform.lock.hcl。锁文件记录了精确版本与校验和,应提交到版本库,保证团队与流水线使用完全一致的插件。
provider_installation 指向内部镜像或文件系统镜像目录,再配合锁文件使用,避免每次 init 都依赖外网。四、四种云的认证方式与配置示例
认证的核心原则是:不要把长期密钥硬编码在 .tf 文件里。优先使用环境变量、实例角色、工作负载身份或密钥管理服务。下面给出四种云在本地开发与 CI 中常见的配置方式。
AWS:推荐使用命名 profile 或 AssumeRole。Provider 块中可指定 profile 与 assume_role,凭证由 ~/.aws/credentials 或环境变量提供。
provider "aws" {
region = "cn-north-1"
profile = "network-prod"
assume_role {
role_arn = "arn:aws-cn:iam::123456789012:role/TerraformNetworkRole"
session_name = "terraform-network"
}
}
Azure:使用 Service Principal,通过 ARM_CLIENT_ID、ARM_CLIENT_SECRET、ARM_TENANT_ID、ARM_SUBSCRIPTION_ID 四个环境变量注入,Provider 块只需声明 features 与订阅。
provider "azurerm" {
subscription_id = var.subscription_id
features {
virtual_network {
delete_virtual_network_before_destroy = true
}
}
}
GCP:使用 Service Account JSON 文件,通过 GOOGLE_APPLICATION_CREDENTIALS 指向文件路径,Provider 中声明 project 与 region。
provider "google" {
project = "net-prod-2024"
region = "asia-east1"
}
阿里云:使用 RAM 用户的 AccessKey,通过 ALICLOUD_ACCESS_KEY 与 ALICLOUD_SECRET_KEY 注入,Provider 中声明 region。生产环境建议改用 STS 临时凭证。
provider "alicloud" {
region = "cn-hangzhou"
}
五、多 Provider 下的资源归属与别名
当同一份配置里出现多个云时,最容易出错的是“资源到底创建到哪个账号/区域”。Terraform 的规则是:资源默认使用同名 Provider 的默认配置;如果同一云需要多个区域或多个账号,就用 alias 定义别名,并在资源中通过 provider = aws.xxx 显式指定。例如同时管理 AWS 北京与宁夏两个区域:
provider "aws" {
alias = "beijing"
region = "cn-north-1"
}
provider "aws" {
alias = "ningxia"
region = "cn-northwest-1"
}
resource "aws_vpc" "bj_vpc" {
provider = aws.beijing
cidr_block = "10.10.0.0/16"
tags = { Name = "bj-network-vpc" }
}
执行 terraform plan 时,输出中会显示资源地址与 Provider 别名,例如 aws_vpc.bj_vpc 对应 provider["registry.terraform.io/hashicorp/aws"].beijing。这是判断“资源是否落到预期账号与区域”的第一道检查点。若发现 plan 中出现了未预期的 Provider,通常说明资源缺少 provider 参数,落到了默认配置上。
六、初始化与验证的完整闭环
配置写完后,按以下顺序验证:先 terraform init 下载 Provider 并生成锁文件;再 terraform providers 查看当前配置解析出的 Provider 树;然后 terraform validate 检查语法与必填参数;最后 terraform plan 观察资源归属与将要创建的网络对象。若认证失败,错误信息通常会明确指出是凭证缺失、权限不足还是区域不匹配,可据此回到对应的环境变量或 Provider 块排查。
.terraform.lock.hcl 加入 .gitignore。缺少锁文件时,不同机器可能拉到不同补丁版本,导致 plan 差异甚至状态迁移问题。锁文件与 required_providers 配合,才是完整的版本约束方案。