Terraform 未来基础设施的描述。 安东·巴本科 (2018)

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

许多人在日常工作中了解并使用 Terraform,但其最佳实践尚未形成。 每个团队都必须发明自己的方法和方法。

您的基础设施几乎肯定是从简单开始的:一些资源+一些开发人员。 随着时间的推移,它会向各个方向生长。 您是否找到了将资源分组到 Terraform 模块中、将代码组织到文件夹中的方法,以及还有哪些可能出错的地方? (著名遗言)

随着时间的流逝,您感觉您的基础设施是您的新宠物,但为什么呢? 您担心基础设施发生莫名其妙的变化,您害怕接触基础设施和代码 - 结果,您延迟了新功能或降低了质量......

在 Github 上管理 AWS 的 Terraform 社区模块集合并在生产中长期维护 Terraform 三年后,Anton Babenko 准备分享他的经验:如何编写 TF 模块,以便将来不会受到伤害。

在演讲结束时,参与者将更加熟悉 Terraform 中的资源管理原则、与 Terraform 中的模块相关的最佳实践以及与基础设施管理相关的一些持续集成原则。

免责声明: 我注意到这份报告的日期是 2018 年 2 月——已经过去了 0.11 年。 报告中讨论的 Terraform 2 版本不再受支持。 过去2年里,已经发布了XNUMX个新版本,其中包含了大量的创新、改进和变化。 请注意这一点并检查文档。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

参考文献:

我叫安东·巴本科。 你们中的一些人可能使用了我编写的代码。 现在我会比以往任何时候都更加自信地谈论这个问题,因为我可以获得统计数据。

我从事 Terraform 工作,自 2015 年以来一直是与 Terraform 和 Amazon 相关的大量开源项目的积极参与者和贡献者。

从那时起,我已经编写了足够的代码,以一种有趣的方式表达它。 我现在将尝试告诉你们这一点。

我将讨论使用 Terraform 的复杂性和细节。 但这并不是 HighLoad 的真正主题。 现在你会明白为什么。

随着时间的推移,我开始编写 Terraform 模块。 用户写了问题,我重写了它们。 然后我编写了各种实用程序来使用预提交挂钩等来格式化代码。

有很多有趣的项目。 我喜欢代码生成,因为我喜欢计算机为我和程序员做越来越多的工作,所以我目前正在使用可视化图表开发 Terraform 代码生成器。 也许你们中有些人见过它们。 这些是带有箭头的漂亮盒子。 我认为如果您可以单击“导出”按钮并将其全部作为代码获取,那就太好了。

我来自乌克兰。 我在挪威生活了很多年。

此外,本报告的信息是从知道我的名字并在社交网络上找到我的人收集的。 我几乎总是有相同的昵称。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

https://github.com/terraform-aws-modules
https://registry.terraform.io/namespaces/terraform-aws-modules

正如我所提到的,我是 Terraform AWS 模块的主要维护者,它是 GitHub 上最大的存储库之一,我们在其中托管用于最常见任务的模块:VPC、自动扩展、RDS。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

而你现在所听到的是最基本的。 如果您怀疑自己是否理解 Terraform 是什么,那么最好将时间花在其他地方。 这里会有很多技术术语。 我毫不犹豫地宣布该报告的级别是最高的。 这意味着我可以使用所有可能的术语进行交谈,而无需太多解释。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

Terraform 于 2014 年作为一个实用程序出现,允许您以代码形式编写、规划和管理基础设施。 这里的关键概念是“基础设施即代码”。

正如我所说,所有文档都是用 terraform.io。 我希望大多数人都知道这个网站并阅读过文档。 如果是这样,那么您来对地方了。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

这就是常规 Terraform 配置文件的样子,我们首先在其中定义一些变量。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

在本例中,我们定义“aws_region”。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

然后我们描述我们想要创建什么资源。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

我们运行一些命令,特别是“terraform init”来加载依赖项和提供程序。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

我们运行“terraform apply”命令来检查指定的配置是否与我们创建的资源匹配。 由于我们之前没有创建任何内容,Terraform 会提示我们创建这些资源。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

我们确认了这一点。 因此我们创建了一个名为seasnail的桶。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

还有几个类似的实用程序。 许多使用 Amazon 的人都知道 AWS CloudFormation 或 Google Cloud Deployment Manager 或 Azure Resource Manager。 他们每个人都有自己的某种实现来管理每个公共云提供商内的资源。 Terraform 特别有用,因为它允许您管理 100 多个提供者。 (更多细节 这里)

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

