[Music]
terraform 是最流行
的基础设施即代码开发工具之一
，在接下来的一个小时左右，
我们将通过本课程中的全面和实践课程带您从零到英雄
，
我们将使用插图简化复杂的
概念 和
动画，您将
通过我们的实验室获得动手练习，您可以
免费访问
是的，我们的实验室直接在您的
浏览器中打开，因此您无需为云帐户支付额外费用
或
在本课程愿景中设置自己的基础设施 将
引导您了解 terraform 的基础知识，
并帮助您不仅了解
基础知识，
而且
如果您是第一次访问我们的
频道，
请不要忘记订阅，因为我们会上传
新视频和课程。 时间
[音乐]
你好，欢迎来到这个初学者的 terraform 课程，
我的名字是 vijayn palazzi，我将成为
你这门课程的讲师，
我们将开始 d 与
terraform 但首先我们
将看看基础设施即
代码或 iac
以及 iac 中可用的不同类型的工具
及其在管理现代
it 基础设施中的目的
然后我们将看到 terraform
在当今的 it 基础设施中的作用
然后我们将学习 如何安装
terraform 接下来是 hashicorp 配置语言的基础知识
接下来我们有我们的第一个实验室，您将在其中
接触 hcl 语法
接下来我们将了解 terraform 的基础知识，
例如提供者
输入和输出变量资源
在此之后，我们将了解 state
和 terraform 使用
它的原因以及使用 state
时要遵循的注意事项，
然后
从 terraform 提供的不同命令开始深入研究基础知识，
然后是讲座 在这里我们
了解
可变和不可变基础设施之间的区别
接下来我们将看看生命周期 terraform
中的规则，我们将在此之后学习如何管理
创建资源的方式，
之后我们将讲授基本
主题，例如数据源
元参数，例如 count 和 for
each，并最终了解
terraform 中的版本约束，
所以让我们开始吧
[音乐]
现在让我们介绍我们的实验室以
访问实验室
转到此链接此链接也
可在下面的描述中找到
如果您是第一次访问代码云
然后免费注册
一旦进入您将找到
在您
的课程列表下的实验室课程 该课程有多个场景 我会在您完成本课程的过程中
告诉您何时访问
其他实验室
所以请前往代码云访问
实验室
让我们从应用程序
交付在传统
基础架构中的工作原理开始 模型
以及它如何
随着云计算
和基础设施即代码等技术的出现而演变 让我们
回到过去，看看基础设施
是如何提供的 在传统的 IT
模型中，
让我们考虑一个
想要推出新应用程序
的组织 业务
提出应用程序
的要求 业务分析师然后
从业务分析中收集需求
并将其转换为一组高级别的
然后将技术要求传递给解决
方案架构师，然后解决方案架构师设计部署此应用程序
要遵循的架构，
这通常包括
基础架构考虑因素，
例如类型
规范和所需的服务器数量，
例如
前端 Web 服务器 后端服务器
数据库
负载平衡等 遵循
传统的基础架构模型
这些必须部署在
组织的内部部署环境中
，这意味着
如果需要额外的硬件，他们
将利用数据中心的资产 必须通过采购团队订购，
该团队将提供一个 ne 如果
向供应商提出硬件请求，
那么在数据中心收到
硬件后，可能需要几天到几周甚至几个月的时间才能购买硬件
并将其交付到
数据中心，
现场工程师将负责
机架和堆栈
系统管理员执行
初始配置的设备
，网络管理员使
系统在网络上可用，
存储管理员将存储分配给
服务器，备份管理员配置
备份
，最后
一旦按照标准设置系统，
他们就可以 移交给
应用程序团队来部署他们的
应用程序
这种今天仍然
非常常用的部署模型
有很多缺点
周转时间可能在数周到数
月之间，这只是为了让
系统处于准备状态以开始
应用程序部署
这包括
系统从最初采购
到交付的时间 团队之间
也无法快速实现按需扩展或缩减
基础架构
部署和维护
此模型的总体成本通常相当高，
而基础架构
分析过程的某些方面可以通过几个步骤实现自动化，
例如机架和堆栈
布线 和其他部署过程
是手动的和缓慢的，
有这么多团队在处理这么多
不同的任务
人为错误的可能性很高，这
导致环境不一致
使用此模型的另一个主要缺点是
计算资源
的利用率不足 基础设施规模调整活动
通常提前很好地执行
并且服务器的大小考虑到
峰值
利用率无法轻松扩展或缩减
意味着大多数这些资源
不会在过去十年左右的非高峰时间使用
，因此组织
一直在转向虚拟化 和
云
平台利用所提供的服务
亚马逊 aws 微软 azure
谷歌云平台等主要云提供商
通过迁移到云，
启动基础设施
的时间和应用程序的上市时间
显着减少，
这是因为使用云，您
无需投资
或管理
在传统基础架构模型的情况下，您通常会使用的实际硬件资产
数据中心 硬件资产
和服务由云
提供商管理 虚拟机可以
在几分钟内在云环境中启动，
并缩短上市时间 与额外的数据中心管理和人力资源成本
相比，传统
基础架构在云环境中使用两周
，基础架构成本从几个月减少
，
云
基础架构支持
apis，这开辟了一个全新的领域
自动化的机会世界，
最后是内置的自动缩放
和弹性功能 云
基础架构
通过
虚拟化和云减少资源浪费
您现在
只需点击几下即可配置基础架构，
而
与
使用管理控制台进行
资源配置的传统部署方法相比，这种方法肯定更快、更有效，但它并不总是
理想的
解决方案 当我们处理有限数量的资源时，可以采用这种方法，
但在具有弹性
和高度可扩展的云环境
和不可变基础设施的大型组织中，
这种方法一旦
配置就行不通，系统仍然必须
通过不同的团队
处理大量流程开销 这
增加了交付时间，
并且人为错误的可能性
仍然很大，导致环境不一致，
因此不同的组织开始
通过开发自己的
脚本和工具来解决这些挑战
，有些使用简单的 shell 脚本，
有些使用编程语言 诸如
python
ruby perl 或 powershell 之类的每个人都在
解决相同的问题，
试图通过利用各种云环境的 api 功能来自动化基础设施
配置，以
更快
、更一致的方式部署环境，
这些功能演变成一组逐渐为人所知的工具
作为
基础设施即代码 在下一
讲中
我们将更详细地了解什么是基础设施即代码
在本讲座中我们将
介绍基础设施即代码，即
通常称为
iac 我们还将看看
常用的 iac
工具 讨论了
通过使用
各种云
提供商
的管理控制台进行配置 提供云基础设施的更好方法
是将整个
配置过程
编码，这样我们就可以编写和执行代码
来定义
配置配置更新并
最终破坏基础设施
资源，
这称为 基础设施即
代码或
具有基础设施的 iac 您可以
将几乎任何基础设施
组件作为代码进行管理，
例如数据库网络存储甚至
应用程序配置
您在此处看到的代码是一个 shell 脚本
但是它不容易管理
它需要编程或开发
技能来构建和维护
有很多 您
需要编写代码的逻辑，它不
容易重用，这就是
像 terraform 和 ansible 之类的工具可以帮助
编写易于学习的代码的地方
现在可以将大型 shell 脚本转换为这样的
简单 terraform 配置文件
使用基础设施即代码，
我们可以
使用简单的人类可读的高级
语言定义基础设施资源
这里是另一个例子，我们将
利用 ansible 提供三个
使用特定 ami 的 aws ec2 实例，
尽管 ansible 和 terraform 是
他们拥有的 iec 工具
他们试图实现的目标存在一些关键差异
，因此他们有一些非常不同的
nt 用例
我们将看到这些差异接下来
有几个不同的工具
部分基础设施作为代码系列
ansible terraform puppet 云形成
包装器 salt stack vagrant docker 等，
尽管您可以使用
这些工具中的任何一个来设计类似的
解决方案，
它们都有 被创建来解决一个
非常具体的
目标，考虑到 iec 可以大致
分为三种类型
配置管理 ansible puppet
salt stack 属于这一类
用于服务器模板的工具
docker packer 和 vagrant 属于这一
类
，最后我们有基础设施
配置工具 例如 terraform 和
云形成
让我们更详细地看一下
这些我们将要了解的第一种 iec 工具
是配置管理工具，其中
包括 ansible
Chef puppet 和 salt stack
等工具，这些工具通常用于
在服务器等现有基础设施资源上安装和管理软件
数据库网络
设备
等与我们之前看到的临时 shell 脚本不同，
配置管理工具
维护一致和标准的代码结构
，这使得根据需要更容易管理和
更新它，
它们还被设计为在
多个远程资源上运行 一旦
可以将 ansible playbook 或角色
签入版本控制
存储库，
这允许我们根据需要重用和分发
它，
但是配置管理工具最重要的特性可能
是它们是有效的，这
意味着您可以运行代码
多次和每次运行
它只会进行
必要的更改以使环境
进入定义的状态
它会保留任何已经就位的东西，
而无需我们编写任何
额外的代码
接下来让我们看看服务器模板
工具
这些 是来自 hashicorp 的 docker vagrant 和 packer 等
这些 是来自 hashicorp 的 docker vagrant 和 packer 等工具
，可
用于创建虚拟机的自定义
映像 ne 或
容器
这些映像已经包含所有
必需的软件和
安装在其上的依赖项，
并且在大多数情况下，这消除
了
在部署 vm 或容器后安装软件的
需要 服务器模板化映像的最常见示例
是 vm 映像，例如 osboxes.org 上
提供的
amazon aws 中的自定义 amis 和 docker hub 上的 docker 镜像
以及其他容器注册
服务器模板工具也促进了
不可变的基础设施，这
与配置管理工具不同，
这意味着一旦部署了 vm 或
容器，
它就被设计为保持不变 如果
要对映像进行更改而不是
像在配置
管理工具（例如 ansible）
的情况下更新正在运行的实例，则
不变
在本课程
中，我们将更详细地
了解最后一种类型的 iec
本课程特别感兴趣的
是配置工具 这些工具用于
使用简单的声明性代码配置基础架构组件
这些基础架构组件的
范围可以从服务器（如虚拟
机
数据库 vpcs 子网
安全组存储）以及几乎
任何基于 我们选择的提供商，
而云形成专门
用于在 aws 中部署服务
正如我们所讨论的，
terraform 是一种流行的 iec 工具，它
作为基础设施
配置工具
特别有用 快速
使我们能够建立管理和
在几分钟内摧毁基础设施
terraform 的最大优势之一是它能够
跨多个平台部署基础设施，
包括私有云和公共云，
例如内部部署的 vSphere 集群
或云解决方案，例如 aws gcp 或
azure
等等 只是
改革可以管理的众多资源中的一小部分
那么 terraform 如何管理
这么多不同类型平台上的基础设施
这是通过提供者实现的
提供
者通过他们的 api 提供者帮助 terraform 管理
第三方平台
启用 terraform 管理云
平台，如 aws gcp
或 我们刚刚看到的 azure 以及
网络基础设施（如 big-ip
cloudflare dns apollo alto 网络和
infoblox
）以及监控和数据
管理工具（如 datadog
grafana 或 xero wavefront 和相扑逻辑
数据库（如 influxdb mongodb mysql
postgresql 和版本控制系统）
像 github bitbucket 或 gitlab
terraform 支持数百个 这样的
提供者因此可以与
几乎所有基础设施平台一起工作
terraform 使用 hcl 代表
hashicorp 配置语言，这
是一种简单的
声明性语言，用于定义
要
作为代码块提供的基础设施资源 所有基础设施
资源都可以在
配置文件
中定义 具有 dot df 文件扩展名
配置语法易于阅读
和编写
，适合初学者使用 该示例
代码用于在 aws 云上配置新的 ec2 实例
该代码是声明性的，可以
在版本控制系统中维护，
允许 它将分发给其他
团队
我们将在本课程的后面更详细地介绍 hcl 语法
我们还有许多动手实验室
，您将在其中
练习使用这些文件并
在本课程结束时获得大量经验
所以我们说代码是声明性的，
但是声明性意味着
我们定义的代码是我们想要的状态
基础设施
处于所需状态，
右侧是当前状态，其中
没有任何东西
terraform 会处理
从当前状态
到所需状态所需的一切，
而我们不必担心如何
到达
那里 terraform 是否执行
terraform 分三个阶段工作
init 计划并在 init 阶段应用
apply phase terraform
对目标环境进行必要的更改
以使其
达到所需状态，
如果由于某种原因环境
从所需状态转变，
则后续的 terraform apply 将
仅通过修复缺失的部分将其恢复到所需状态 组件
改革管理的每个对象都
称为
资源 资源可以是计算实例
clo 中的数据库服务器 ud
或在物理服务器中，前提是
terraform 管理
terraform 管理资源的生命周期，
从其供应
到配置再到退役
更新
特定平台的资源时采取
terraform 可以确保整个
基础设施始终处于定义的
状态
状态是
terraform 部署的基础设施的蓝图
terraform 可以
通过配置数据源读取现有基础设施组件的属性
这可以在以后 用于配置
terraform 内的其他资源 terraform 还可以导入
terraform
之外的其他手动或
通过其他 iec 工具创建的资源
，并将其置于其控制之下，以便
它可以管理这些资源，
因此云和 terraform 企业
提供附加功能 允许
管理基础设施的团队之间简化协作
提高安全性和集中式 ui
来管理改革部署
所有这些功能都可以
很好地执行出色的企业级
基础设施配置
工具，这是对 terraform 的快速介绍，
因此让我们深入探索所有
这些在本节
即将到来的讲座
中更详细，我们将学习如何
安装 terraform
terraform 可以作为单个
二进制文件
或可执行文件从 www.terraform.io 的 terraform
下载部分下载
安装 terraform 就像
下载这个一样简单 文件
并在安装后将其复制到系统路径中
我们可以
通过运行命令
terraform version 检查版本 在此录制时最新版本的
terraform
是 0.13，
并且将在
整个课程中使用此
版本 Windows mac
和 其他几个基于 linux 的
发行版
请注意所有
本课程中使用的示例和实验室
将使用在 linux 机器上运行的 terraform
，特别是 0.13 版本
，就是这样，我们现在可以开始
使用 terraform 部署资源
，如前所述 terraform 使用
以 hcl 编写的配置文件
来部署基础设施资源
这些文件有一个 .tf 扩展名，
可以使用任何文本编辑器创建，
例如
记事本或记事本 plus 用于 windows
或命令行文本编辑器，例如
vm 或 linux 中的 emac 或者它可以
是您选择的任何 ide
那么资源是什么 资源是一个
对象，因此管理
它可以是本地主机上的文件，也
可以是云上的虚拟机，
例如 ec2 实例
，也可以是服务，如 s3 存储桶
ecs
dynamodb 表 imuses rime
组角色策略等
或 它可能是主要云提供商的资源，
例如来自 azure azure 活动目录等 gcp 数据库的计算和应用程序引擎，
字面上有 hun
可以使用 terraform 跨
大部分云和本地
基础设施配置的大量资源，
我们将在本课程的后面部分研究其中的一些示例
，
但在前几节中，我们将
坚持使用两个
非常容易理解的资源
本地文件
资源类型和一种
称为随机宠物的特殊资源
一旦我们对基础知识有了很好的理解，使用简单的资源类型来真正了解 terraform 的基础知识很重要，例如资源的生命周期、hcl 格式等
可以轻松地将这些知识应用到
其他实际用例中
，我们将在本课程的后面部分中看到，
我们将了解
hcl（hashicorp 配置
语言）的基础知识
，然后使用 terraform 创建资源
让我们首先了解 hcl
语法 hcl 文件由块和
参数组成 块在花括号内定义
，它包含一组
键值中的参数
表示配置数据的pair格式，
但是什么是块以及
它
以最简单的形式包含什么参数块整个形式
包含有关
基础设施平台的信息
以及我们想要创建的该平台内的一组资源
例如让我们考虑一个 简单的
任务
我们想在安装了 terraform 的本地系统中创建一个文件
首先让我们在斜杠根目录下创建一个
名为 terraform dash 本地 dash 文件
的
目录 这是我们将在该目录下
创建
一次 hcl 配置文件 我们切换
到这个新目录，
我们可以创建一个名为 local.tf 的配置文件
，在这个文件中，我们可以定义一个这样的
资源块
，在资源块中，我们使用块参数指定
要创建的文件
名及其内容
让我们分解 local.tf 文件以
了解每一行的含义
此文件中的第一个元素是一个
块
this 可以是 由
我们在这里看到的块类型内的花括号标识的
称为资源块
，这可以通过块开头的关键字名为 resource 来标识，
紧跟关键字名为 resource 我们
有
我们想要的资源类型的声明 创建
这
是一个固定值，取决于
我们想要在何处创建资源的提供者
在这种情况下，我们有
称为本地文件
的资源类型资源类型首先提供两位
信息
是提供者，它
由前面的单词表示
资源类型中的下划线
这里我们使用了本地
提供者
下划线后面的单词
在这种情况下是文件表示
资源
的类型 此资源块中的下一个和最后声明
是资源名称 这是用于的逻辑
名称 识别资源，它
可以命名为
任何名称，但在这种情况下，我们将其命名
为 pet，
因为我们正在创建的文件包含
信息 关于宠物的离子
，在这个块内和花括号内，
我们定义了资源的参数，
这些
参数以键值对格式编写，
这些参数特定于
我们正在创建的资源类型
，在这种情况下是本地
文件，第一个参数是 文件名
，我们将绝对部分分配给
我们要
在此示例中创建的文件，它设置为斜杠根
宠物点txt 现在我们还可以
通过使用内容参数
向此文件添加一些内容，让我们 添加我们爱
宠物的值文件名
和内容这两个词特定于
我们要创建的本地文件资源
，它们不能更改换句话说
本地文件的资源类型
期望我们为
每个资源提供文件名和内容的参数
type 有特定的参数，他们
希望
我们在学习过程中会看到更多这样的参数
，就是这样，我们现在有了一个完整的 hcl
配置文件
，我们可以用它来创建一个文件
这个文件名为patch.text，将在斜杠
根目录中创建，它将包含
一行数据
，我们在这里看到的资源块只是
hcl中使用的配置块的一个示例，
但它也是强制性的
使用 terraform 部署资源所需的块
是为配置 aws ec2 实例而创建的资源文件
示例
资源类型是 aws 下划线
实例
我们命名为资源 Web 服务器
，我们在这里使用的参数
是 ami id 和
这里的实例类型是
用于创建
aws s3 存储桶的资源文件的另一个示例 在这种情况下，资源类型
是
aws underscore s3 underscore 存储桶
我们选择的资源名称是
data
和我们提供的参数
作为存储桶名称
和 acl 一个简单的 terraform 工作流程
包括四个步骤
首先编写配置文件，
然后运行 terraform init 命令
，然后使用
最后，
一旦我们准备好使用 terraform apply 命令应用更改并
准备好配置文件，我们现在可以
使用 terraform 命令创建文件资源，如下所示
首先运行 terraform init 命令
此命令将检查
配置文件并初始化 terraform plan 命令
包含
tf 文件的工作目录此命令所做的第一件事
是了解我们正在
根据资源块中声明的资源类型使用本地提供程序，
然后它将下载插件
以便能够在
从这个命令的输出中在 dot tf 文件中声明的资源
我们可以看到 terraform init 已经
安装了一个
名为 local 的插件接下来
我们准备创建资源但
在我们这样做之前
如果你想
看到将被执行的执行计划 通过 terraform
我们可以使用命令 terraform plan
该命令将显示
terraform t 将执行的操作
o 创建资源 terraform
知道它必须创建资源
，这显示在输出中，
类似于
git 中的 diff 命令 输出在名为 pet
的本地文件类型资源旁边有一个加号
这包括我们
在中指定的所有参数 用于创建资源的 dot tf 文件，
但您还会注意到
我们没有
在配置文件
中明确声明的一些默认或可选参数也显示在屏幕
上加号表示
将创建资源
现在记住这一步 不会
创建基础设施资源，但
会提供此信息供
用户查看
并确保在查看后需要
在此执行计划中执行的所有操作
我们可以创建
资源
，为此我们将使用
terraform apply 命令
此命令将再次显示执行
计划，
然后它会要求用户
通过键入
yes 进行确认以继续执行一次 我们确认
它将继续创建
资源，在这种情况下
是一个文件，我们可以通过运行 cad 命令查看文件来验证该
文件确实是创建
的
我们也可以
在配置
目录中运行 terraform show 命令来查看
我们刚刚创建
此命令
的资源的详细信息检查状态文件并显示资源详细信息，
我们将
在后面的讲座中了解有关此命令和状态的更多信息，
因此在结束本节之前，我们现在已经使用 terraform 创建了我们的第一个
资源
让 我们
回过头来看看
本例中local.tf文件中的配置块
我们使用了local文件的资源类型
，了解到这里下划线前的关键字
是provider的名字叫local 但是
我们怎么知道呢？
在名为 local 的提供程序下，除了本地文件之外还有哪些资源类型可用
，最后我们如何知道
本地文件资源需要哪些参数
之前我们提到 terraform
支持 100 多个提供者，
包括
我们在本示例中使用的本地提供者，
其他常见示例是 aws
在
amazon aws cloud azure
gcp alicloud 等中部署资源
，这些提供者中的每一个都有一个
可以在其上创建的唯一资源列表
那个特定的平台
和每个资源可以有许多
必需的
或可选的参数来
创建该资源
，我们可以根据需要创建尽可能多的
每种类型的资源
不可能记住所有
这些选项
，当然我们不 必须这样做
terraform 文档非常
全面
，这是我们需要遵循的单一事实来源，
如果我们在文档中查找本地提供者
，
我们可以看到它只有一种类型的
资源，称为
参数下的本地文件 部分
我们可以
看到资源块
接受
了几个参数，其中只有一个是强制性的
文件名
其余参数是
可选的，这就是本讲座的内容 现在让
我们转到动手实验室
并练习使用 hcl 并
使用 terraform 创建我们的第一个资源
这是一个介绍性视频，可让
您快速浏览动手操作
本课程中可用的实验室
每个实验室都是专门为帮助
您练习
和获取我们
在相关讲座和演示中学到的主题的知识
单击此按钮打开
动手实验室并等待实验室
环境加载
它可以 最多花一分钟时间
实验室界面有两个部分
iac 服务器的终端
位于左侧
，您将在此处运行命令
并根据提出的问题执行任务
可以在 分屏
右侧的测验门户
有两种类型的问题，
您可以
期待第一种类型是多项
选择题，您必须在其中
查找 a 回答特定问题，
其中一些可能很简单，但
对于其中一些，您必须
从终端检查 terraform 配置
，例如要回答这个问题，我们
必须导航到特定路径
并检查文件的扩展名
创建的
一种方法是从左侧的终端
我们可以看到
在这个目录中创建了一个名为 main.tf 的文件，
所以让我们回到任务门户并
选择 dot tf 作为我们对这个
问题的答案
第二类问题是这些问题的
配置测试
，您必须
执行特定任务，
例如编写 terraform 配置
文件和运行 terraform 工作流
以创建
更新或销毁基础设施，例如
在这里我们必须在其中运行 terraform init
命令 相同的配置
目录，
如果您不确定如何尝试
提问，可以使用左侧的终端再次完成此操作，请单击 o n 提示按钮，
它将为您提供有用的提示，并
在您进入本课程的 aws 部分后为您指明正确的方向，
您将开始使用 aws
服务实验室与 aws 测试框架集成，
这将允许您构建
例如更新和销毁aws 上的资源
这个问题需要我们
创建一个名为mary 的im 用户
，然后在配置目录中运行terraform init
本课程的动手实验
与我们的其他课程略有不同，
以优化terraform 的学习体验
我们已将 Visual
Studio 代码 ide 集成到实验室中，
这将允许您使用
内置的 terraform 扩展
，这将帮助您快速有效地编写 terraform
配置文件
以访问 Visual Studio 代码单击顶部
的 vs 代码选项卡
将
在新选项卡中打开它的终端，
从这里我们可以
打开 iic 服务器上的配置目录并
导航到 pa 在问题中指定的 th
我们也可以使用
预先安装的 terraform 扩展
来回答这个问题让我们在 im 目录中创建一个
名为 imuser.tf 的文件
来轻松创建资源块让我们
使用将加载的命令完成功能
接下来是资源类型的资源块模板，只需输入
aws
并同时按下 control 和空格键，
这将列出
aws 中可用的所有资源类型，
我们现在可以输入 iam 并选择
适当的资源类型
，在本例中为 aws iam 用户
我们还可以在
块中以相同的方式查找此资源块的参数
按控制和空格
键以查看所有可用参数的列表
并选择您
需要的参数
从终端准备好运行 terraform 命令
我们也可以从 在 vs 代码中，
我们可以
在目录内右键单击，然后单击
打开集成终端，
这将打开屏幕底部的 bash 终端
好的，这就是本视频的内容 我们希望
您
在本次讲座中获得出色的学习体验 我们将在上一堂课中学习如何使用 terraform
更新和销毁基础设施
我们看到了如何创建本地文件
现在让我们看看如何更新和
销毁 此资源
首先使用 terraform 让我们尝试
更新此资源
让我们添加文件权限参数
以将文件的权限更新
为 0700 而不是默认
值 077 这将删除
除文件所有者之外的其他所有人的任何权限
现在，如果我们运行 terraform plan 我们将看到
这样的输出
从输出中我们可以看到
资源将被替换
计划中资源名称开头的减号表示它将被
删除然后重新创建
该行 使用读取
强制替换
的命令负责删除和
重新创建
，在本例中，这是由我们广告
的文件权限参数
引起的
即使我们所做的更改
微不足道 terraform 也会删除旧
文件
，然后创建一个具有更新权限的新
，然后创建一个具有更新权限的新文件
这种类型的基础设施称为
不可变基础设施
我们在讨论不同类型的 iec 时简要地看到了这一点
工具，
如果您想继续进行更改，请
使用 terraform apply 命令
，然后
在确认提示时键入 yes 删除现有文件
并使用新权限重新创建以
完全删除基础设施
运行 terraform destroy 命令
此命令显示执行计划
同样，您还可以看到资源
及其所有参数旁边都有一个减号
，
这表明资源将被
销毁
以继续执行提示中的销毁确认是
这将删除
当前配置目录中的所有资源
在这个例子中，它删除了文件 root
pets dot txt 这就是本课的内容，
让我们继续 转到动手实验并
在本讲座中练习使用 terraform 更新和删除基础设施资源让我们更详细地了解
提供者，
我们在上一堂课中看到，
在我们编写 terraform 配置
文件后
，首先要做的是初始化
当我们在包含配置文件的目录中运行 terraform init 时，带有 terraform init 命令的
目录
terraform 下载并安装配置中
使用的提供程序的插件，
这些插件可以是云提供程序的插件，
例如 aws
gcp azure 或像本地一样简单的插件
我们用来创建
本地文件类型资源的提供程序
terraform 使用基于插件的
架构来处理数百个
此类基础设施平台
terraform 提供程序由 hashicorp 分发，
并且在 url registry.terraform.io 的 terraform 注册表中公开可用，
共有三个 提供者
的层次 第一个是官方提供
者 se 由 hashicorp 拥有和维护
，包括主要的云提供商，
例如 aws gcp 和 azure
我们迄今为止使用的本地提供商
也是
官方提供商 第二类
提供商
是经过验证的提供商 经过验证的
提供商由以下方拥有和维护
第三方技术公司
与 hashicorp 进行了合作伙伴提供商
流程，其中
一些示例是 fi 网络 heroku digitalocean 等的 big-ip
提供商
，最后我们有
由 hashicorp 社区的个人贡献者发布和维护的社区提供商
terraform init 命令运行时
显示正在安装的插件版本，
在这种情况下我们可以看到插件
名称
hashicorp slash local 版本为
2.0.0
已安装在目录中
terraform init 是一个安全命令
，它可以 在
不影响实际
部署的基础设施的情况下根据需要运行多次
插件下载
在
包含我们示例中的配置文件的工作目录中的一个名为 dot terraform slash plugins 的隐藏目录中
工作目录是
slash root slash terraform dash local
dash
file 你在这里看到的插件名称
hashicorp slash local 也
称为源地址
这是
terraform 用来
从注册表中定位和下载插件的标识符，
让我们仔细看看名称的格式
，
名称的第一部分，在本
例中是 hashicorp
是组织命名空间，
其后是 type
它是提供者的名称，例如本地提供者的
其他示例是 aws
azure rm google random
等插件名称也可以选择
在前面有一个主机名主机名
是插件所在的注册表的名称
如果省略它 默认为
registry.reform.io，这是 hashicob 的
公共注册表
，因为本地提供
程序存储在公共 terrafor 中 m
在 hashicorp 命名空间中的注册表
它的源地址可以表示
为
registry.terraform.io hashicorp
local 或简单地由 hashicorp
local 表示
，默认情况下省略主机名 terraform 安装最新
版本的提供
程序提供程序插件，尤其是官方插件
不断更新 对于较新的
版本，
这样做是为了引入新
功能或添加错误修复
，这些可能会给
您的代码带来重大更改，
我们可以锁定我们的配置文件
以使用特定的提供程序
版本，
我们将看到如何做到这一点 在本课程的后面，
现在让我们看一下 terraform 中使用的
配置目录
和文件命名约定，
到目前为止，我们一直在使用名为 local.tf 的
单个配置文件
，该文件位于
名为 terraform dash local
dash file
的目录中 我们的配置目录
这个目录不限于一个
配置文件
我们可以创建另一个
我们可以创建另一个配置文件
像这样
的 iguration 文件 cad.tf 是另一个配置文件
，它在应用时使用相同的
本地下划线文件资源
，它将创建一个名为 cad.txt 的新文件
是拥有一个
包含
供应基础设施所需的所有资源块
的单个配置文件，单个配置文件可以包含与您需要的
数量一样多的配置块，
用于此类配置文件的通用命名约定
是将其称为 main。 tf
目录中还可以创建其他配置文件，
例如 variables.tf 输出.tf
和 providers.tf 我们将
在本课程的后面部分详细讨论这些文件
现在让我们转到动手实验
并
在本讲座中探索与提供者的合作，我们将看到如何在 terraform 中使用
多个提供者
和资源，
直到现在我们 一直在使用名为 local 的
单个提供程序
在系统 terraform 中部署本地文件
还支持
在同一配置中使用多个提供程序
来说明这一点 让我们使用
另一个名为
random 的提供程序 此提供程序允许我们创建
随机资源，例如 作为随机
id 随机整数随机密码等
让我们看看如何使用此提供程序并
创建一个名为
random pet 的资源 当通过使用文档应用时，此资源类型
将生成随机宠物名称
我们
可以向其中添加资源块 像这样的现有
main.ta 文件
我们在前面的讲座中使用了称为 random pet 的资源类型
，我们看到
资源类型可以分解为两
部分
，下划线之前的关键字
是提供者
，在这种情况下 是随机的紧随其后的关键字
是资源类型，即宠物
让
我们在此资源块中将此资源称为 mypet 我们将
使用三个参数 ts 第
一个是要添加
到宠物名称
的前缀 第二个参数是
前缀
和生成的宠物名称之间的分隔符
最后一个参数
是长度，它是
要在单词中生成的宠物名称的长度
main.tf 文件现在有
两个不同提供者的
资源
定义 我们之前已经创建的本地文件类型的
资源和随机宠物类型的另一种资源
在我们生成执行计划并
创建这些资源之前，
我们必须运行 terraform init
命令
现在再次这是一个强制性步骤，
因为随机提供程序的插件
应该在
配置目录中初始化，然后我们才能
在 terraform init 的命令输出中使用它，
我们可以看到本地提供
程序之前已安装，它将
另一方面，将安装随机提供程序的插件，
因为它在我们现在可以
运行 terraform 计划
以查看执行之前未使用 n
按预期计划，名为 pet 的本地文件资源
将不会更新，因为
它与之前的相同，应用
名为 my pet 的新资源
将
基于我们刚刚添加的新资源块创建，
现在让我们应用配置
terraform
按预期应用本地文件资源
保持原样，
但现在已经创建了一个新资源
，称为
我的宠物随机提供程序是一个逻辑
提供程序
，它在屏幕上显示宠物名称的结果，
如下所示，这里有一个名为的属性
在我们继续之前，包含宠物名称的 id 由 apply 命令写入请注意，在
我们的插图中
，狗图标代表宠物，我们
将在
整个课程中使用它，随机宠物
可以生成
任何宠物 名称，它不必
专门是一只狗
，现在让我们前往动手
实验室，并在本讲座中探索
与 terraform 中的多个提供者合作，
我们将看到如何
利用 对于
terraform 中的变量，
到目前为止，我们在 terraform 块中使用了几个参数，
对于本地文件，我们有文件名
和内容
，对于随机宠物资源，我们
使用前缀
分隔符和长度作为参数，
因为这些值是直接在其中定义
的 主要配置文件
它们被认为是硬编码
值
硬编码值对于一个人来说不是一个好主意
，这限制了代码的可重用性，
这违背了使用 iac 的目的，
我们希望确保可以再次使用相同的代码
和 再次根据
可以在执行期间提供的一组输入变量来部署资源
，这就是输入变量
出现的
地方，就像在任何通用
编程语言（
例如 bash 脚本或 powershell）中一样，
我们可以在其中使用输入变量
terraform 分配变量让我们创建一个名为 variables.tf 的新
配置文件，
并
在 variables.tf 文件中定义这样的值
就像 main.tf 文件由
块
和参数组成来创建一个变量，
使用称为 variable 的关键字，
然后是变量名，
这可以命名为任何名称，但作为
标准
使用适当的名称，
例如我们要使用的参数名称
使用这个块中的变量，我们可以为变量提供一个
默认值，
这是一个可选参数，但它是
一种快速而简单的
为变量赋值
的方法，我们将
在后面的讲座中看到其他方法，
现在我们很好 有我们的变量
配置文件，
但我们如何在 main.tf 文件中使用它
来做到这一点，我们可以用变量名替换参数
值
，前缀为
战争，
当使用变量时，
您不必将值括
在双引号内
正如您在提供实际
值
和使用我们已经多次看到的相同执行流程时所做的那样，
我们可以使用 terraform 计划创建资源，
然后使用 terraform
应用资源现在已
按预期创建，
如果您想
通过更改现有参数来更新资源，
我们可以通过
更新 variables.tf 文件来实现
，main.tf 不需要修改
，例如让 我们更新本地文件
资源
以在同一位置创建文件，
但更新
内容读取我最喜欢的宠物是
胡须夫人
，对于随机宠物资源让我们
将宠物名称的长度更改为两个
我们可以这样
做 预期当我们运行 terraform apply
它将重新创建资源
文件的内容已更改
，并且宠物名称现在
在前缀后面有两个词，
然后我们结束本讲座这里是
我们的配置
文件
在创建时的样子的示例
带有 terraform 的 aws 中的 ec2 实例，
同时使用输入变量
，如果资源块
和参数不熟悉，请不要担心
我们有一个单独的讲座，我们将在那里学习
在本讲座的课程后面的 aws 资源的使用
我们将仔细
研究 terraform 中的变量块
首先让我们看看
变量块使用
terraform 中的变量块的不同参数访问
三个
参数第一个我们 have already used
是默认参数，
这是我们
为变量指定默认值的地方，
其他是类型，描述
description 是可选的，但
使用此参数来
描述变量
用于类型参数是可选的是一个很好的做法 同样，
但是当使用它时，
它强制
使用
的变量类型可以使用的基本变量类型
是字符串
数字和布尔字符串变量，
正如我们在我们的示例中看到的那样，目前
接受一个可以是字母数字的单个值
，它由 字母和
数字 number 变量类型接受
一个数字的单个值，
它可以是正数或负数
，布尔变量类型接受 sa
值为 true
或 false 前面提到的类型参数
是可选的，
如果它没有在变量
块中指定它默认设置为类型
any 除了这三个
简单的变量类型
trafform 还支持其他类型，
例如列表
映射集对象和 tuple
现在让我们看看如何在 terraform 中使用所有这些
让我们从列表开始，一个列表是一个
编号的值集合
，它可以像这样定义
在这个例子中我们有一个名为 prefix 的变量
，它使用一个值列表 mr mrs
先生，
但为什么我们称它为编号
集合，因为每个值
也称为元素
可以由该列表中的数字或索引引用
，
列表的索引总是
从零开始，
在这种情况下是第一个元素
索引 0
处的列表的单词 mister 索引 1 处的元素
未命中，索引 2 处的最后一个元素
是 Sir 这些变量可以
在这样的配置文件
中使用索引访问
在方括号内指定
因此表达式 word.prefix 与索引 0
使用值 mister
one.prefix 与索引 1 使用值 Missus
和索引 2 它使用值 Sir
接下来让我们看看称为 map 的类型
地图是 在 variables.ta 文件中以键值对格式表示的数据
让我们创建一个
名为
file content 的新变量，其类型设置为映射
到默认值中，我们可以在此处指定尽可能
多的键值对
括在花括号
中 语句 1 和语句 2 是键
，它们后面的字符串数据
现在是值，用于
从
terraform
配置文件中的地图访问特定值，我们可以使用
键匹配，
在这种情况下，我们希望
本地文件资源的内容是值
称为 statement2 的键
，为此我们使用表达式
var.file content
，它是映射类型变量的名称，
后跟
方括号内的匹配键，
我们也可以组合类型 con
例如，
如果您想要一个字符串类型元素列表，
我们可以像这样声明
它以使用数字列表
如果使用的变量值与约束类型不匹配
terraform 命令将在此
示例中失败
我们有 使用了类型列表，其中
元素应该是数字类型，
但现在默认值都是字符串类型，
当我们运行 terraform 命令（
例如计划
或应用）时，您将看到类似这样的错误
，
指出默认值不兼容
使用变量类型约束
并且需要数字而不是
字符串
，同样适用于映射
，我们可以使用类型约束来
确保映射的值
在我们所在的第一个变量块中属于特定类型 使用
字符串类型的映射
，在第二
个映射中，我们使用了一个使用数字的映射，
现在让我们看看集合与
列表相似，
集合和列表之间的
区别在于集合不能
在这些例子中有重复的元素我们有一组可变
类型
的字符串或一组数字
左边的例子很好，
但右边的不是它们中
有重复的值，
它们会抛出错误默认
值 声明
就像你对列表所做的一样，但
请记住，这里不应该有任何
重复的值
，我们将要查看的下一种变量类型
是
带有对象的对象，我们可以通过组合所有变量类型来创建复杂的数据
结构
例如，让我们考虑一个名为 bella 的新
变量
，它是一只猫的名字，这个
变量用于定义草图的不同
特征，例如
它的名字是一个字符串，
颜色是一个字符串作为 嗯，这是一个
数字
，它吃的食物是一个字符串列表
和一个布尔值，指示它是否是
最喜欢的赌注
让我们现在为这个变量分配一些值
让我们使用
name 等于 bella 颜色等于
棕色
年龄等于 7 食物是鱼
鸡肉和火鸡 最喜欢的
赌注 设置为
true 我们可以在变量块中使用相同的默认值
是元组元组类似于列表
，由一系列元素组成
元组和列表之间的
区别在于列表使用相同
变量类型的元素，
例如字符串或数字，但在元组的情况下，
我们可以使用以下元素 不同
的变量类型 要在
元组中使用的变量类型
在本例中的方括号内定义 我们定义了三种类型的
元素
第一个是字符串 第二个是
数字 最后一个布尔值
要传递给 this 的变量应该
正好是 3 的数字和
特定类型的它在
这里工作我们已经将 cat 的值传递
给字符串元素，
将数字 7 传递给数字元素，并将
true 传递给布尔值，
添加额外的元素 ents 或不正确的
类型将导致错误，如
这里所见，
如果您向变量中添加 dog 的附加值，
它将失败，因为元组只需要
三个类型为 string
number 和 boolean 类型的元素，这就是本
讲座的内容
让我们转向手 - 在实验室和
探索在本讲座中使用 terraform 中的变量类型，
我们将看看在 terraform
中使用输入变量的不同方式，
到目前为止，
我们已经在 terraform 中创建了输入变量
并为其分配了默认值。
在变量类型上，这只是
将值传递给变量的一种方式，
之前我们了解到
变量块中的默认参数是
可选的，这意味着我们可以
很好地让变量块
看起来像这样，但是
如果 我们现在运行 terraform 命令，当
我们在 terraform apply 上时，
如果您
不想在
in 在交互模式下，
我们也可以在 terraform 命令中使用这样的命令行
标志
，我们可以
使用 dash war 选项，其中
变量名等于
值格式，我们可以通过此方法传入任意数量
的变量 多次使用破折号或标志
，
我们还可以使用环境
变量，其中 tf
下划线 var 下划线后跟
声明变量的名称，
如本示例中所示
，tf 下划线战争下划线文件
名设置名为 filename 的变量的值
到值 slash root pets.txt
并且类似地，名为 length 的变量
现在的值为
2。最后，当我们处理
大量变量时，
我们可以通过使用这样的变量定义文件来加载值，
这些变量定义
文件可以 可以命名为任何名称，
但应始终以 .tfrs
或 tfos.json 结尾，这里
我们已经
在名为 terraform.tf-force 的文件中声明了变量和值，
如果您查看
用于创建此文件的语法
您会发现它使用
与 hcl 文件相同的语法，
但它仅包含
变量定义文件（如果称为
terraform.tfrs
或 teform.tfrs.json 或以任何其他名称
结尾）。 auto.efrs 或 dot
auto.tfs.json
将由 terraform 自动加载，
如果您使用任何其他文件名，例如
variable.tfrs 例如，
您必须将它与
名为 dash war dash file 的命令行标志一起传递，
最后像这样
需要注意的是，我们可以使用
我们在本讲座中看到的任何选项
来为
变量赋值，
但是如果我们使用多种方式
为同一变量赋值
terraform 遵循变量
定义优先级以了解
它的值 应该接受
来说明这一点让我们使用一个
简单的例子，
在这种情况下，我们有一个
带有单个资源的主配置文件，
一个本地文件，它将
在变量中声明的路径上创建文件 能够
在 variables.tf 文件中调用文件名我们没有
为此变量指定默认值
，我们以多种方式为此变量分配了不同的值
我们导出了
名为 tf underscore y
underscore 文件名
的环境变量，值为斜杠 root
slashcats.text terraform.ta4 文件的值是
slashroot patch.txt，
我们还使用了一个名为 variable.auto.tfors 的变量
定义文件
，其值为 root mypet.txt
，最后 我们还在
运行 terraform
apply 命令时使用了 dash war 选项，其值为斜杠
根
最佳宠物点文本，因此在这种情况下
，这些值中的哪一个将被
接受
terraform 遵循变量定义
优先顺序来首先确定它
在 terraform.tf wars 文件中的值旁边加载环境变量，
然后是任何
以 alph 中的点 auto.tfrs 或点 auto.tfrs.json 结尾的文件 abetical
order
和最后 terraform 考虑具有最高优先级
的 dash war
或 dash war dash 文件的命令行标志，
并会覆盖任何先前的
值，
在这种情况下，变量文件名将
被分配为 slashroot bestpet.txt 的值
，就是这样 对于本次讲座，
让我们前往动手实验室并
练习使用
我们在本次讲座中学到的概念 在本次
讲座中，我们将学习如何
通过利用
在上几堂课中看到的资源属性将两个资源链接在一起 现在为了
使用变量来提高代码的可重用
性，
我们的配置文件中有两个资源，
每个资源都有一组
参数，用于为文件资源创建该
资源
，我们使用
文件名和内容作为 参数
和宠物资源我们在应用此配置时使用
了前缀分隔符
和长度
terraform 创建一个文件和一个随机
宠物资源 因为
随机宠物的名字
在屏幕上显示为一个
id，在这种情况下是公牛先生，
因为这两种资源之间没有依赖
关系，
但这在现实
世界的基础设施配置
过程
中很少发生，肯定会有
多个相互依赖的资源，
如果你想
利用一个资源的输出
并将其用作另一个资源的输入，
如果我们希望文件的内容
使用随机宠物资源生成的名称怎么办
目前文件的内容被设置
为我最喜欢的宠物是猫先生
但是如果我们希望它被设置为
随机宠物资源生成的名称
来理解这一点让我们跳回
随机宠物资源的文档 在
registry.terraform.io 中，
您会注意到文档
中提供了大量示例，
包括参数示例，但
还有一个称为
属性引用的部分 它提供了
在运行 terraform apply 后从资源返回的属性列表，
在这种情况下，随机宠物资源
仅返回一个名为 id 的属性
，它是字符串类型，id
是我们运行 terraform apply 后生成的宠物名称
之前看到
我们的目标是使用名为 id 的属性
并将其用作
本地文件资源
的内容为此我们可以使用
这样的表达式 此表达式用于
从名为的资源中引用属性 mypet
使用此引用表达式的语法
是
资源类型，后跟资源
名称和要使用的属性，
所有这些都用句
点或点分隔
本示例中的资源类型是
随机宠物
，其后是 mypet，它是
资源名称
和属性使用 id 您
还会注意到
我们使用美元符号，
后跟用
大括号括起来的表达式 s
这被称为插值
序列，
因为内容参数已经使用
了字符串类型的数据，
这个序列用于评估
花括号内给出的表达式，
将结果转换为字符串，然后
像这样将其插入到最终字符串中，现在让我们 应用
所做的更改并允许 terraform 在输出中重新创建
本地文件
，您可以看到
内容正在被替换
为我们想要的值，并且它包含
由随机宠物
资源
生成的宠物名称，这就是现在的讲座 让我们
前往动手实验室，并
在本讲座中探索在 terraform 中使用引用表达式和资源属性的工作 我们将在上一堂课中了解 terraform
中不同类型的资源
依赖关系
我们看到了如何
将一个资源链接到另一个资源
通过使用参考表达式
和插值使用参考属性，
我们能够
利用随机投注资源的输出 urce 现在
作为本地文件资源的输入，
当 terraform 创建这些
资源时，它知道依赖关系，
因为本地文件资源依赖于
随机电池源的输出，
因此它使用以下顺序
来提供它们
首先 terraform 创建随机 pet
资源，然后
在删除资源时创建本地文件资源 terraform
以相反的顺序删除
本地文件，然后是随机
pet
这种类型的依赖项称为
隐式依赖项，
这里我们没有明确指定
依赖哪个资源 哪些
其他资源
terraform 自己计算出来，
但是
还有另一种方法可以
在配置文件中指定依赖项
，例如，如果您仍然想确定，让我们使用较旧的
配置文件而不使用
文件内容的引用表达式
本地
文件资源是在随机宠物之后创建的，
我们可以通过使用来做到这一点 g
像这样的依赖参数我们在本地文件
的资源块内添加了一个依赖参数，
并且我们提供了一个
依赖项列表，其中包括名为 mypet 的随机宠物
资源，
这将确保
仅创建本地文件 在随机宠物资源创建之后，
这种类型的依赖被称为
显
式依赖，
只有
当
资源间接依赖其他资源
并且它不使用引用
表达式时，才需要明确指定依赖，如
在后面部分中看到的这种情况 在本课程中，我们
将看到如何以及何时在
实际
用例中使用它 现在让我们进入
动手实验室并探索
在 terraform 中使用资源依赖项
现在让我们看看 terraform 中的输出变量
到目前为止我们已经有了 在我们的 terraform 配置文件中使用了输入变量和
引用表达式
以及输入变量 terraform
还支持
输出变量 这些变量可
用于在 terraform 中存储表达式的值，
例如让我们回到上一课中
使用的配置文件，
我们已经知道随机投注
资源将
使用名为 id 的属性生成随机宠物名称 当我们
应用
配置将这个 id 保存在一个名为 pet name 的输出变量中时，
我们可以创建一个这样的输出块
，用于创建这个输出块的语法
是关键字
output 后跟我们想要在 this 中
调用这个变量的名称
block value 的强制参数
是引用表达式
我们还可以添加一个描述，它是
一个可选参数，用于描述
当我们运行 terraform apply 时创建此块后此输出变量将用于什么我们可以
看到输出变量是
创建资源后在屏幕上打印我们
还可以使用
terraform output 命令来打印
输出变量的值
bles 命令 terraform output 本身
将打印
当前配置目录中所有文件中定义的所有输出变量
我们也可以专门使用此命令
来打印
现有输出变量
的值，现在您可能想知道我们
可以在哪里使用 在这些输出变量中，
我们已经看到依赖资源
可以使用引用表达式
从一个资源块中获取输出
作为另一个块的输入，
因为这里并不真正需要这样的输出变量
最好在
需要时使用 terraform 输出变量 要在屏幕上快速
显示有关供应资源的详细信息，
或将输出变量提供给其他
iac 工具，
例如用于配置管理和测试的附加脚本或 ansible
剧本，
现在让我们前往动手实验室
并练习使用
在本讲座中我们将
看到在 terraform 中使用 state 的目的
我们已经看到了 terraform 如何使用 st ate
文件将资源配置映射
到现实世界的基础设施，
此映射允许 terraform 在
确定
资源配置文件
和状态之间存在偏差时创建执行计划，因此状态文件可以被
视为
所有资源的蓝图 适用
于现实世界中的管理者，
当 terraform 创建资源时，
它会在状态中记录其身份，
无论是在机器中创建文件的本地文件资源
还是逻辑资源，例如随机
宠物，它只会抛出随机宠物
名称
或云中的资源 每个
由 terraform 创建和管理的资源
都有一个唯一的 id，用于
识别现实世界中的资源，除了配置中的资源与现实世界
之间的映射之外
，状态文件还跟踪元数据的
详细信息，例如资源
之前我们了解到我们的表单
支持两种类型的
依赖：隐式和显式，如果
我们 查看示例配置文件，
我们可以看到我们在
这里提供了三个资源，
名为 pet 的本地文件资源
取决于随机 pet 资源，
这从使用对随机 pet 资源的引用
的本地文件资源块中的 content 参数可以看出
名为 cat 的本地文件资源
与另一个文件资源无关
，因此
当我们应用此配置时，它可以与随机宠物资源并行创建，
名为 mypet 的随机电池源
和名为 cat 的本地文件可以同时
首先创建
，但是 名为pet的本地文件
资源
只能在随机宠物
资源创建后
才能创建我们可以看到，名为cat的本地文件
和名为mypet的随机宠物资源
是最先
创建的资源
，只有这样才能创建 迄今为止创建的
名为 pet 的本地文件资源，
我们不依赖
状态进行配置，
但是如果我们决定删除
随机宠物怎么办 配置中的资源
和依赖的本地文件
让我们现在看看当我们从文件中删除资源时会发生什么，例如，如果我们要应用配置，我们会
从文件
中删除本地文件
和随机宠物资源，
现在 terraform 知道它 必须
删除这些资源，
但是如果它首先删除随机宠物资源或本地文件，它会以什么顺序删除它
，
有关资源
依赖项的信息在配置文件中不再可用，
因为我们已从中删除了这些行，
这是 terraform 依赖于
状态以及它
在状态文件中跟踪元数据的事实，我们可以清楚地看到
，名为 pet 的本地文件资源
依赖于随机 pet
资源，
因为这两个资源现已
从配置中删除
terraform 现在知道 它应该
首先删除本地文件，
然后是随机资源
，使用状态的另一个好处是
性能
w 在处理少量
资源时，
terraform
在
每个 terraform 命令（例如
plan 或 apply）之后协调状态与现实世界的基础设施可能是可行的，但在现实世界中，
terraform 将管理
成百上千的此类资源，
并且何时这些资源 分布
到多个提供者
，尤其是那些在
云上的提供者 terraform 为每个 terraform 操作协调状态是不可行的，
这是因为
在某些
情况下，terraform 需要几秒钟到几分钟才能
从 为大型基础设施
配置的所有提供者
在这种情况下，这可能会
被证明
太慢 在状态中
，我们可以专门制作 terraform
来参考 在运行命令时单独到状态文件，
并绕过
每次都必须刷新状态
来执行此操作，我们可以使用破折号
刷新等于错误标志
以及所有使用状态的 terraform 命令，
当我们使用它运行计划时 标志你
可以看到我们的表单不刷新
状态
而是依赖于缓存的
属性，在这个例子
中配置文件中已经更改的内容
，因此执行计划绘制
了资源替换
状态的最终好处，我们是
正如
我们在之前的讲座中所看到的那样，团队合作时要看看
terraform 状态文件存储
在同一配置目录中的一个
名为 terraform.tf state 的文件
中，在正常情况下，这意味着
状态文件驻留在
最终用户笔记本电脑中的文件夹或目录，
这在从
terraform 学习和
单独实施小项目开始时没问题，
但这还很远 从理想
的团队合作开始，
团队中的每个用户都应该
在运行 terraform 之前始终拥有最新的状态数据，
并确保没有其他人同时运行
terraform
不这样做可能会导致
不可预测的错误
，因此在这种情况下
强烈建议将此
terraform 状态文件保存
在远程数据存储中，而不是
依赖于本地副本，
这允许
在团队的所有成员之间安全地共享
状态远程状态存储的示例是
亚马逊网络服务
s3 服务 hashicorps 控制台 和
terraform cloud
我们将
在后面的部分中更详细地了解远程状态存储
我们还将了解改革云
和它自己的一个单独部分
现在让我们前往动手实验室
并探索在 terraform state
中的工作 之前的讲座我们
了解了 terraform state 及其好处
terraform state 是
terraform 了解什么是唯一的事实来源
部署在现实世界中，
但是在使用 state 时需要注意一些事项
，我们将在本讲座中了解它们
state 是 terraform 中的一个非可选功能，
但是有一些注意事项
首先是 state 文件
其中包含敏感
信息，其中包含
有关我们基础架构的所有小细节，
这里是 aws ec2 实例的状态文件示例片段，该
实例
本质
上是 aws 云上的虚拟机，
该状态文件包含
虚拟机的所有属性，即
提供诸如
分配的 CPU 内存
操作系统或图像使用的磁盘类型和大小
等它还存储信息，例如
分配给 vm 的 IP 地址
和使用的 ssh 密钥对
等资源（例如数据库）
状态还可以存储
使用本地状态时的初始密码状态
存储在纯文本
json 文件中，如您所见，此
信息可以归类为
敏感信息，因此我们
需要确保状态文件
始终存储在安全存储中，
因此我们的配置目录中有两种
文件：存储基础设施状态的 terraform 状态文件
和我们使用的 terraform 配置
文件 用于在
团队合作时提供和管理基础设施
，
将 terraform 配置文件存储
在分布式版本控制系统
（如 github git lab 或 bitbucket）
中被认为是最佳实践，但是
由于状态
文件的敏感性，不建议存储 它们在
git 存储库中
而不是将状态存储在远程
后端系统中，例如 aws s3
谷歌云存储 azure 存储
terraform 云等
我们将看到如何
在其自己的专用部分中使用远程状态后端
，
但现在重要的是
这些注意事项的说明
terraform state 是一个 json 数据结构
，旨在供 terraf 内部使用
或者
我们永远不应该自己手动尝试
编辑状态文件，
但是在某些情况下，
我们可能想要更改状态
文件
，在这种情况下，我们应该依赖
terraform 状态命令，
我们将在课程的后面部分介绍这些命令
到目前为止，我们已经看到了相当多的
terraform 命令正在运行，
例如 terraform init plan 和
apply
现在让我们看看
terraform 中可用的更多
命令 我们将看看的第一个命令
是编写后的 terraform validate
命令 我们的配置
文件没有必要运行 terraform plan
或申请检查所使用的语法是否
正确，
而是我们可以像这样使用 terraform
validate 命令
，如果文件一切正常
，
我们应该看到这样的成功验证
消息，
如果 配置文件中存在错误，
验证命令将向您显示
文件中导致错误的行
以及修复它的提示
我 在这个例子中，我们对本地文件资源使用了一个
错误的参数
它应该是文件权限而不是
文件权限
我们将看到的下一个命令
是 terraform fmt
或 terraform format 命令 此
命令扫描当前配置
文件 工作目录
并将代码格式化为规范
格式
这是一个有用的命令，可
提高 terraform
配置文件的可读性
当我们运行此命令时
配置目录中更改的文件
显示在屏幕
上 terraform show 命令打印出
在这个例子中 terraform 看到的基础设施的当前状态
我们已经创建了本地文件
资源
，当我们运行 show 命令时，它
会显示资源的当前状态，
包括
terraform 为该资源创建的所有属性，
例如文件名 文件和目录
权限的
内容以及它们的来源的 id
我们还可以使用 json 标志以
json 格式打印内容以查看
配置
目录中
使用的所有提供程序的列表 使用 terraform providers 命令
您还可以使用 mirror sub
命令将当前配置所需的提供程序插件复制
到另一个 像这样的目录 此
命令将镜像提供程序
配置在新路径中
使用命令 terraform output
您还可以
通过将变量的名称附加到
输出命令的末尾来打印特定变量的值，
就像这样 terraform refresh
命令用于将 terraform 与现实
世界的基础设施同步
，例如，如果有
对 terraform 在其控制之外创建的资源所做的任何更改，
例如手动
更新 terraform refresh 命令将
拾取它并更新状态文件
此协调有助于
确定在下一次应用期间要采取的操作
此命令不会修改任何
基础设施资源，
但它会修改状态文件，
正如我们之前看到的 terraform refresh
也运行 由
terraform plan
和 terraform apply 等命令自动执行，这是
在
terraform 生成执行计划之前完成的，
但是可以通过使用
破折号刷新等于 false
选项绕过
命令 terraform graph 命令用于
创建可视化表示
在此示例中，terraform 配置或执行计划中
的依赖项 我们的 main.ta 文件中的本地文件
依赖
于随机宠物资源 此命令
可以在
配置文件准备好
甚至在初始化之前立即运行
运行
terraform graph 命令后，
您应该会看到带有 terraform 的配置目录 像这样的
文本生成的输出很难理解
，但它是一个以称为点的格式生成的图形，
以便使该图形更有意义
我们可以通过图形
可视化软件（
例如 graphiz）传递它，我们可以将其安装在
ubuntu 使用
apt 安装后，
我们可以将 terraform 图形的输出传递
给我们使用图形面包安装的 dot 命令，
并
生成这样的图形
我们现在可以通过浏览器打开此文件
，它应该显示
依赖关系图
像这样 root 是这个图的配置所在的配置
目录
我们可以看到有两个资源，
一个叫做 pet 的本地文件和一个叫做 my pet 的随机
宠物资源
，它们分别使用了本地和
随机提供者
，最后 我们可以看到
名为 pet 的本地文件
依赖于名为 mypet 的随机宠物资源，
因为我们在本地文件资源中使用了一个引用
表达式
，指向 到本讲座的随机宠物的 id
现在让我们
前往动手实验室并
探索使用
我们在本节本讲座中学到的 terraform 命令
我们将了解
可变和不可变基础设施之间
的区别 我们在之前的讲座之一中看到
，当 terraform 更新资源（
例如更新本地文件的权限）时，
它首先销毁它，然后
使用新权限重新创建它，
那么为什么 terraform 会这样做以
了解这一点，
让我们使用一个简单的方法 例如，
考虑一个运行
1.17 版本 nginx 的应用服务器，
当新版本的 nginx 发布时，
我们首先将在该 Web 服务器上运行的软件
从 1.17 升级到 1.18
，最终当新版本
1.19 发布时，
我们以相同的方式从 1.18 升级 到
1.19
这可以使用多种
不同的方式来完成
一个简单的方法是下载
所需的 nginx 版本
，然后将其用于 manu 在维护窗口期间升级
Web 服务器上的软件
当然我们
也可以使用诸如 addox 脚本之类的工具或诸如 ansible 之类的
配置管理工具
来实现这一点以
实现高可用性而不是
依赖一台 Web 服务器
我们可以拥有一个池 在
所有运行相同软件和代码的 Web 服务器中，
我们必须使用与我们用于第一个 Web 服务器相同的方法
对这些服务器中的每一个使用相同的软件升级生命周期，
这种类型的更新称为就地
更新
，这 是因为底层
基础设施保持不变，
但这些服务器上的软件和配置
作为更新的一部分发生了变化，这是
一个系统上可变基础设施
更新软件的示例可能是一项
复杂的任务
，几乎在所有情况下都有 在升级成功执行
之前必须满足一组依赖项
让我们假设 Web 服务器 1 和 2
在我们尝试
将版本从 1.18 升级到 1.19 时满足所有依赖项
，结果这两个服务器
升级没有任何问题
Web 服务器 3 另一方面，
Web 服务器 3 上的升级不会失败，
因为它有一些依赖项
未满足
，因此它仍保留在 1.18 版中
。
升级失败可能是
由于多种原因造成的，例如
影响
到软件存储库
文件系统的连接的网络问题 与其他两个相比，
在 Web 服务器 3 上运行的完整或不同版本的操作系统，
但是
这里要注意的重要一点 是
我们现在有一个由三个 Web 服务器组成的池，
其中一个服务器
运行不同版本的软件，
而其他服务器
随着时间的推移
对该服务器池进行了多次更新和更改
，这些服务器中的每一个都有可能
彼此不同
可能是软件、配置或
操作系统等，
这被称为配置漂移
，例如在几个更新窗口之后，
我们的三个 Web 服务器可能看起来像
这个
Web 服务器 1 和 2 的 nginx 版本为
1.19
和 Web 服务器 3 有一个 1.18 版本
，所有三个 Web 服务器也可能
在它们上面运行略有不同版本的操作系统，这种
配置漂移
可能会导致 使基础设施处于
复杂状态，使其难以
计划
和执行后续更新
故障排除问题也将是一项
艰巨的任务
，
因为由于
这种配置漂移，
而不是更新
Web 服务器上的软件版本，每台服务器的行为都会与其他服务器略有不同
我们可以使用更新的软件版本启动新的 Web 服务器
，然后删除旧的 Web 服务器，
因此当我们想要将 nginx 1.17 更新到
1.18 时，如果更新通过，则新服务器将配备 1.18
版本的 nginx
，那么旧的
Web 服务器是 删除了
这被称为不可变的
基础设施
不可变意味着不变或
您无法更改
的内容，因此使用不可变的
基础设施我们无法再
对资源进行就地更新
这并不意味着以
这种方式更新网络服务器不会导致
故障
如果升级因任何原因失败，
旧的 Web 服务器将保持不变
，而失败的服务器 er 将被删除
，因为我们
不会在我们的服务器之间留下太多的配置漂移空间，
确保它处于一个简单
易懂的状态，
并且由于我们正在使用
基础设施作为代码不变性
使得版本化更容易
基础设施
并在版本之间回滚和前滚
terraform 作为基础设施
配置工具使用这种
方法返回到我们的示例更新
本地文件资源的资源块
并将权限从 777 更改为
700
将导致原始文件被
删除 并且默认情况下要
使用更新权限
创建的新文件 teform 在创建新资源之前首先销毁资源，
但是如果我们希望在删除旧资源之前先创建资源
或完全忽略删除
怎么办 我们这样做可以通过
在我们的资源块中使用生命周期规则来完成
，我们将在接下来的内容中看到如何做到这
一点 是部分我们将学习如何
在 terraform 中设置生命周期规则
之前我们看到当 terraform
更新资源时，
它释放了基础设施使其
不可变，并
在
创建
具有更新配置的新资源之前首先删除资源，
例如，
如果我们更新文件 将
本地文件资源的权限
从 777 设置为 700
，然后运行 terraform apply 您会
看到
旧文件先被删除，然后
现在创建新文件，
这在所有情况下可能不是一种理想的方法
，有时您可能需要更新
在删除旧资源之前首先创建资源的版本，或者
您可能根本不希望资源被
删除，即使
在其本地配置中进行了更改，
这可以通过使用生命周期规则在 terraform 中实现
这些规则使用了
迄今为止我们已经多次看到的相同块语法
，它们直接进入
我们想要改变其行为的资源块
内部 ge
具有生命周期规则的资源块的语法
在生命周期块中看起来像这样
我们添加了我们希望 terraform
在更新资源时遵守的规则
，一个这样的参数或规则是
在销毁规则之前创建
我们在这里有相同的
已使用 create before destroy 生命周期规则更新的资源块
设置为
true
此规则确保当配置更改
强制重新创建资源时，
首先创建新资源，然后删除旧资源，
现在会出现以下情况 不
希望资源因任何原因被销毁，
我们可以
在设置为 true 时使用防止销毁选项 terraform 将
拒绝任何会
导致资源被销毁的更改，
并显示如下错误
消息 对于防止
您的资源被意外
删除特别有用，
例如
mysql
或 postgresql 等数据库资源可能不是某些东西
我们想在
配置后删除的一件重要
事情是，
如果您使用 terraform destroy 命令，该资源仍然可以被
销毁，
此规则只会防止
因对配置所做的更改
和随后的应用而删除资源
我们将在这里看到的最后一个参数类型
是忽略更改规则
，应用此生命周期规则
将阻止
根据
我们在生命周期块中定义的属性列表更新资源，
以便更好地理解这一点让我们使用
示例 ec2 实例
，它是 aws 云上的虚拟机，
此 ec2 实例将用作 Web
服务器，可以使用这样的简单资源块创建，
如果此资源
块和参数看起来不熟悉，请不要担心
将在课程的 ec2 部分更详细地介绍它，
但现在请注意，
名为 web server 的资源使用了
三个
参数 ami 并且实例类型
用于部署
具有预定义规范的特定类型的 vm
在这种情况下，我们选择的值
部署具有一个
cpu 和 1 gb ram 的 ubuntu 服务器，
我们还使用了一个名为 name 的标签
，它具有 project a web
server 使用 tax 参数
的值，当我们运行
terraform apply 时
，ec2 实例将按预期创建，
并使用
名为 name 的标签和 project a web server 的值，
如果对其中任何一个进行更改
参数
terraform
将按预期在下一次应用期间尝试修复它
，例如，如果我们修改名为 name 的标签
并将其值从 project a web
server 更改为
project b web server，手动
或使用任何其他工具
terraform 将检测到此更改，并且 它
会尝试将
其改回原来的样子，
在极少数情况下，我们可能实际上
希望更改名称，
而其他任何方法都是可以接受的，
并且 我们想要防止 terraform
恢复到旧标签
来做到这一点，我们可以使用
生命周期块和 ignore changes
参数
这样的 ignore changes
这样的 ignore changes 参数
接受一个由方括号指示的列表
，并将接受任何有效的资源
属性 在这种特殊情况下，我们要求
terraform 忽略
对特定 ec2 实例的 tags 属性
所做的更改，如果对标签进行了更改，
随后的 terraform 应用
现在应该显示没有
更改可以应用
对标签所做的更改
terraform 之外的服务器现在完全
被忽略
，因为它是一个列表，我们可以更新更多这样的
元素，
您也可以用 all 关键字替换列表，
如果您
不想修改资源以进行
更改，这尤其有用 任何资源属性
，当我们使用 aws 资源时，我们将在课程后面学习更多关于生命周期规则的
信息，
但现在这里是一个快速总结
我们在本讲座中看到的三种参数类型
现在让我们转到动手
实验室并练习
在 terraform 中使用生命周期规则
在本节中 我们将看看 terraform 中的
数据源
我们现在知道 terraform 使用
配置
文件和状态文件一起
提供基础设施资源，
但正如我们之前看到的，terraform 只是
基础设施之一，作为可用于提供基础设施的代码工具
，可以
使用其他工具进行配置，
例如
puppet Cloud Formation salt stack
ansible 等
更不用说临时脚本和
手动配置基础设施
，甚至是
terraform 从另一个配置
目录创建
的资源，让我们假设
数据库实例是
在 aws 云中手动配置的，
尽管 terraform 不管理此
资源，但它可以读取属性，例如
作为数据库名称
主机地址或 db 用户并使用它
来提供
由 terraform 管理的应用程序资源
让我们举一个更简单的例子，我们有一个
名为 pet 的本地文件资源，
其中包含我们爱宠物的内容，
一旦配置了该资源，就会
在斜杠根目录中创建
文件，并且还会存储有关此文件的信息
在 terraform 状态文件中，
现在让我们使用像这样的简单 shell 脚本创建一个新文件，
很明显这个文件
在 terraform 的控制和管理之外
，此时
terraform 负责的本地文件资源是
pets.txt 下 根目录，
与名为 docs.txt 的本地文件没有关系，该文件
也在
斜杠根目录
下创建 docs.txt 有一行表示
狗很棒，我们希望
terraform 使用此文件作为数据源
和
如果我们想利用
这个由批处理脚本创建的新文件的属性，则使用它的数据作为
我们现有文件 pets.txt 的内容。 n 利用数据源
数据源允许 terraform
从其控制之外提供的资源
中读取属性，例如从
名为 docs.txt 的本地文件中读取属性，
我们可以
像这样在配置文件中定义一个数据块
，您可以 已经注意到数据块
与资源块非常相似，
而不是名为 resource 的关键字
我们定义了一个数据源块
，其中关键字名为 data
这后面是我们试图读取的资源类型，
在这个例子中它是一个本地文件
这可以是
terraform 支持的任何提供程序的任何有效资源类型
接下来是逻辑资源
名称，资源的属性
将
在块中读取我们有参数
，就像我们在普通资源
块中一样，数据源块由
数据源的特定参数并知道
需要哪个参数，我们可以
查找提供的文档和
terraform 注册表
对于本地文件数据源，我们
只有一个应该使用的参数，
它是要读取的文件名，
然后从数据源读取的
数据在数据对象 interterra 形式下可用，
以便在资源调用 pet 中使用此数据，
我们 可以简单地使用
data.localfile.doc.content
这些细节当然可以在
文档内的数据源下的 terraform
文档和导出的属性下找到
我们可以看到本地文件的数据源
公开了两个
属性 content 和 base64
内容的编码版本
以区分资源和
数据源 让我们做一个快速比较
使用资源块创建资源
和使用数据块创建数据源
terraform 中的资源
用于创建
更新和销毁基础设施，
而数据源是 用于
从特定资源中读取信息的
常规资源也称为
托管资源，因为它是一种
扩展 由 terraform
数据源管理 也称为数据
资源
这就是本讲座的内容 现在让我们
前往动手实验室并
练习在本讲座
中使用 terraform
中的数据源 我们将看看 terraform 中的
元
参数 直到现在
我们 已经能够使用 terraform 创建单个
资源，
例如本地文件和随机宠物
例如本地文件和随机宠物资源，
但是如果您想创建
同一资源的多个实例，
例如，
如果您使用的是 shell 脚本或
其他一些编程语言，请说三个本地文件
我们可以在这个例子中创建多个这样的文件
我们创建了一个名为 createfiles.sh 的 bash
脚本
，它使用 for
循环在根目录中创建空文件，
这些文件将被称为 pet 后跟从
1 到 3 的范围。
而我们 不能使用与
资源块中相同的脚本
terraform 提供了多种替代方案来
实现相同的目标，
这些可以通过使用
特定的 terraform 中的
元参数可以在任何资源块中使用元参数
来改变资源的行为，
我们已经在本课程中看到了两种类型的元
参数，
它们依赖于定义
资源之间的显式依赖关系
和定义如何使用的生命周期规则
资源应该
在 terraform 中创建更新和销毁
现在让我们看看更多
与 terraform 中的循环相关的元参数
在本讲座中我们将
看看 for each meta 参数
及其在 terraform 中的用途我们在上
一堂课
中看到 当我们使用 count 时，
资源被创建为一个列表
，这在更新它们时可能会产生不良结果
，
解决这个问题的一种方法是
使用 for
each 参数而不是像这样的 count
将文件名的值设置为
每个 列表中的元素，
我们可以像这样使用每个点值的表达式，
但是
如果我们现在运行 terraform plan 就会有一个问题，我们将设置 e
一个
错误 for each 参数仅适用于 variables.tf 文件中的
映射或集合
，我们
目前正在使用
包含字符串元素的列表，
有几种方法可以解决此问题，
或者将名为 file name 的变量更改
为
在变量讲座中我们
了解到集合类似于列表，但是
一旦我们更改变量类型，
然后运行 terraform plan，它就不能包含重复的元素，
我们应该看到要创建三个文件
来解决此错误
将变量类型保留为列表
是为了使用另一个内置
函数，
这次我们将使用两个 set
函数，该函数将在完成后将变量
从列表
转换为集合
terraform plan 命令现在应该
按预期工作
现在让我们复制与
我们之前使用 count 元参数所做的相同的场景，并
在运行 terraform plan no 时从列表中删除值为 slash root bets.txt 的第一个元素 我们可以
看到只有一个资源被设置为
销毁
名为 pets.txt 的文件，
其他资源将保持不变
以查看这是如何工作的让我们创建
一个名为 pets 的输出变量
来打印资源详细信息，就像我们
所做的一样 使用
terraform 输出命令中的 count 的示例我们
现在可以看到，
当我们使用 for each
而不是 count 资源被
创建为地图
和订单列表时，资源被存储为地图而不是列表，这意味着
资源不是 不再由索引标识，
从而绕过了我们在使用 count 时看到的问题，
它们现在由
文件名 slash root slash
dot dot txt
和 slash root cache dot txt 标识，
它们由
配置中的每个参数使用
如果我们将其与
使用 count 时获得的早期输出进行比较，我们
可以看到
资源创建方式
的差异 count 选项将其创建为列表，
而
对于每个将其创建为列表 map
在 terraforms 中还有一些其他元参数，
例如供应
商提供程序后端等我们将
在本课程的后面看到，
现在让我们转到动手实验室
并练习使用
terraform 中的每个元参数
讲座我们将看到如何
在 terraform 中使用特定的提供程序版本我们之前看到，
提供程序使用基于插件的
架构
，并且大多数流行的程序都
可以在公共
terraform 注册表中使用而无需额外
配置 terraform init 命令下载
最新版本的 配置文件所需的提供程序插件
但是这并不是我们
每次都可能希望
提供程序插件的功能
从一个版本到另一个版本可能会发生巨大变化时
我们的terraform配置可能无法
按
预期工作 幸运的
是，
我们可以确保
提供程序的特定版本
是您 当我们运行 data terraform init 命令时，由 terraform sed
在注册表中提供的文档中提供了使用特定版本提供程序的说明，
例如，如果我们在注册表中查找本地
提供程序，
则默认版本为
2.0.0 也是此录音的最新版本
以使用不同版本单击
版本选项卡
，它应该打开一个下拉列表，其中包含
所有旧版本的提供程序
让我们选择版本 1.4.0
以使用此特定版本的
本地提供程序单击 在右侧的
use provider 选项卡上，这
应该会打开
我们可以在配置中复制和粘贴的代码块，
我们正在使用一个名为 terraform 的新块，
该块用于配置
与 terraform 本身相关的设置
以利用
我们需要
在 terraform 块内和我们可以拥有
的 required providers 块内使用另一个称为 required providers 的提供程序的特定版本
我们想在这个例子中使用的每个提供程序的多个参数
我们有一个参数
，其中本地提供程序的键称为
local 这个参数的值
是一个对象
，其中包含提供程序的源地址
和我们要安装的确切版本
在这种情况下是 1.4.0
，其中 terraform 块配置为
使用本地提供程序的 1.4.0 版本，
当我们在其中运行 terraform 时，我们应该
看到这样的消息，
然后再结束本讲座让我们
看一下语法
用于在本地提供程序的配置中定义 terraform 中的版本约束，
我们指定版本
等于 1.4.0
这允许 terraform 查找和
下载本地提供程序的确切版本，
但是如果我们使用，还有其他方法可以使用
版本约束
不等于符号
而不是 terraform 将确保在这种情况
下不下载此特定版本
我们特别要求
terraform 不要
使用版本 2.0.0 s o 它会
下载以前的可用版本
，即 1.4.0，
如果您希望表单使用
低于给定版本的版本，
我们可以通过使用这样的
比较运算符
来实现，并使用大于一个的版本
特定版本
我们可以
像这样使用大于运算符
我们也可以
像这样组合比较运算符
来使用范围内的特定版本
在这个例子中我们想使用
任何大于 1.2.0 但小于 1.2.0 的版本
比 2.0.0 但
也不是 1.4.0 版本
，因此 terraform 下载了
1.3.0 版本，这在这种情况下是可以接受的
，最后我们还可以使用
悲观约束
运算符，这是通过
使用波浪号更大来定义的 比这样的
符号这个运算符允许 terraform
根据我们提供的值下载特定版本
或任何可用的增量版本
，例如我们在下面给出了 1.2 的值
波浪号大于符号
这意味着 terraform 可以
下载版本 1.2
或增量版本，例如 1.3 1.4
1.5 一直到 1.9
但是如果您查看提供程序
文档，
我们没有版本 1.5 或
高于最大版本的任何版本
在这种情况下我们可以使用的是
1.4.0 这是
我们在其中运行 terraform 时下载的版本
让我们这次使用另一个值
1.2.0 使用相同的悲观
约束运算符
这次 terraform 可以下载
版本 1.2.0
或版本 1.2.1 或版本
1.2.2
一直到 1.2.9
再次我们
在注册表中只有 1.2.2
的最大版本，这是
我们运行时将下载的版本
在代码云中很好地适应这一切，
我们为您精心策划了多个学习路径
，以帮助您从
初学者到各种 DevOps 技术的专家，
所以不要忘记检查它，
不要忘记 苏 bscribe 到这个
频道，
因为我们经常发布更多的课程，
你