Terraform是一种部署技术,任何想要通过基础设施即代码(Infrastructure as Code,IaC)方法来置备和管理基础设施的人,都可以使用这种技术。基础设施指的主要是基于云的基础设施,不过从技术上讲,任何能够通过应用程序编程接口(Application Programming Interface,API)进行控制的东西都可以算作基础设施。基础设施即代码是通过机器可读的定义文件来管理和置备基础设施的过程的
Terraform的基本原则是,它允许编写人类可读的配置代码来定义IaC。借助配置代码,你可以把可重复的、短暂的、一致的环境部署到公有云、私有云和混合云上的供应商
图1.1 Terraform可以把基础设施部署到任何云或者混合云中
有6个关键特征让Terraform与众不同,给它带来了竞争优势。
Terraform的优点 | 描述 |
---|---|
置备工具 | 部署基础设施,而不仅仅是应用程序 |
易于使用 | 适合非专家用户使用 |
免费且开源 | 无需支付费用,源代码开放 |
声明式 | 关注目标状态,而非达到该状态的具体操作 |
云无关 | 可以部署到任何云平台 |
表达能力强且可扩展 | 灵活且支持扩展,不受特定语言限制 |
表1.1 Terraform与其他IaC工具的对比
术语 | 定义 |
---|---|
Cloud Development Kit (CDK) | 一种允许实现类似Pulumi功能的云开发工具包 |
配置管理工具 | 用于管理可变基础设施的工具,例如Ansible、Chef、Puppet和SaltStack |
置备工具 | 用于管理不可变基础设施的工具,如Terraform |
云无关 | 使用相同的工具和工作流在任意云平台上无缝运行的能力 |
从技术上讲,Pulumi最接近Terraform,唯一的区别在于它不是声明式的。Pulumi团队认为这是Pulumi相较于Terraform的优势,但Terraform也有一个云开发工具包(Cloud Development Kit,CDK),允许实现相同的功能。
Ansible、Chef、Puppet和SaltStack都是配置管理工具,而不是基础设施置备工具。它们解决的问题类别与Terraform有些区别,不过也存在重叠的地方。
配置管理工具和置备工具之间的区别主要在于理念。配置管理工具常用于管理可变基础设施,而Terraform和其他置备工具常用于管理不可变基础设施。
云无关指的是能够使用一组相同的工具和工作流,无缝运行在任意云平台上。Terraform是云无关的,使用Terraform把基础设施部署到AWS与部署到GCP、Azure甚至私有数据中心一样简单(参见图1.2)。
图1.2 使用Terraform同时部署到多个云
表1.2从技术的角度对比了Terraform和AWS CloudFormation(催生Terraform的技术)。
表1.2 Terraform和AWS CloudFormation的技术对比
注意 本书中的所有代码均可在GitHub上通过搜索“terraform-in-action/manning-code”获取。
在Terraform中,资源是最重要的元素,因为它们置备虚拟机、负载均衡器、NAT网关等基础设施。资源被声明为HCL对象,具有resource类型和两个标签。第一个标签指定了要创建的资源的类型,第二个标签是资源的名称。名称并没有特别的意义,只用来在给定模块作用域内引用该资源。类型与名称合起来构成资源标识符,每个资源的标识符都是唯一的
图1.5 资源块的语法
每个资源都有输入和输出。输入称作实参,输出称作特性。实参通过资源进行传递,也可作为资源特性使用。另外,资源还有计算特性,但只有在创建了资源后才能使用它们。计算特性包含计算得到的关于管理资源的信息。
图1.6 aws_instance资源的实参、特性和计算特性的示例
与资源不同,提供程序只有一个标签Name。这是该提供程序在Terraform注册表中发布时使用的正式名称(如“aws”代表AWS,“google”代表GCP,“azurerm”代表Azure)。
图1.7 提供程序块的语法
提供程序没有输出,只有输入。通过传递输入(或配置实参)给provider块,可以配置提供程序。配置实参包括服务端点URL、地区、提供程序版本、通过API身份验证所需的任何凭据等
图1.8 当发出API调用时,配置的提供程序如何把凭据注入aws_instance中
在让Terraform部署EC2实例之前,我们首先必须初始化工作空间。尽管我们已经声明了AWS提供程序,但是Terraform仍然需要从Terraform注册表下载和安装二进制文件。至少需要为所有工作空间执行一次初始化。 运行terraform init命令可以初始化Terraform。运行该命令将看到如下输出。
资源的状态信息存储在一个名为terraform.tfstate的文件中。不要被扩展名.tfstate误导,它其实就是一个JSON文件。使用terraform show命令可以从状态文件输出人类可读的输出,这使得列举Terraform管理的资源的信息非常方便。
警告 不要手动编辑或删除terraform.tfstate文件,这一点很重要,否则Terraform将无法跟踪其管理的资源。
添加一个数据源来动态查找Ubuntu AMI的最新值。我们将把输出值传入aws_instance,这样就不必在EC2实例的资源配置中静态设置AMI了
图1.10 aws_ami数据源的输出如何与aws_instance资源的输入连接到一起
与资源一样,要声明数据源,需要创建一个HCL对象,其类型为“data”,且具有两个标签。第一个标签指定数据源的类型,第二个标签是数据源的名称。类型和名称合起来构成了数据源的标识符,标识符在一个模块内必须保持唯一
图1.12 数据源的语法
小结 ● Terraform是一个声明式IaC置备工具,可以把资源部署到任何公有云或私有云。 ● Terraform是一个置备工具,容易使用,免费且开源,采用声明式编程,与云无关,表达能力强且易于扩展。 ● Terraform的主要元素包括资源、数据源和提供程序。 ● Terraform可以把代码块连接起来,进行动态部署。 ● 要部署一个Terraform项目,首先编写配置代码,然后配置提供程序和其他输入变量,初始化Terraform,最后应用修改。使用destroy命令执行清理操作。
特点/元素 | 描述 |
---|---|
类型 | 声明式IaC置备工具 |
访问性 | 易于使用,免费且开源 |
编程方式 | 声明式 |
云兼容性 | 与云无关 |
灵活性 | 表达能力强,易于扩展 |
主要组成 | 资源、数据源、提供程序 |
图2.2 创建资源,然后读取并更新资源,最后删除资源
生命周期函数钩子 所有Terraform资源都实现了资源模式接口。资源模式要求资源定义CRUD函数钩子,Create()、Read()、Update()和Delete()各有一个钩子。当满足特定条件时,Terraform将调用这些钩子。一般来说,在创建资源时会调用Create(),在生成计划时会调用Read(),在更新资源时会调用Create(),在删除时会调用Delete()。其实并不是这么简单,但你应该能够理解这里的模式。
因为local_file是资源,所以也实现了资源模式接口。这意味着,它为Create()、Read()、Update()和Delete()定义了函数钩子。这与local_file数据源不同,后者只实现了Read()
图2.3 本地提供程序中的两个资源分别是管理的资源和非管理的数据源。管理的资源实现了完整的CRUD,而数据源只实现了Read()
Terraform特性
特性 | 描述 |
---|---|
Heredoc字符串 | 使用<<-表示,忽略前导空格,字符按字面解释 |
Terraform配置块 | 用于配置Terraform本身,包括版本锁定、状态文件存储位置和提供程序下载 |
Terraform init | 在安装本地提供程序之前必须执行 |
资源块 | 声明具体资源,例如local_file资源,用于置备特定文件 |
提示 <<-表示一个有缩进的heredoc字符串。开始标识符和结束标识符(EOT)之间的任何字符都按字面解释。但是,前导空格将被忽略(这与传统的heredoc语法不同)。
代码清单2.1中有两个配置块。第一个配置块terraform {…}是一个特殊的配置块,负责配置Terraform,主要用于锁定用户代码的版本号,但也可以配置状态文件的存储位置,以及从什么地方下载提供程序(第6章将详细讨论)。需要注意的是,现在还没有安装本地提供程序。要进行安装,首先需要执行terraform init。 第二个配置块是一个资源块,它声明了local_file资源。这个配置块使用给定文件名和内容值来置备一个文本文件。在这里,内容将包含《孙子兵法》的前两段,文件名则是art_of_war.txt。我们使用heredoc语法(<<-)来输入一个多行字符串字面量。
Terraform资源生命周期函数钩子的总结
功能 | 资源 | local_file资源 | local_file数据源 |
---|---|---|---|
Create() | 在创建资源时调用 | 实现了 | 未实现 |
Read() | 在生成计划时调用 | 实现了 | 实现了 |
Update() | 在更新资源时调用 | 实现了 | 未实现 |
Delete() | 在删除资源时调用 | 实现了 | 未实现 |
erraform有一个terraform graph命令,专门用于可视化依赖图。该命令会输出一个DOT文件,使用多种工具可以把该文件转换为一个图形。图2.5显示了生成的DOT图。
图2.4 Terraform在为新部署生成执行计划时完成的步骤
图2.5 生成的DOT图
terraform.tfstate文件是一个状态文件,Terraform使用它来跟踪自己管理的资源。它用于在执行plan期间比较差异,以及检测配置漂移。
警告 不要编辑、删除或破坏terraform.tfstate文件,这一点十分重要,否则Terraform可能无法跟踪它管理的资源。虽然我们能够还原损坏的或者丢失的状态文件,但这是很困难、很耗时间的操作。
小结 随机性必须是受约束的。避免使用遗留的uuid()和timestamp()函数,因为不会汇集的状态,它们可能在Terraform中引入难以察觉的bug。
Terraform模块及其相关概念
概念 | 描述 |
---|---|
Terraform模块 | 自包含的代码包,用于组合相关资源,创建可复用组件 |
根模块 | 工作空间的顶级模块,配置输入变量和运行Terraform命令 |
子模块 | 位于根模块下,帮助组织和复用配置,可本地或远程存储 |
标准模块结构 | 包括main.tf、outputs.tf、variables.tf等文件 |
根模块文件 | 包含variables.tf、terraform.tfvars、providers.tf、main.tf、outputs.tf、versions.tf |
网络模块 | 管理网络相关的资源和依赖 |
数据库模块 | 管理数据库配置,包括与网络模块的交互 |
避免相互依赖 | 避免模块间复杂的相互依赖关系 |
嵌套模块设计 | 提高软件的抽象度和代码复用,但数据传递可能复杂 |
模块是自包含的代码包,允许把相关资源组合到一起,创建出可复用的组件
每个工作空间都有一个根模块,你在这个目录中运行terraform apply。在根模块下,你可以有一个或多个子模块,用来帮助组织和复用配置。模块可以位于本地(意味着它们嵌入在根模块内),也可以远程存储(意味着在执行terraform init时,将从某个远程位置下载它们)。在这里,我们将结合使用本地和远程存储的模块。
图4.7 整体模块结构,包含嵌套的子模块
HashiCorp强烈建议每个模块都遵守一种代码约定,这种约定称为“标准模块结构”。这意味着每个模块中至少要有3个Terraform配置文件。
● main.tf:主入口点。 ● outputs.tf:所有输出值的声明。 ● variables.tf:所有输入变量的声明。 注意 在根模块中,versions.tf、providers.tf和README.md也是必要的文件
图4.8 详细的模块结构
根模块是顶级模块,在这里配置用户提供的输入变量,运行Terraform命令,如terraform init和terraform apply命令。在根模块中有3个输入变量和两个输出值。3个输入变量是namespace、ssh_keypair和region,两个输出值是db_password和lb_dns_name
图4.9 根模块的输入变量和输出值
根模块包含6个文件。下面列出了这6个文件,以及它们的作用。
在该目录中,创建一个variables.tf文件
我们通过变量定义文件来设置变量。变量定义文件允许参数化配置代码,但无须硬编码默认值。它使用与Terraform配置相同的基本语法,但只包含变量名称和赋值。创建一个新的文件,并命名为terraform.tfvars,在其中插入代码清单4.2中的代码。这将设置variable.tf中的namespace和region变量。
在提供程序声明中引用此变量。为此,创建一个新的providers.tf文件
虽然现在我们还没有完善子模块的功能,但可以使用已经知道的信息为它们创建存根(stub)。使用代码清单4.4创建一个main.tf文件。
在main.tf文件中为模块声明添加了存根后,以相同的方式为输出值添加存根。
我们需要锁定提供程序和Terraform的版本。通常,我推荐在运行完terraform init命令后再执行这个步骤,这样一来,你就只需要记下来下载的提供程序版本并使用它们;但是因为我们提前执行了这个步骤,所以现在就锁定了版本。使用代码清单4.6创建versions.tf文件
图4.10 网络模块的整体输入和输出
图4.11 网络模块置备的管理资源
图4.12 网络模块的依赖图
代码清单4.8显示了main.tf的代码,将这些代码复制到你的文件中。不必过于担心难以理解这里的代码,只需要关注不同部分如何连接起来即可。
将相关特性组合到一个输出值中,有助于组织代码。
图4.16 数据库的安全组ID从网络模块传递到数据库模块的数据流
避免使用相互依赖的模块,它们会导致困惑。
虽然大量使用any类型很有诱惑力,但这是一种懒惰的编码习惯,很多时候只会造成问题。只有当在模块之间传递数据时才应使用any类型,绝不要使用any类型来配置根模块上的输入变量。
目录结构。
对于复杂的Terraform项目,嵌套模块是一种好的设计,因为它们提高了软件的抽象度和代码复用,但传递数据可能会变得烦琐。
图4.24 嵌套模块层次的一般结构
特性 | 描述 |
---|---|
无服务器 | 技术位于平台即服务(PaaS)和软件即服务(SaaS)之间 |
函数的优势 | 易于测试和扩展,适合无服务器应用程序 |
函数的缺点 | 无状态且彼此隔离,需要更多关联 |
Terraform与ARM结合 | 通过将ARM模板逐步替换为原生Terraform资源,实现从ARM到Terraform的迁移 |
导入工作量 | 需要大量工作将配置表示为配置代码 |
解决方案 | 开源项目如Terraformer和HashiCorp的原生支持 |
图5.1 无服务器是一种表示位于平台即服务(PaaS)和软件即服务(SaaS)之间的技术
函数的主要优势在于易于测试和扩展,这让它们非常适合无服务器应用程序。其缺点是,函数是无状态的,并且彼此被隔离开,所以需要进行更多关联。
图5.2 函数是将整套逻辑拆分为最小组成部分的最终结果
图5.16 将ARM迁移到Terraform的扼杀者外观模式。一开始只有包装到azurerm_template_deployment 资源中的一个巨大的ARM模板。随着时间的流逝,从ARM模板中逐渐取出资源,并将其配置为原生的Terraform资源。最终,因为所有资源都成为Terraform管理的资源,所以不再需要ARM模板
在使用Terraform时,最令人痛苦的地方是需要做大量工作才能把你想要实现的配置表示为配置代码。
许多开源项目旨在解决这个问题,其中最值得关注的是Terraformer。HashiCorp也承诺会在将来发布的Terraform版本中改进导入,针对从部署的资源生成配置代码提供原生支持。
图5.17 你可以选择当前部署的任意资源组,将其导出为一个 ARM模板文件,然后使用Terraform部署该模板
概念/实践 | 描述 |
---|---|
S3后端模块开发 | 不需要providers.tf,提供程序隐式传入;建议锁定模块版本 |
Terraform-docs | 开源工具,用于自动生成基于配置代码的文档 |
.gitignore文件 | 用于Terraform模块,排除不必要的文件 |
共享模块 | 可以通过多种方式获取,如本地路径、GitHub仓库、Terraform注册表 |
GitHub模块发布 | 创建以terraform--形式命名的仓库 |
Terraform注册表 | 免费且易于使用,支持公共和私有模块共享 |
官方模块规则 | 模块应为GitHub公共仓库,遵守特定命名和结构约定 |
工作空间复用配置 | 使用不同的变量定义文件部署到多个环境 |
工作空间切换 | 默认创建default工作空间,可切换至其他如dev或prod |
Terraform Cloud | 提供远程状态存储和VCS驱动的工作流,适用于不同预算需求 |
我们不需要providers.tf(见代码清单6.5),因为这是一个模块。根模块将在初始化期间隐式传入所有提供程序。 尽管我们没有声明提供程序,但锁定模块版本仍然是一个好主意。
Terraform-docs是一个很好的开源工具,能够根据配置代码自动生成文档。推荐使用这个工具。
代码清单6.7显示了Terraform模块中一个典型的.gitignore文件。
图6.5 使用多种方式获取模块,包括本地路径、GitHub仓库和Terraform注册表
从GitHub获取模块很容易。只需采用terraform--这种形式的名称创建一个仓库,然后将配置代码保存到该仓库即可(参见图6.6)。对于PROVIDER和NAME应该是什么,并不存在固定的规则,但我一般把PROVIDER视为部署到的云,把NAME视为对项目有帮助的描述字符。因此,我们将把要部署的模块命名为terraform-aws-s3backend。
图6.6 terraform-aws-s3backend模块的示例GitHub仓库
Terraform注册表是免费的,而且很容易使用。你只需要有一个GitHub账户即可开始使用Terraform注册表。登录后,你只需要在UI中单击几次,就可以注册一个模块,这样其他人就可以开始使用该模块了。因为Terraform注册表始终从公共GitHub仓库读取代码,所以把模块发布到注册表中,可以让该模块对每个人可用。Terraform Enterprise有一个额外的优势:它允许你有自己的私有Terraform注册表,这对于大型组织内共享私有模块很有用。
Terraform的主要优势是,它基于已经确立的模块发布最佳实践,强制实施特定的命名约定和标准。Terraform网站描述了HashiCorp针对模块建议采用的最佳实践。它也使得版本控制和按照名称或提供程序搜索其他人的模块变得更加容易。下面列出了官方的规则。
● 模块是GitHub上的公共仓库。 ● 模块具有terraform--形式的名称。 ● 模块有一个README.md文件(最好有一些用法示例代码)。 ● 模块符合标准模块结构(即具有main.tf、variables.tf和outputs.tf文件)。 ● 模块使用语义化版本标签(如v0.1.0)。
图6.7 导航到Terraform注册表主页
我们需要有一个根模块封装器来部署S3后端模块。如果你将模块发布到GitHub或Terraform注册表上,则可以将source设置为指向你的模块;否则,你可以使用我已经发布的那个模块。创建一个新的Terraform项目,在其中添加一个包含了代码清单6.8中的文件。
图6.11 工作空间允许使用相同的配置代码来部署到多个环境,通过不同的变量定义文件可以参数化这些配置代码
每次执行terraform init的时候,Terraform就会创建并切换到一个名为default的工作空间。通过运行terraform workspace list命令你可以证明这一点,该命令会列出全部工作空间,并在当前工作空间的名称旁边添加一个星号。
创建一个新的文件夹,在其中包含一个main.tf文件,并在文件中添加代码清单6.11所示的代码(与之前一样,需要替换bucket、profile、role_arn和dynamodb_table)。
在当前目录中,创建一个名为environments的文件夹;在该目录中,创建两个文件——dev.tfvars和prod.tfvars。
代码清单6.12显示了dev.tfvars的变量定义文件的示例。
现在切换到一个名为dev的工作空间来部署开发环境。
使用dev变量为开发环境部署配置代码。
现在已经在键为env:/dev/team1/my-cool-project的S3桶中创建了状态文件。切换到一个新的prod工作空间来部署生产环境。
因为我们在新的工作空间中,所以现在状态文件为空文件。通过运行terraform state list命令,我们可以证明这一点。该命令什么也不会返回。
使用prod.tfvars变量定义文件来部署到prod工作空间。
首先,删除prod部署。
然后,切换到dev工作空间进行销毁。
小结 Terraform Cloud是Terraform Enterprise的SaaS版本。如果价格是你的考虑因素,则可以选择Terraform Cloud的低价选项,但这些选项提供的特性也更少。不过,这些选项提供了一个远程状态存储区,还允许采用VCS驱动的工作流
概念/组件 | 描述 |
---|---|
CI/CD管道 | 自动化软件交付流程的多个阶段 |
两种部署方法 | 重部署整个栈和拆分常变与不变部分 |
GCP上的Docker容器CI/CD | 使用Cloud Run服务和Knative,简化无服务器容器部署 |
初始工作空间设置 | 使用Monorepos进行管理 |
资源置备程序 | 包括创建时和销毁时置备程序,用于挂钩资源生命周期事件 |
Terraform后门 | 资源置备程序,慎用且仅在必要时使用 |
图7.1 CI/CD管道包含多个阶段,可以自动化软件交付流程
图7.2 每次做出修改时都重新部署整个栈很慢
图7.3 通过将项目拆分为经常改变的东西和不常改变的东西,可以更加快速地部署应用程序代码
Knative是Kubernetes之上的一个抽象层,可以轻松地运行和管理无服务器工作负载。它是一个叫作Cloud Run的GCP服务的支柱,该服务为容器执行自动扩展、负载均衡和解析DNS操作。使用Cloud Run的目的是简化这种场景,因为部署Kubernetes集群有些复杂。
● 启用API:GCP要求显式启用想要使用的API。 ● CI/CD管道:置备并连接CI/CD管道的各个阶段。 ● Cloud Run服务:在GCP上运行无服务器容器。
图7.5显示了我们将置备的资源的依赖图。 图7.5 依赖图共有4组组件:一组用于启用API,一组用于配置Cloud Build,一组用于配置IAM访问,一组用于配置Cloud Run服务
使用Monorepos
置备程序允许挂钩到资源生命周期事件,从而动态扩展资源的功能。资源置备程序有以下两种类型: ● 创建时置备程序; ● 销毁时置备程序。
这个创建时置备程序调用命令sleep 60,在Create()完成后,Terraform将该资源标记为“已创建”之前等待60s(参见图7.9)。类似地,在调用Delete()之前,销毁时置备程序会等待15s(参见图7.10)。这两次等待(通过多次测试得出)对于避免启用/禁用服务API时出现竞争条件十分重要。
图7.9 在Create()函数钩子退出之后,Terraform将资源标记为“已创建”之前,会调用local-exec置备程序
图7.10 在调用Delete()之前调用local-exec置备程序
cowsay是一个CLI工具,可以输出一张ASCII奶牛的图片。本例让这个ASCII奶牛来说出消息。
Terraform后门(即资源置备程序)本身是危险的,应该避免使用它们。只有当别无选择时,才使用它们。
表7.1 Terraform中的资源置备程序
多云环境相比单云环境的优势的总结
多云优势 | 描述 |
---|---|
灵活性 | 选择同类最优服务的能力 |
节约成本 | 利用不同云供应商的不同定价模型 |
避免捆绑供应商 | 减少对特定供应商的依赖,改善谈判位置 |
恢复力 | 故障转移能力强,比单云架构更强 |
合规性 | 符合特定国家或地区的政府规定 |
无论是选择采用多云,还是被迫采用多云,你都应该知道,多云相比单云有一些优势。 ● 灵活性:你可以从任何云中选择同类最优的服务。 ● 节约成本:不同云供应商的定价模型不同,所以你可以选择低价选项,从而节约成本。 ● 避免捆绑供应商:一般来说,让自己捆绑到特定供应商不是一个好主意,因为这会让你处在一个不利的谈判位置。 ● 恢复力:多云架构可以自动把故障从一个云转移到另一个云,这让它们的恢复力比单云架构更强。 ● 合规性:内部或外部因素可能产生影响。例如,如果你想在某个国家运营云,就必须遵守相关的政府规定。
更新策略 | 描述 |
---|---|
默认资源更新 | 先销毁旧资源,再创建新资源,可能导致停机 |
create_before_destroy设置为true | 先创建新资源,再销毁旧资源,避免停机时间 |
零停机时间部署(Zero-Downtime Deployment,ZDD)是保持服务始终运行及对用户可用(即使在更新软件时也是如此)的一种实践。如果恰当执行ZDD,则用户应该不会注意到什么时候对系统做了修改。
图9.1 默认情况下,资源上的任何force-new更新将导致停机时间。这是因为在创建新资源之前,必须先销毁旧资源
图9.2 当create_before_destroy设置为true时,会在销毁旧资源之前创建替换资源。这意味着在force-new更新期间,不会出现停机时间
概念 | 描述 |
---|---|
for_each展开 | 使用for_each来展开Terraform模块,提高配置的灵活性 |
splat表达式 | 简洁的迭代表达式,用于提取列表中所有元素的特定属性,如var.list[*].id |
Terratest | 一个流行的Terraform测试框架,用于测试Terraform模块及其他如Docker、Kubernetes的结构 |
映射使用 | 使用映射在Terraform中管理复杂的数据结构 |
键值映射 | 使用键值对映射进行更精确的数据组织 |
图10.6 使用for_each展开Terraform模块
splat表达式是一个语法糖,允许以简洁的方式表达简单的for表达式。例如,如果你有一个对象列表,每个对象都有id特性,则可以使用表达式[for v in var.list : v.id] 将全部ID提取到一个新的字符串列表中。与之相比,splat表达式var.list[].id要简洁得多(特殊的[]符号表示迭代列表中的全部元素)。
Gruntworks开发的Terratest是最流行的Terraform测试框架之一。它已经被开发出来很久了,并且有大量的社区支持。与Terraform-exec一样,它被实现为一个Go库,包含一些可调用Terraform CLI命令的帮助函数,但它已经逐渐转变为一个更加通用的测试框架。许多人不仅使用它来测试Terraform模块,还使用它测试Docker、Kubernetes和Packer。
使用映射
使用键值映射
特性 | 描述 |
---|---|
Terraform Cloud和Enterprise | 自动运行Terraform的两个产品,基本相同,Cloud是Enterprise的SaaS版本 |
CI/CD管道 | 用于自动部署Terraform工作空间的各个阶段 |
HashiCorp的Terraform Cloud和Terraform Enterprise两个产品可以自动运行Terraform。这两个产品基本相同,Terraform Cloud只不过是Terraform Enterprise的软件即服务(Software as a Service,SaaS)版本
开发一个持续集成/持续交付(CI/CD)管道来自动部署Terraform工作空间。图12.1显示了CI/CD管道的各个阶段。
表12.1 按主题归类的Terraform Enterprise的关键特性