Terraform 从一开始就追求的目标:

  • Terraform 提供单一资源视图。
  • 允许您支持所有现代平台。
  • Terraform 从一开始就被设计为一个实用程序,可让您安全且可预测地更改基础设施。

2014年,“可预测”这个词在这种背景下听起来很不寻常。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

Terraform 是一个通用实用程序。 如果你有 API,那么你绝对可以控制一切:

  • 您可以使用 120 多个提供商来管理您想要的一切。
  • 例如,您可以使用 Terraform 来描述对 GitHub 存储库的访问。
  • 您甚至可以在 Jira 中创建和关闭错误。
  • 您可以管理 New Relic 指标。
  • 如果您确实愿意,甚至可以在 Dropbox 中创建文件。

这一切都是使用 Terraform 提供程序实现的,这些提供程序具有可以用 Go 描述的开放 API。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

假设我们开始使用 Terraform,阅读了网站上的一些文档,观看了一些视频,然后开始编写 main.tf,正如我在前面的幻灯片中所示的那样。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

一切都很好,您有一个创建 VPC 的文件。

如果您想创建 VPC,则大约需要指定这 12 行。 描述您要在哪个区域创建、要使用哪个 cidr_block IP 地址。 就这样。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

自然而然,项目就会逐渐壮大。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

你将在那里添加一堆新东西:资源、数据源,你将与新的提供者集成,突然你会想要使用 Terraform 来管理你的 GitHub 帐户中的用户等。你可能想要使用不同的DNS 提供商,跨越一切。 Terraform 让这一切变得简单。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

让我们看下面的例子。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

您逐渐添加 internet_gateway,因为您希望 VPC 中的资源能够访问 Internet。 这是一个好主意。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

结果是这样的 main.tf:

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

这是 main.tf 的顶部部分。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

这是 main.tf 的底部部分。

然后添加子网。 当您想要添加 NAT 网关、路由、路由表和一堆其他子网时,您将不再有 38 条线路,而是大约 200-300 条线路。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

也就是说,你的 main.tf 文件正在逐渐增长。 人们常常将所有内容放在一个文件中。 10-20 Kb 出现在 main.tf 中。 想象一下 10-20 Kb 是文本内容。 一切事物都相互关联。 这逐渐变得难以处理。 10-20 Kb 是一个很好的用户案例,有时甚至更多。 人们并不总是认为这很糟糕。

与常规编程一样,即不是基础设施即代码,我们习惯于使用一堆不同的类、包、模块、分组。 Terraform 允许您做很多相同的事情。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

  • 代码正在增长。
  • 资源之间的依赖性也在不断增强。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

我们有一个非常非常大的需求。 我们明白我们不能再这样生活了。 我们的代码变得越来越庞大。 当然,10-20 Kb 并不是很大,但我们只讨论网络堆栈,即您只添加了网络资源。 我们不是在谈论应用程序负载均衡器、部署 ES 集群、Kubernetes 等,100 Kb 可以轻松编织进去。 如果您写下所有这些,您很快就会了解到 Terraform 提供了 Terraform 模块。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

Terraform 模块是一个独立的 Terraform 配置,作为一个组进行管理。 这就是您需要了解的有关 Terraform 模块的全部内容。 他们一点也不聪明,他们不允许你根据某些东西建立任何复杂的联系。 这一切都落在了开发商的肩上。 也就是说,这只是您已经编写的某种 Terraform 配置。 您可以简单地将其称为一个组。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

因此,我们试图了解如何优化 10-20-30 Kb 的代码。 我们逐渐意识到我们需要使用一些模块。

您遇到的第一种模块是资源模块。 他们不了解您的基础设施是什么、您的业务是什么、地点和条件是什么。 这些正是我与开源社区一起管理的模块,我们将其作为您的基础设施的最初构建块。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

资源模块的示例。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

当我们调用资源模块时,我们指定应该从哪个路径加载其内容。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

我们指明要下载哪个版本。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

我们在那里传递了一堆参数。 就这样。 这就是我们使用该模块时需要知道的全部内容。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

很多人认为使用最新版本就一切稳定了。 但不是。 基础设施必须进行版本控制;我们必须清楚地回答这个或那个组件部署到哪个版本。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

