CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
Terraform 基础设施即代码/课时/init 与 Provider
RawBlame
课时目录12 节

Terraform 基础设施即代码

  1. 01Terraform 是什么
  2. 02HCL 语法
  3. 03init 与 Provider
  4. 04plan 与 apply
  5. 05State 管理
  6. 06变量与输出
  7. 07Module 复用
  8. 08AWS 资源示例
  9. 09Terraform 与 K8s
  10. 10CI 中的 Terraform
  11. 11Terraform vs Helm
  12. 12综合练习

init 与 Provider

terraform init、版本锁定 .terraform.lock.hcl。

30 分钟

terraform init 与 Provider

这一课你将能做到

  1. 说清楚 terraform init 到底做了哪几件事,哪些产物该提交 Git
  2. 正确声明 Terraform 和 provider 的版本约束,看懂锁文件
  3. 掌握 provider 的多别名配置、升级方法和初始化常见报错的处理

为什么要学

init 是 Terraform 所有命令的「入场券」:不 init,plan 和 apply 都跑不了。它看着简单(一行命令),但背后负责下载 provider 插件、初始化后端、拉取子模块、建立模块索引。团队协作中版本对不齐、插件下不动、锁文件冲突,几乎是每个人第一周都会撞上的问题。这一课把 init 一次讲明白,以后遇到初始化问题不再靠玄学。

人话:init 像项目开工前的「领料 + 进场」——按清单把工具(provider)领齐、确认仓库门(backend)在哪、把外包小组(modules)联系上,之后才能开工。

先建立图像

init 的输入和产物:

输入:*.tf 中的 required_providers、backend、module 源
  │
  ├─ 下载 provider 插件 → .terraform/providers/
  ├─ 生成/校验依赖锁    → .terraform.lock.hjson
  ├─ 初始化 backend    → 本地目录 或 S3 等远程存储
  └─ 拉取子模块        → .terraform/modules/

Git 提交策略:

文件/目录提交 Git?原因
*.tf是配置本体
.terraform.lock.hjson是保证全员用同版本 provider
.terraform/否体积大、含平台相关二进制
terraform.tfstate本地练习可留;团队用远程 backend含敏感信息且需加锁
*.tfvars 含密钥时否密钥不进仓库

跟着做

步骤 1:写版本约束

新建 init-demo/versions.tf:

terraform {
  required_version = ">= 1.7.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"   # 允许 5.x,不允许 6.0
    }
    random = {
      source  = "hashicorp/random"
      version = ">= 3.5.0, < 4.0.0"
    }
  }
}

~> 5.0 是最常用的约束:允许 5.0–5.x 的任何补丁/小版本,6.0 不自动升(大版本可能有破坏性变更)。

步骤 2:配置 provider

新建 providers.tf:

provider "aws" {
  region = "ap-northeast-1"
}

此时还不需要真实 AWS 凭证即可 init——下载插件发生在凭证检查之前。

步骤 3:执行初始化

terraform init

输出中重点看三段:

Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 5.0"...
- Installed hashicorp/aws v5.x.x ...
Terraform has been successfully initialized!

打开生成的 .terraform.lock.hjson,能看到 provider 的版本和哈希。锁文件保证同事和 CI 拿到的是完全相同的插件版本。

步骤 4:provider 多别名(同一账号两个区域)

改 providers.tf:

provider "aws" {
  region = "ap-northeast-1"   # 默认:东京
}

provider "aws" {
  alias  = "singapore"
  region = "ap-southeast-1"   # 备用:新加坡
}

使用非默认 provider 时要在资源上显式声明:

resource "aws_s3_bucket" "backup" {
  provider = aws.singapore
  bucket   = "my-backup-bucket-12345"
}

不加 provider 的资源全部走默认(东京)配置。跨账号、跨区域架构都靠 alias 实现。

步骤 5:升级 provider

当 5.x 出了新版本想跟进:

# 在约束范围内升级并刷新 lock
terraform init -upgrade

然后 git diff .terraform.lock.hjson 确认升级了什么,跑一遍 plan 验证后再提交。没有 -upgrade 时,init 严格按 lock 里的版本安装,这正是锁文件的意义。

步骤 6:从干净环境复现

删掉 .terraform 目录(模拟新同事拉代码):

Remove-Item -Recurse -Force .terraform
terraform init