这是该模块内的代码。 安全组模块。 这里滚动到第 640 行。 在 Amazon 中以每种可能的配置创建安全组资源是一项非常重要的任务。 仅仅创建一个安全组并告诉它传递什么规则是不够的。 这会很简单。 亚马逊内部有上百万种不同的限制。 例如,如果您使用 VPC端点、前缀列表、各种API 并尝试将所有这些与其他所有内容结合起来,那么 Terraform 不允许您这样做。 亚马逊 API 也不允许这样做。 因此,我们需要将所有这些可怕的逻辑隐藏在一个模块中,并为用户提供看起来像这样的代码。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

用户不需要知道它的内部是如何制作的。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

第二类模块由资源模块组成,已经解决了更适合您业务的问题。 通常,这是 Terraform 的扩展的地方,并为公司标准的标签设置一些严格的值。 您还可以在其中添加 Terraform 目前不允许您使用的功能。 这就是现在。 现在版本 0.11,这即将成为过去。 但是,预处理器、jsonnet、cookiecutter 和其他一些东西仍然是必须用于成熟工作的辅助机制。

接下来我将展示一些这方面的例子。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

基础设施模块的调用方式完全相同。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

指示了下载内容的来源。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

传入一堆值,传入这个模块。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

接下来,在该模块内,调用一堆资源模块来创建 VPC 或应用程序负载均衡器,或者创建安全组或弹性容器服务集群。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

有两种类型的模块。 理解这一点很重要,因为我在本报告中分组的大部分信息都没有写在文档中。

现在 Terraform 中的文档很有问题,因为它只是说有这些功能,你可以使用它们。 但她没有说明如何使用这些功能,以及为什么使用它们更好。 因此,很多人写出了他们无法忍受的东西。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

接下来我们看看这些模块是如何编写的。 然后我们将了解如何调用它们以及如何使用代码。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

地形注册表 - https://registry.terraform.io/

提示 #0 是不要编写资源模块。 这些模块中的大多数已经为您编写了。 正如我所说,它们是开源的,它们不包含任何业务逻辑,它们没有 IP 地址、密码等硬编码值。该模块非常灵活。 而且很可能已经写好了。 亚马逊有很多资源模块。 大约650个。而且大部分质量都很好。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

在这个例子中,有人来找你说:“我希望能够管理数据库。 创建一个模块,以便我可以创建一个数据库。” 此人不知道 Amazon 或 Terraform 的实施细节。 他只是说:“我想管理 MSSQL。” 也就是说,我们的意思是它将调用我们的模块,传递引擎类型并指示时区。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

人们不应该知道我们将在这个模块中创建两种不同的资源:一个用于 MSSQL,第二个用于其他所有资源,只是因为在 Terraform 0.11 中您无法将时区值指定为可选。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

在该模块的出口处,人们将能够简单地收到一个地址。 他不会知道我们在内部从哪个数据库、哪个资源创建所有这些。 这是隐藏的一个非常重要的元素。 这不仅适用于那些在开源中公开的模块,也适用于您将在项目和团队中编写的那些模块。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

这是第二个参数,如果您已经使用 Terraform 一段时间,那么这一点非常重要。 您有一个存储库,其中放置了您公司的所有 Terraform 模块。 随着时间的推移,这个项目的大小会增长到一到两兆字节,这是很正常的。 这可以。

但问题是 Terraform 如何调用这些模块。 例如,如果您调用模块来创建每个单独的用户,Terraform 将首先加载整个存储库,然后导航到该特定模块所在的文件夹。 这样您每次将下载一兆字节。 如果您管理 100 或 200 个用户,那么您将下载 100 或 200 兆字节,然后转到该文件夹​​。 因此,您自然不想每次点击“Terraform init”时都下载一堆东西。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

https://github.com/mbtproject/mbt

这个问题有两种解决方案。 第一种是使用相对路径。 这样,您就可以在代码中指示该文件夹是本地文件夹 (./)。 在启动任何内容之前,您可以在本地对该存储库进行 Git 克隆。 这样你就可以做一次。

当然,也有很多缺点。 例如,您不能使用版本控制。 有时这很难忍受。

第二个解决方案。 如果您有很多子模块并且已经建立了某种管道,那么可以使用 MBT 项目,它允许您从单一存储库收集许多不同的包并将它们上传到 S3。 这是一个非常好的办法。 因此,iam-user-1.0.0.zip 文件的大小仅为 1 Kb,因为创建此资源的代码非常小。 而且它的工作速度会快得多。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

我们来谈谈模块中不能使用的内容。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

为什么这在模块中是邪恶的? 最糟糕的是假设用户。 假设用户是一个提供者身份验证选项,可以由不同的人使用。 例如,我们都会同化这个角色。 这意味着 Terraform 将承担这个角色。 然后它会通过这个角色执行其他操作。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

邪恶的是,如果 Vasya 喜欢以一种方式连接到 Amazon,例如使用默认环境变量,而 Petya 喜欢使用他在秘密地方的共享密钥,那么您不能在地形。 为了让他们不会经历痛苦,没有必要在模块中指出这个块。 这必须在更高的层面上指出。 也就是说,我们有一个资源模块、一个基础设施模块和顶部的组合。 这应该在更高的地方指出。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

第二个邪恶是供给者。 这里的邪恶并不是那么微不足道,因为如果你编写代码并且它对你有用,那么你可能会认为如果它有效,那么为什么要改变它。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

问题在于,您并不总是能够首先控制何时启动此配置程序。 其次,您无法控制 aws ec2 的含义,即我们现在谈论的是 Linux 还是 Windows。 因此,您无法编写在不同操作系统或不同用户情况下同样工作的东西。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

最常见的例子(也在官方文档中指出)是,如果您编写 aws_instance 并指定一堆参数,那么如果您在那里指定配置程序“local-exec”并运行您的 ansible- 则没有任何问题 -剧本。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

事实上,是的,这并没有什么错。 但很快你就会意识到这个 local-exec 的东西不存在,例如在 launch_configuration 中。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

当您使用 launch_configuration,并且想要从一个实例创建一个自动缩放组时,那么在 launch_configuration 中就没有“provisioner”的概念。 这里有一个“用户数据”的概念。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

因此,更通用的解决方案是使用用户数据。 当实例打开时,它将在实例本身上启动,或者当自动缩放组使用此 launch_configuration 时,它将在相同的用户数据中启动。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

如果您仍然想运行配置程序,因为它是一个粘合组件,当创建一个资源时,此时您需要运行您的配置程序,您的命令。 这样的情况还有很多。

最正确的资源称为 null_resource。 Null_resource 是从未实际创建的虚拟资源。 它不接触任何东西,没有API,没有自动缩放。 但它允许您控制何时运行命令。 在这种情况下,该命令在创建期间运行。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

链接 http://bit.ly/common-traits-in-terraform-modules

有几个迹象。 我不会详细讨论所有迹象。 有一篇文章是关于这个的。 但是如果你使用过 Terraform 或者使用过其他人的模块,那么你经常会注意到很多模块,就像开源中的大多数代码一样,都是人们根据自己的需求编写的。 一个人写了它并解决了他的问题。 我把它放在 GitHub 上,让它活下去。 它会存在,但如果没有文档和示例,那么就没有人会使用它。 如果没有任何功能可以让您解决比其特定任务更多的问题,那么也没有人会使用它。 失去用户的方法有很多。

如果你想写一些东西以便人们会使用它,那么我建议遵循这些标志。

它们是:

  • 文档和示例。
  • 功能齐全。
  • 合理的默认值。
  • 干净的代码。
  • 试验。

测试是一种不同的情况,因为它们很难编写。 我更相信文档和示例。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

因此,我们研究了如何编写模块。 有两种说法。 第一个,也是最重要的,如果可以的话就不要写,因为很多人在你之前已经完成了这些任务。 其次,如果您仍然决定,请尽量不要在模块和配置程序中使用提供程序。

这是文档的灰色部分。 你现在可能会想:“有些事情还不清楚。 不相信。” 但我们将在六个月后看到结果。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

现在我们来谈谈如何调用这些模块。

我们知道我们的代码会随着时间的推移而增长。 我们不再只有一个文件,我们已经有 20 个文件了。 它们都在一个文件夹中。 或者也许在五个文件夹中。 也许我们开始以某种方式按地区、按某些组成部分将它们分解。 然后我们就明白,现在我们已经有了一些同步和编排的基础。 也就是说,我们必须了解如果我们更改了网络资源我们应该做什么,我们应该如何处理其余的资源,如何导致这些依赖关系等等。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

有两个极端。 第一个极端是一体的。 我们有一个主文件。 目前,这是 Terraform 网站上的官方最佳实践。