init 按 lock 文件精确还原插件版本——这一步在 CI 里每次都会发生,所以 lock 必须提交。

讲清楚要点

  1. init 是安全且可重复运行的:改了 provider 配置、加了模块、换了 backend 参数,重新 init 即可,它不会动你的资源。
  2. 三级版本约束要分清:Terraform 核心版本(required_version)、provider 版本(version)、锁文件记录实际选中的版本。约束给范围,锁定给事实。
  3. provider 来源是注册表地址:hashicorp/aws 表示 registry.terraform.io 上的官方插件;也可以用第三方或本地文件系统源。
  4. 凭证不写在配置里:AWS provider 按顺序从环境变量 AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY、共享凭证文件、IAM 角色(EC2/IRSA)取凭证。硬编码 AK/SK 是事故级错误。
  5. backend 初始化是 init 的一部分:配置了 S3 backend 后,init 会询问并迁移现有本地 state,第 5 课完整演示。

你可能会懵的地方

  • init 之后改了 provider 版本,要做什么? 重新 terraform init。若新约束与 lock 冲突,会提示用 -upgrade;普通改约束后 init 会自动更新 lock。

  • .terraform.lock.hjson 合并冲突怎么办? 最稳妥:删掉 lock 文件后重新 terraform init 生成,再 plan 验证一次提交。别手工编辑哈希。

  • 为什么 CI 里 init 报插件哈希校验失败? lock 是在别的操作系统生成且未包含对应平台哈希。多平台团队执行一次 terraform providers lock -platform=windows_amd64 -platform=linux_amd64 把各平台哈希都写入。

  • provider 下载慢/超时怎么办? 企业网络可搭 provider 网络镜像(network_mirror),或在 CI 预置插件缓存目录并设置 TF_PLUGIN_CACHE_DIR,避免每次重复下载。

  • 一个配置能用多个云的 provider 吗? 能,required_providers 里同时声明 aws、azurerm、google 即可,但要评估 state 和 blast radius,生产通常按云/系统拆配置。

错法对照

错法问题正解
provider "aws" { access_key = "AKIA..." }密钥进 Git,泄露风险用环境变量/凭证文件/角色
不写 version 约束今天和下个月装的版本不同~> 5.0 固定大版本
提交 .terraform/ 目录仓库膨胀、跨平台报错gitignore 忽略
lock 提交了但从不更新错过安全补丁定期 init -upgrade 并验证
多个 provider alias 却不在资源上指定资源全落到默认 region需要时写 provider = aws.别名

卡点急救

  1. Failed to query available provider packages:网络不通或镜像问题。检查代理设置,或配置 network_mirror;公司环境确认 registry.terraform.io 是否在白名单。
  2. Unsupported Terraform Core version:本机 Terraform 太老。升级 CLI 到 required_version 要求的版本,别为了跑通而删约束。
  3. Provider configuration not present / already declared:多 alias 时资源引用了不存在的别名,或同一个 alias 声明了两次,核对 providers.tf。

面试常问

  • terraform init 做了哪些事? 初始化 backend;按 required_providers 下载并校验插件、生成锁文件;下载配置引用的模块;建立工作目录。它不管理任何真实资源。

  • .terraform.lock.hjson 的作用?为什么要提交? 记录每个 provider 的选中版本和包哈希,保证团队成员和 CI 在约束范围内使用完全一致的插件,防止「我机器上能跑」和供应链被替换问题。

  • 如何让 Terraform 同时操作两个 AWS 区域? 声明两个 provider 块,其中一个用 alias,资源上通过 provider = aws.别名 选择;跨区域资源也可以分模块各自传 providers 参数。

自测三问

  1. ~> 5.0、>= 5.0、= 5.40.0 三种约束分别允许哪些版本?
  2. 哪些 init 产物该进 Git,哪些不该?为什么?
  3. 同事的 CI 报 provider 哈希校验失败,你怀疑是什么原因,怎么修?

小结一句话

init 负责按版本约束领齐 provider、锁死版本、接好 backend 和模块,lock 提交、.terraform 忽略,是协作不翻车的起点。

延伸

  • Command: init 官方说明
  • Provider Requirements 版本约束语法
  • Lock File 锁文件文档
  • 下一课:plan 与 apply——看懂执行计划并安全落地变更。
加载本节练习…
← 上一课HCL 语法下一课 →plan 与 apply