但现在它被写为已弃用并被删除。 随着时间的推移,Terraform 社区意识到这远非最佳实践,因为人们开始以不同的方式使用该项目。 并且存在问题。 例如,当我们在一处列出所有依赖项时。 在某些情况下,当我们单击“Terraform plan”时,直到 Terraform 更新所有资源的状态,可能会过去很多时间。

很多时间是,例如5分钟。 对于某些人来说,这是很多时间。 我见过需要 15 分钟的案例。 AWS API 花了 15 分钟试图弄清楚每个资源的状态发生了什么。 这是一个非常大的区域。

当然,当您想要更改某个地方的某些内容时,就会出现相关的问题,然后您等待 15 分钟,它就会为您提供一些更改的画布。 你吐了口唾沫,写了“是”,然后出了问题。 这是一个非常真实的例子。 Terraform 不会试图让您免受问题的困扰。 也就是说,写你想要的东西。 会有问题——你的问题。 虽然 Terraform 0.11 并不试图以任何方式帮助您。 0.12中有一些有趣的地方可以让你说:“Vasya,你真的想要这个,你能清醒过来吗?”

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

第二种方式是减少这个区域,即来自一个地方的呼叫可以较少地从另一个地方连接。

唯一的问题是你需要编写更多的代码,即你需要在大量文件中描述变量并更新它。 有些人不喜欢它。 这对我来说很正常。 还有人想:“为什么要写在不同的地方呢,我把它都放在一个地方吧。” 这是可能的,但这是第二个极端。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

谁把这一切都集中在一个地方? 一、二、三人,即有人在使用。

谁调用一个特定组件、一个块或一个基础设施模块? 五到七人。 这很酷。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

最常见的答案是介于两者之间。 如果项目很大,那么您经常会遇到没有合适的解决方案并且并非所有问题都能解决的情况,因此您最终会得到一个混合体。 这并没有什么错,只要你明白两者都有优点。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

如果堆栈 VPC 中发生了某些变化,并且您想要将这些更改应用到 EC2,即您想要更新自动缩放组,因为您有一个新的子网,那么我将这种类型称为依赖项编排。 有一些解决方案:谁使用什么?

我可以建议有哪些解决方案。 您可以使用 Terraform 来发挥作用,也可以使用 makefile 来使用 Terraform。 看看那里是否有什么变化,您可以在这里启动它。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

您觉得这个决定怎么样? 有人认为这是一个很酷的解决方案吗? 我看到一个微笑,显然疑虑已经悄然而至。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

当然,不要在家尝试这个。 Terraform 从未被设计为从 Terraform 运行。

在一份报告中,他们告诉我:“不,这行不通。” 关键是它不应该起作用。 虽然当您可以从 Terraform 启动 Terraform,然后启动 Terraform 时看起来非常令人印象深刻,但您不应该这样做。 Terraform 应该总是很容易启动。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

https://github.com/gruntwork-io/terragrunt/

如果当某个地方发生某些变化时您需要调用编排,那么 Terragrunt 是不错的选择。

Terragrunt 是一个实用程序,是 Terraform 的附加组件,可让您协调和编排对基础设施模块的调用。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

典型的 Terraform 配置文件如下所示。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

您指定要调用哪个特定模块。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

该模块有哪些依赖项?

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

该模块接受什么参数。 这就是关于 Terragrunt 的全部信息。

文档就在那里,GitHub 上有 1 个星。 但在大多数情况下,这是您需要了解的。 对于刚刚开始使用 Terraform 的公司来说,这很容易实现。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

所以编排就是 Terragrunt。 还有其他选择。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

现在我们来谈谈如何使用代码。

如果您需要向代码添加新功能,在大多数情况下这很容易。 您正在编写一个新资源,一切都很简单。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

如果你有一些预先创建的资源,比如你开了AWS账户后了解了Terraform,并想使用你已有的资源,那么通过这种方式扩展你的模块是合适的,这样它支持使用现有资源。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

并支持使用块资源创建新资源。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

在输出时,我们总是根据所使用的内容返回输出 ID。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

Terraform 0.11 中的第二个非常重要的问题是使用列表。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

困难在于,如果我们有这样一个用户列表。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

当我们使用块资源创建这些用户时,一切都会顺利。 我们遍历整个列表,为每个列表创建一个文件。 一切安好。 然后,例如中间的user3,应该从这里删除,那么在他之后创建的所有资源都将被重新创建,因为索引会改变。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

在有状态环境中使用列表。 什么是有状态环境? 这就是当这个资源被创建的时候,就创造了一个新的价值的情况。 例如,AWS访问密钥或AWS秘密密钥,即当我们创建用户时,我们会收到新的访问密钥或秘密密钥。 而每次我们删除一个用户时,这个用户都会有一个新的密钥。 但这不是风水,因为如果每次有人离开团队时我们都为他创建一个新用户,用户就不会想与我们成为朋友。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

这就是解决方案。 这是用 Jsonnet 编写的代码。 Jsonnet 是 Google 的一种模板语言。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

此命令允许您接受此模板,并返回根据您的模板制作的 json 文件作为输出。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

模板看起来像这样。

Terraform 允许您以相同的方式使用 HCL 和 Json,因此如果您有能力生成 Json,那么您可以将其放入 Terraform 中。 扩展名为.tf.json的文件将成功下载。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

然后我们像往常一样使用它:terraform init,terramorm apply。 我们创建两个用户。

现在我们不害怕有人离开球队。 我们只需编辑 json 文件即可。 瓦夏·普普金离开了,佩佳·皮托奇金留下来。 Petya Pyatochkin 将不会收到新钥匙。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

将 Terraform 与其他工具集成并不是 Terraform 真正的工作。 Terraform 是作为创建资源的平台而创建的,仅此而已。 而之后发生的一切就不是 Terraform 关心的了。 而且没有必要把它编织在那里。 Ansible 可以满足您所需的一切。

但是,当我们想要扩展 Terraform 并在某件事完成后调用某些命令时,就会出现这种情况。

第一种方式。 我们在编写此命令的位置创建一个输出。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

然后我们从 shell terraform 输出中调用此命令并指定我们想要的值。 因此,该命令将使用所有替换值执行。 非常舒服。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

第二种方式。 这是 null_resource 的使用取决于我们基础设施的变化。 一旦某些资源的ID发生变化,我们就可以调用相同的local-exe。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

当然,这在纸面上是很顺利的,因为亚马逊和所有其他公共提供商一样,有很多自己的边缘情况。

最常见的边缘情况是,当您开设 AWS 账户时,使用哪个区域很重要; 该功能是否已启用; 也许您在 2013 年 XNUMX 月之后打开过它; 也许您在VPC等中使用默认值。有很多限制。 亚马逊将它们分散在整个文档中。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

我建议避免一些事情。

首先,请避免 Terraform 计划或 Terraform CLI 中的所有非秘密参数。 所有这些都可以放入 tfvars 文件或环境变量中。

但你不需要记住整个魔法命令。 Terraform 计划 – var,我们开始吧。 第一个变量是var,第二个变量是var,第三个,第四个。 我最常使用的基础设施即代码最重要的原则是,只需查看代码,我就应该清楚地了解那里部署了什么、处于什么状态以及具有什么值。 因此,我不必阅读文档或询问 Vasya 他使用哪些参数来创建我们的集群。 我只需要打开一个扩展名为 tfvars 的文件(该文件通常与环境匹配),然后查看其中的所有内容。

另外,不要使用目标参数来缩小范围。 为此,使用小型基础设施模块要容易得多。

而且,不需要限制和增加并行性。 如果我有 150 个资源,并且我想将 Amazon 并行度从默认的 10 增加到 100,那么很可能会出现问题。 或者现在可能进展顺利,但当亚马逊说你拨打的电话太多时,你就会遇到麻烦。

Terraform 将尝试重新启动大多数此类问题,但您几乎不会取得任何成果。 如果您偶然发现 AWS API 或 Terraform 提供程序内部的某些错误,Parallelism=1 是一个很重要的选择。 然后您需要指定:parallelism=1 并等待 Terraform 完成一个调用,然后是第二个调用,然后是第三个调用。 他将一一发射它们。

人们经常问我:“为什么我认为 Terraform 工作空间是邪恶的?” 我认为基础设施即代码的原则是查看创建了哪些基础设施以及具有哪些价值。

工作空间不是由用户创建的。 这并不意味着用户在 GitHub 中写道,没有 Terraform 工作区我们就无法生存。 不,不是这样的。 Terraform Enterprise 是一个商业解决方案。 HashiCorp 的 Terraform 认为我们需要工作空间,因此我们将其归档。 我发现将其放在单独的文件夹中要容易得多。 然后文件会多一点,但是会更清晰一些。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

如何使用代码? 事实上,使用列表是唯一的痛苦。 让 Terraform 变得更容易。 这并不能为你带来一切好处。 没有必要把文档中写的所有内容都塞在那里。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

报告的主题是“为了未来”。 我将非常简短地讨论这一点。 对于未来来说,这意味着0.12即将发布。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

0.12 是一大堆新东西。 如果您来自常规编程,那么您会错过各种动态块、循环、正确和条件比较操作,其中左侧和右侧不是同时计算的,而是根据情况计算的。 你很想念它,所以 0.12 会为你解决它。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

但! 如果您使用现成的模块和第三方解决方案编写得更少、更简单,那么您就不必等待并希望 0.12 会到来并为您解决所有问题。

Terraform 未来基础设施的描述。 安东·巴本科 (2018)

感谢您的报告! 您谈到了基础设施即代码,并逐字逐句地谈到了测试。 模块中是否需要测试? 这是谁的责任? 我需要自己写还是由模块负责?

明年将会充斥着我们决定测试一切的报告。 测试什么是最大的问题。 有很多依赖关系,来自不同提供商的很多限制。 当你和我谈话时,你说:“我需要测试”,然后我问:“你要测试什么?” 您说您将在您所在的地区进行测试。 然后我说这在我的地区行不通。 也就是说,我们甚至无法在这一点上达成一致。 更不用说还有很多技术问题。 也就是说,如何编写这些测试以使它们足够。

我正在积极研究这个主题,即如何根据您编写的基础设施自动生成​​测试。 也就是说,如果你编写了这段代码,那么我需要运行它,基于此我可以创建测试。

地测 是最常提到的库之一,它允许您为 Terraform 编写集成测试。 这是实用程序之一。 我更喜欢 DSL 类型,例如 rspec。

安东,感谢您的报告! 我叫瓦莱里。 让我问一个小哲学问题。 有条件地,有供应,有部署。 配置创建了我的基础设施,在部署中我们用一些有用的东西填充它,例如服务器,应用程序等。在我看来,Terraform更适合配置,而Ansible更适合部署,因为Ansible也适用于物理基础设施允许您安装 nginx、Postgres。 但与此同时,Ansible 似乎允许配置 Amazon 或 Google 资源等。 但是 Terraform 还允许您使用其模块部署一些软件。 从您的角度来看,Terraform 和 Ansible 之间是否存在某种边界,在哪里使用以及什么更好? 或者,例如,您是否认为 Ansible 已经是垃圾,您应该尝试使用 Terraform 来完成所有事情?

好问题,瓦莱里。 我相信自 2014 年以来,Terraform 的目的就没有改变。 它为基础设施而生,也为基础设施而亡。 我们仍然需要并且将会需要 Ansible 配置管理。 挑战在于 launch_configuration 中有用户数据。 然后你就可以使用 Ansible 等。这是我最喜欢的标准区别。

如果我们谈论的是美丽的基础设施,那么有像 Packer 这样的实用程序可以收集此图像。 然后 Terraform 使用数据源查找该图像并更新其 launch_configuration。 也就是说,这样的pipeline是我们先拉Tracker,再拉Terraform。 如果发生构建,则会发生新的更改。

你好! 感谢您的报告! 我叫 Misha,来自 RBS 公司。 创建资源时,您可以通过provisioner调用Ansible。 Ansible 还有一个主题称为动态库存。 你可以先调用 Terraform,然后调用 Ansible,Ansible 将从状态获取资源并执行它。 什么更好?

人们使用两者都取得了同样的成功。 在我看来,如果我们不谈论自动缩放组,Ansible 中的动态库存是一件很方便的事情。 因为在autoscaling组中我们已经有了自己的工具包,叫做launch_configuration。 在 launch_configuration 中,我们记录了创建新资源时需要启动的所有内容。 因此,在我看来,对于 Amazon,使用动态库存并读取 Terraform ts 文件是大材小用。 如果您使用其他没有“自动缩放组”概念的工具,例如,您使用 DigitalOcean 或其他没有自动缩放组的提供商,那么您将必须手动拉取 API,查找 IP 地址,创建一个动态清单文件,Ansible 已经在其中漫游了。 也就是说,对于亚马逊,有 launch_configuration,而对于其他一切,有动态库存。

来源: habr.com

添加评论