Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

Terraform 开发人员似乎为使用 AWS 基础设施提供了相当方便的最佳实践。 只是有一个细微差别。 随着时间的推移,环境的数量不断增加,每个环境都有自己的功能。 应用程序堆栈的几乎副本出现在邻近区域中。 并且Terraform代码需要根据新的需求仔细复制和编辑或制作成雪花。

我的演讲涉及 Terraform 中用于对抗大型和长期项目中的混乱和手动例程的模式。

视频:

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

我今年 40 岁,从事 IT 工作已经 20 年了。 我在 Ixtens 工作了 12 年。 我们从事电子商务驱动的开发。 我已经实践 DevOps 实践 5 年了。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

我的故事将讲述我在一家公司的一个项目中的经历,我不会透露该公司的名字,隐藏在保密协议后面。

幻灯片上的数字是为了了解项目的规模而显示的。 接下来我要说的一切都与亚马逊有关。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

我四年前加入了这个项目。 由于项目规模不断扩大,基础设施重构正如火如荼地进行。 而且以前使用的图案已经不合适了。 考虑到项目的所有计划增长,有必要想出一些新的东西。

感谢马特维,他昨天告诉我们在渡渡鸟披萨发生的事情。 这就是4年前这里发生的事情。

开发人员开始制作基础设施代码。

之所以需要这样做,最明显的原因是上市时间。 有必要确保 DevOps 团队在部署过程中不会成为瓶颈。 除此之外,Terraform 和 Puppet 在第一级就被使用了。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

Terraform 是 HashiCorp 的一个开源项目。 对于那些甚至不知道这是什么的人,请看接下来的几张幻灯片。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

基础设施即代码意味着我们可以描述我们的基础设施并要求一些机器人确保我们收到我们所描述的资源。

例如,我们需要一个虚拟机。 我们将描述并添加几个必需的参数。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

之后,我们将在控制台中配置对 Amazon 的访问。 我们会要求提供 Terraform 计划。 Terraform 计划会说:“好吧,我们可以为您的资源做这些事情。” 并且至少会添加一种资源。 预计不会有任何变化。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

一旦您对一切感到满意,您可以要求 Terraform 申请,Terraform 将为您创建一个实例,您将在云中收到一个虚拟机。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

我们的项目正在进一步发展。 我们正在那里添加一些更改。 我们要求更多实例,我们添加了 53 个条目。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

我们重复一遍。 请计划一下。 我们看看计划进行哪些改变。 我们申请。 这就是我们的基础设施的发展方式。

Terraform 使用称为状态文件的东西。 也就是说,发送到 Amazon 的所有更改都保存在一个文件中,其中对于您描述的每个资源,都有在 Amazon 中创建的相应资源。 因此,当资源描述发生变化时,Terraform 确切地知道 Amazon 中需要更改哪些内容。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

这些状态文件原本只是文件。 而且我们将它们存储在Git中,这非常不方便。 总是有人忘记提交更改,从而产生了许多冲突。

现在可以使用后端,即 Terraform 指定状态文件应保存在哪个存储桶中以及通过哪个键保存。 Terraform 本身将负责获取此状态文件,执行所有操作并返回最终结果。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

我们的基础设施正在不断发展。 这是我们的代码。 现在我们不仅仅是想创建一个虚拟机,我们还想有一个测试环境。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

Terraform 允许您创建模块之类的东西,即在某个文件夹中描述相同的东西。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

例如,在测试中,调用此模块并获得与我们在模块本身中执行 Terraform apply 相同的结果。 为了进行测试,将有此代码。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

对于生产,我们可以在那里发送一些更改,因为在测试中我们不需要大型实例;在生产中,大型实例才有用。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

然后我会回到这个项目。 这是一项艰巨的任务,规划的基础设施非常庞大。 有必要以某种方式放置所有代码,以便对每个人都方便:无论是对代码进行维护的人还是进行更改的人。 按照计划,任何开发人员都可以根据自己平台部分的需要修复基础设施。

如果您有一个大型项目,并且将整个基础设施划分为一些小部分并在单独的文件夹中描述每个部分是有意义的,那么这是 HashiCorp 本身推荐的目录树。

拥有广泛的资源库,您可以在测试和生产中调用大致相同的东西。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

在我们的例子中,这并不完全合适,因为开发人员或测试的测试堆栈需要以某种更简单的方式获得。 但我不想遍历文件夹并按所需的顺序应用它们,并担心数据库会上升,然后使用该数据库的实例也会上升。 因此,所有测试都是从一个文件夹启动的。 那里调用了相同的模块,但一切都是在一次运行中完成的。

Terraform 负责处理所有依赖关系。 并且它总是按顺序创建资源,以便您可以获取IP地址,例如,从新创建的实例中获取IP地址,并在route53记录中获取该IP地址。

另外,平台非常大。 启动测试堆栈,即使是一个小时,即使是 8 小时,也是一项相当昂贵的任务。

我们将这件事自动化了。 Jenkins 的工作让我们能够运行堆栈。 其中,有必要启动一个拉取请求,其中包含开发人员想要测试的更改,指定所有必要的选项、组件和维度。 如果他想要性能测试,那么他可以采取更多实例。 如果他只需要检查某些表格是否打开,那么他可以从最低工资开始。 还指出是否需要集群等。

然后Jenkins推送了一个shell脚本,该脚本稍微修改了Terraform文件夹中的代码。 我删除了不必要的文件并添加了必要的文件。 然后,通过运行一次 Terraform apply,堆栈就会被提升。

然后还有其他一些我不想讨论的步骤。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

由于测试时我们需要比生产中更多的选项,因此我们必须复制模块,以便在这些副本中我们可以添加仅测试所需的功能。

碰巧的是,在测试中我有点想测试那些最终将投入生产的更改。 但实际上,测试了一种东西,在生产中使用了一种略有不同的东西。 生产中所有变更均由运营团队应用的模式有一个小小的突破。 有时事实证明,那些本应从测试到生产的更改仍然保留在另一个版本中。

此外,还有一个问题是添加了一项新服务,该服务与一些已经存在的服务略有不同。 我们必须复制现有模块并添加必要的更改,而不是修改现有模块。

本质上,Terraform 并不是一种真正的语言。 这是一个声明。 如果我们需要声明什么,那么我们就声明它。 这一切都有效。

在某个时候,当讨论我的一个拉取请求时,我的一位同事说没有必要创建雪花。 我想知道他是什么意思。 有一个科学事实:世界上没有两片完全相同的雪花,它们都略有不同。 当我听到这个消息时,我立即感受到了 Terraform 代码的全部分量。 因为当需要从一个版本迁移到另一个版本时,Terraform 需要打破链式更改,即代码不再与下一个版本兼容。 我们必须发出拉取请求,该请求涵盖了基础设施中几乎一半的文件,以便将基础设施引入下一版本的 Terraform。

当这样的雪花出现之后,我们所有的Terraform代码都变成了一大堆雪。

对于操作之外的外部开发人员来说,这对他来说并不重要,因为他发出了拉取请求,他的资源就启动了。 仅此而已,这已经不再是他关心的事了。 确保一切正常的 DevOps 团队需要进行所有这些更改。 每增加一片雪花,这些改变的成本就会增加得非常非常多。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

有一个故事是关于一个研讨会上的学生如何用粉笔在黑板上画两个完美的圆圈。 老师很惊讶他在没有圆规的情况下竟然能画得如此流畅。 学生回答:“很简单,我在部队呆了两年,开绞肉机。”

在我参与这个项目的四年中,我从事 Terraform 工作大约两年了。 当然,我有一些技巧和一些关于如何简化 Terraform 代码、像编程语言一样使用它以及减轻必须保持此代码最新的开发人员的负担的建议。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

我想开始的第一件事是符号链接。 Terraform 有很多重复的代码。 例如,我们创建基础设施的几乎每个点对提供商的调用都是相同的。 将其放在单独的文件夹中是合乎逻辑的。 以及任何需要提供者为此文件创建符号链接的地方。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

例如,在生产中,您使用假设角色,这允许您获得某些外部亚马逊帐户的访问权限。 更改一个文件后,资源树中的所有剩余文件都将拥有所需的权限,以便 Terraform 知道要访问哪个 Amazon 段。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

符号链接在哪里失败? 正如我所说,Terraform 有状态文件。 他们非常非常酷。 但问题是 Terraform 首先初始化了后端。 并且他不能在这些参数中使用任何变量;它们必须始终以文本形式编写。

结果,当有人制作新资源时,他会从其他文件夹复制一些代码。 他可能会弄错钥匙或水桶。 例如,他从沙箱中制作沙箱的东西,然后在生产中制作它。 因此,生产中的存储桶可能会从沙箱中使用。 当然,他们很快就会找到。 有可能以某种方式解决这个问题,但无论如何,这都是浪费时间,并且在某种程度上浪费资源。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

接下来我们可以做什么? 在使用 Terraform 之前,您需要对其进行初始化。 在初始化时,Terraform 下载所有插件。 在某些时候,它们从单体架构分裂为更加微服务的架构。 而且您始终需要执行 Terraform init,以便它拉出所有模块、所有插件。

您可以使用 shell 脚本,它首先可以获取所有变量。 shell脚本不以任何方式受到限制。 其次,路径。 如果我们始终使用存储库中的路径作为状态文件的密钥,那么相应地,这里的错误将被消除。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

我在哪里可以获得数据? JSON 文件。 Terraform 不仅允许您使用 hcl(HashiCorp 配置语言)编写基础设施,还允许您使用 JSON 编写基础设施。

JSON 很容易从 shell 脚本中读取。 因此,您可以将带有存储桶的配置文件放在某个位置。 并在 Terraform 代码和 shell 脚本中使用此存储桶进行初始化。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

为什么为 Terraform 提供一个存储桶很重要? 因为有远程状态文件这样的东西。 也就是说,当我提出一些资源时,为了告诉亚马逊:“请提出实例”,我需要指定很多必需的参数。

这些标识符存储在其他文件夹中。 我可以说:“Terraform,请运行到该资源的状态文件并为我提供这些标识符。” 因此,不同地区或环境之间出现了某种统一。

并不总是可以使用远程状态文件。 例如,您手动创建了一个VPC。 创建 VPC 的 Terraform 代码会创建如此不同的 VPC,这将需要很长时间,并且您必须将一个 VPC 调整为另一个 VPC,因此您可以使用以下技巧。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

也就是说,创建一个似乎创建 VPC 的模块,并且可以为您提供标识符,但实际上只是一个包含硬编码值的文件,可用于创建相同的实例。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

并不总是需要将状态文件保存在云中。 例如,在测试模块时,您可以使用后端初始化,其中文件将在测试时简单地保存在磁盘上。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

现在介绍一下测试。 您可以在 Terraform 中测试什么? 可能有很多可能,但我会谈谈这四件事。

HashiCorp 了解 Terraform 代码应如何格式化。 而 Terraform fmt 允许您根据这种信念来格式化您编辑的代码。 因此,测试必须检查格式是否与 HashiCorp 遗赠的格式相对应,以便不需要更改括号的位置等。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

下一个是 Terraform 验证。 它只是检查语法 - 唉,所有括号是否都配对。 这里重要的是什么? 我们的基础设施非常广泛。 里面有很多不同的爸爸。 在每个中,您都需要运行 Terraform 验证。

因此,为了加快测试速度,我们使用并行方式并行运行多个进程。

并行是一个非常酷的东西,使用它。

但每次 Terraform 初始化时,它都会向 HashiCorp 询问:“最新的插件版本是什么? 还有我缓存中的插件——它是正确的还是错误的?” 而且每一步都减慢了速度。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

如果你告诉 Terraform 插件在哪里,那么 Terraform 会说:“好吧,这可能是最新的东西。 我哪儿也不去,我会立即开始验证你的 Terraform 代码。”

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

为了用必要的插件填充文件夹,我们有一个非常简单的 Terraform 代码,只需要初始化即可。 当然,在这里,您需要指定以某种方式参与代码的所有提供程序,否则 Terraform 会说:“我不知道某个提供程序,因为它不在缓存中。”

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

接下来是 Terraform 计划。 正如我所说,发展是周期性的。 我们对代码进行更改。 然后您需要了解计划对基础设施进行哪些更改。

当基础设施非常非常大时,您可以更改一个模块,修复某些测试环境或某些特定区域并破坏某些相邻的模块。 因此,应该为整个基础设施制定 Terraform 计划,并显示计划进行哪些更改。

你可以巧妙地做到这一点。 例如,我们编写了一个解决依赖关系的Python脚本。 根据更改的内容:Terraform 模块或特定组件,它会为所有依赖文件夹制定计划。

Terraform 计划必须根据要求制定。 至少我们就是这么做的。

当然,为每次更改、每次提交进行测试是件好事,但计划是相当昂贵的事情。 在拉取请求中,我们说:“请给我计划。” 机器人启动。 并发送评论或附上您的更改预期的所有计划。

计划是一件相当昂贵的事情。 这需要时间,因为 Terraform 会去亚马逊询问:“这个实例还存在吗? 这个自动秤的参数一模一样吗?” 为了加快速度,您可以使用刷新= false 等参数。 这意味着 Terraform 将从 S3 下载状态。 并且它会相信该状态将与亚马逊中的状态完全匹配。

这样的 Terraform 计划要快得多,但状态必须与您的基础设施相对应,即在某个地方、某个时间必须开始 Terraform 刷新。 Terraform 刷新正是这样做的:状态与实际基础设施中的内容相匹配。

我们需要谈谈安全。 这是我们必须开始的地方。 当您运行 Terraform 且 Terraform 在您的基础设施上运行时,存在漏洞。 也就是说,您实际上是在执行代码。 如果拉取请求包含某种恶意代码,那么它可以在具有过多访问权限的基础设施上执行。 因此,在运行 Terraform 计划的地方要小心。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

接下来我想谈的是用户数据测试。

什么是用户数据? 在亚马逊中,当我们创建实例时,我们可以随该实例发送特定的字母——元数据。 当实例启动时,通常 cloud init 始终存在于这些实例上。 Cloud init 读到这封信后说道:“好吧,今天我是负载均衡器。” 并且按照这些契约他执行一些行动。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

但是,不幸的是,当我们制定 Terraform 计划并应用 Terraform 时,用户数据看起来就像是一堆数字。 也就是说,他只是向您发送哈希值。 你在计划中所能看到的就是是否会有任何变化或者哈希值是否保持不变。

如果您不注意这一点,那么一些损坏的文本文件可能最终会出现在亚马逊的真实基础设施上。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

或者,在执行时,您可以不指定整个基础架构,而仅指定模板。 并在代码中说:“请在我的屏幕上显示此模板。” 因此,您可以打印出您的数据在亚马逊上的样子。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

另一种选择是使用模块来生成用户数据。 您将应用此模块。 您收到磁盘上的文件。 与参考品进行比较。 因此,如果有人决定稍微更正用户数据,那么你的测试会说:“好吧,这里那里有一些变化 - 这是正常的。”

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

接下来我想谈的是自动化 Terraform 应用。

当然,以自动模式应用 Terraform 是相当可怕的,因为谁知道那里发生了什么变化以及它们对生活基础设施有多大破坏性。

对于测试环境来说,这都是正常的。 也就是说,创建测试环境的工作是所有开发人员都需要的。 像“一切都对我有用”这样的表达并不是一个有趣的模因,而是证明一个人感到困惑,提出了一个堆栈,并在这个堆栈上运行了一些测试。 他确保一切正常后说道:“好的,我要发布的代码已经过测试。”

在生产、沙箱和其他对业务更为关键的环境中,您可以非常安全地部分使用某些资源,因为它不会导致任何人死亡。 它们是:自动缩放组、安全组、角色、route53,并且列表可能相当大。 但请密切关注正在发生的事情,阅读自动应用程序报告。

如果应用是危险或可怕的,例如,如果这些是来自数据库的一些持久资源,则收到有关基础设施的某些部分存在未应用的更改的报告。 工程师在监督下开始申请工作或通过他的控制台进行工作。

亚马逊有“终止保护”之类的东西。 在某些情况下,它可以防止您不需要的更改。 也就是说,Terraform 去了亚马逊并说:“我需要杀死这个实例以创建另一个实例。” 亚马逊说:“抱歉,今天不行。 我们有终止保护。”

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

锦上添花的是代码优化。 当我们使用 Terraform 代码时,我们必须向模块传递大量参数。 这些是创建某种资源所必需的参数。 并且代码会变成大量参数,需要从一个模块传递到另一个模块、从一个模块传递到另一个模块,尤其是在模块嵌套的情况下。

而且它很难阅读。 对此进行审查非常困难。 很多时候,事实证明,一些参数经过审查,但它们并不完全是所需要的。 这需要时间和金钱来修复。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

因此,我建议您使用这样的东西作为包含特定值树的复杂参数。 也就是说,您需要某种文件夹,其中包含您希望在某个环境中拥有的所有值。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

通过调用该模块,您可以获得一棵在一个公共模块中生成的树,即在对整个基础设施具有相同作用的公共模块中生成的树。

在本模块中,您可以使用 Terraform 中的最新功能(如局部变量)进行一些计算。 然后,通过一个输出,给出一些复杂的参数,其中可能包括数组哈希值等。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

这是我所有最好的发现结束的地方。 我想讲一个关于哥伦布的故事。 当他为发现印度的探险队寻找资金时(正如他当时所想的那样),没有人相信他,他们认为这是不可能的。 然后他说:“确保鸡蛋不会掉下来。” 所有的银行家,非常富有而且可能很聪明的人,都试图以某种方式放置鸡蛋,但它不断掉落。 然后哥伦布拿起鸡蛋,稍微压了一下。 蛋壳碎了,蛋一动不动。 他们说:“哦,这太简单了!” 哥伦布回答说:“是的,这太简单了。 当我开放印度时,每个人都会使用这条贸易路线。”

而我刚才告诉你的,可能是很简单、琐碎的事情。 当你了解它们并开始使用它们时,一切都是按顺序进行的。 所以要充分利用。 如果这些对你来说是完全正常的事情,那么至少你知道如何放置鸡蛋以免它掉落。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

总结一下:

  • 尽量避免雪花。 雪花越少,您在整个大型基础设施中进行任何更改所需的资源就越少。
  • 不断的变化。 也就是说,当代码中发生某些更改时,您需要尽快使您的基础架构符合这些更改。 不应该出现这样的情况:两三个月后有人来看Elasticsearch,制定了Terraform计划,并且出现了一堆他没有预料到的变化。 并且需要花费很多时间才能让一切恢复正常。
  • 测试和自动化。 您的代码包含的测试和功能越多,您就越有信心自己所做的一切都是正确的。 自动交付将使您的信心倍增。
  • 测试环境和生产环境的代码应该几乎相同。 实际上,因为生产仍然有点不同,并且仍然存在一些超出测试环境的细微差别。 但无论如何,这都是可以保证的。
  • 如果您有大量 Terraform 代码,并且需要花费大量时间来使这些代码保持最新,那么重构并使其保持良好状态永远不会太晚。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

  • 不可变的基础设施。 AMI 按计划交付。
  • 当您有很多条目并且希望它们的顺序一致时,route53 的结构。
  • 对抗 API 速率限制。 这时亚马逊说:“就是这样,我无法接受更多请求,请稍等。” 一半的办公室正在等待基础设施启动。
  • 现货实例。 亚马逊并不是一个便宜的活动,而且景点可以让你节省很多。 在那里你可以讲述一份完整的报告。
  • 安全和 IAM 角色。
  • 寻找丢失的资源,当你在亚马逊有来源不明的实例时,它们会吃钱。 即使实例每月费用为 100-150 美元,每年也超过 1 美元。 寻找这样的资源是一项有利可图的生意。
  • 和预留实例。

Terraform 中的模式可对抗混乱和手动例程。 马克西姆·科斯特里金 (Ixtens)

这就是我的全部。 Terraform 很酷,你用它。 谢谢你!

问题

感谢您的报告! 你的状态文件在S3中,但是如何解决几个人可以拿走这个状态文件并尝试扩展的问题?

首先,我们并不着急。 其次,有一些标志,我们在其中报告我们正在编写某些代码。 也就是说,尽管基础设施非常庞大,但这并不意味着有人在不断地使用某些东西。 当有一个活跃阶段时,这就是一个问题;我们将状态文件存储在 Git 中。 这很重要,否则有人会制作状态文件,我们必须手动将它们放在一起才能使一切继续。 现在不存在这样的问题了。 总的来说,Terraform 解决了这个问题。 如果某些内容不断变化,那么您可以使用锁来阻止您所说的内容。

您使用开源还是企业?

没有企业,即您可以免费下载的所有内容。

我的名字是斯坦尼斯拉夫。 我想做一点补充。 您谈到了 Amazon 的一项功能,该功能允许您使实例无法被杀死。 Terraform 本身也是如此;在 Life Second 块中,您可以指定禁止更改或禁止破坏。

时间有限。 好点子。

我还想问两件事。 首先,您谈到了测试。 您使用过任何测试工具吗? 我听说过 Test Kitchen 插件。 也许还有更多的事情。 我还想问一下当地价值观。 它们与输入变量有什么根本不同? 为什么我不能仅通过本地值参数化某些内容? 我试图弄清楚这个话题,但不知何故我自己无法弄清楚。

我们可以在这个房间外更详细地讨论。 我们的测试工具完全是自制的。 没有什么可以测试的。 一般来说,当自动化测试在某处获取基础设施时,有一些选择,检查它是否正常,然后销毁所有内容,并报告您的基础设施仍处于良好状态。 我们没有这个,因为测试堆栈每天都在运行。 这就足够了。 如果某些东西开始损坏,我们无需在其他地方检查它,它就会开始损坏。

关于当地价值观,我们在室外继续讨论吧。

你好! 感谢您的报告! 信息非常丰富。 你说你有很多相同类型的代码来描述基础设施。 您是否考虑过生成此代码?

很好的问题,谢谢! 关键是,当我们使用基础设施即代码时,我们假设我们查看代码并了解该代码背后的基础设施。 如果生成了代码,那么我们需要想象将生成什么代码,以便了解那里会有什么样的基础设施。 要么我们生成代码,提交它,本质上会发生相同的事情。 所以我们按照我们写的路走,我们得到了它。 当我们开始制造 Plus 发电机时,它们出现得稍晚一些。 而此时想要改变已经太晚了。

你听说过 jsonnet 吗?

看,这是一件非常酷的事情。 我看到一个特定的案例,您可以应用它并生成数据结构。

拥有发电机就很好用,就像关于剃须机的笑话一样。 也就是说,第一次的脸是不同的,但后来每个人的脸都是一样的。 发电机工作得很好。 但不幸的是,我们的面孔略有不同。 这是问题。

只是看看。 谢谢你!

我叫马克西姆,来自俄罗斯联邦储蓄银行。 您谈到了如何尝试将 Terraform 转化为相当于编程语言的内容。 使用 Ansible 不是更简单吗?

这些是非常不同的事情。 您可以在 Ansible 中创建资源,Puppet 可以在 Amazon 中创建资源。 但 Terraform 是直接锐化的。

你们只有亚马逊吗?

这并不是说我们只有亚马逊。 我们几乎只有亚马逊。 但关键特征是 Terraform 具有记忆功能。 在 Ansible 中,如果你说:“给我 5 个实例”,那么它就会升高,然后你说:“现在我需要 3 个。” Terraform 会说:“好吧,我会杀掉 2 个”,Ansible 会说:“好吧,这是 3 个给你。” 共 8 个。

你好! 感谢您的报告! 听到 Terraform 的消息非常有趣。 我想立即对 Terraform 仍然没有稳定版本这一事实发表一点评论,因此请谨慎对待 Terraform。

晚餐的好勺子。 也就是说,如果你需要一个解决方案,那么有时你会推迟不稳定的事情等等,但它有效并且对我们有帮助。

问题是这样的。 你使用远程后端,你使用S 3。为什么不使用官方后端?

官方?

地形云。

他什么时候出现的?

大约4个月前。

如果它出现在四年前,那么我可能会回答你的问题。

已经有内置函数和锁,并且可以存储状态文件。 试一试。 但我也没有测试过。

我们乘坐一列高速行驶的大型火车。 而且你不能只拿走几辆车然后扔掉。

你谈到了雪花,为什么不用树枝呢? 为什么事情没有这样发展呢?

我们的方法是,整个基础设施都位于一个存储库中。 Terraform、Puppet、所有与此相关的脚本,它们都在一个存储库中。 这样我们就可以确保增量更改被一个又一个地测试。 如果是一堆分支,那么这样的项目几乎不可能维护。 六个月过去了,他们的分歧如此之大,以至于这只是某种惩罚。 这就是我在重构之前想要逃避的。

那么它不起作用吗?

这根本行不通。

在分支中,我剪出了文件夹幻灯片。 也就是说,如果你对每个测试堆栈都这样做,例如,团队 A 有自己的文件夹,团队 B 有自己的文件夹,那么这也不起作用。 我们创建了一个统一的测试环境代码,该代码足够灵活,可以适合每个人。 也就是说,我们提供了一个代码。

你好! 我的名字是尤拉! 感谢您的报告! 关于模块的问题。 你说你正在使用模块。 如果对一个模块所做的更改与其他人的更改不兼容,您如何解决问题? 您是否以某种方式对模块进行版本控制或尝试使用 wunderwaffle 来满足两个要求?

这是一个大雪堆问题。 当一些无害的变化可能破坏基础设施的某些部分时,我们就会遭受这种痛苦。 而且这一点只有在很长一段时间后才会明显。

也就是说,事情还没有解决?

您制作通用模块。 避免雪花。 一切都会成功。 报告的后半部分是关于如何避免这种情况的。

你好! 感谢您的报告! 我想澄清一下。 在幕后有一大堆我来找的。 Puppet 和角色分配是如何集成的?

用户数据。

也就是说,您只是吐出文件并以某种方式执行它?

用户数据是一个注释,即当我们克隆图像时,Daemon 会在那里升起,并试图找出他是谁,并读取他是负载均衡器的注释。

也就是说,这是某种被放弃的单独过程吗?

它不是我们发明的。 我们用它。

你好! 我只是有一个关于用户数据的问题。 你说那里有问题,有人可能会把东西发送到错误的地方。 是否有某种方法可以将用户数据存储在同一个 Git 中,以便始终清楚用户数据所指的内容?

我们从模板生成用户数据。 也就是说,那里使用了一定数量的变量。 Terraform 生成最终结果。 因此,你不能只看模板就说会发生什么,因为所有的问题都与开发人员认为他在这个变量中传递了一个字符串,但那里使用了一个数组有关。 然后他——砰的一声和我——某某,某某,下一行,一切都崩溃了。 如果这是一个新资源,有人拿起它并发现有些东西不起作用,那么它很快就会得到解决。 如果更新此自动缩放组,则在某个时刻自动缩放组中的实例将开始被替换。 砰,有些东西不起作用了。 好痛。

原来唯一的解决办法就是测试?

是的,您看到了问题,您在那里添加了测试步骤。 也就是说,还可以测试输出。 也许不太方便,但您也可以做一些标记 - 检查用户数据是否已固定在此处。

我的名字是帖木儿。 有关于如何正确组织 Terraform 的报告真是太酷了。

我还没开始呢

我想也许在下一次会议上会有。 我有一个简单的问题。 为什么将值硬编码在单独的模块中而不是使用 tfvars,即为什么具有值的模块比 tfvars 更好?

也就是说,我应该在这里写(幻灯片:Production/environment/settings.tf):domain = variable、domain vpcnetwork、variable vpcnetwork 和 stvars – 我可以得到同样的东西吗?

这正是我们所做的。 例如,我们指的是设置源模块。

本质上,这就是这样的 tfvar。 Tfvars 在测试环境中非常方便。 我有针对大型实例和小型实例的 tfvar。 我将一个文件放入文件夹中。 我得到了我想要的。 当我们削减基础设施时,我们希望能够查看并立即了解一切。 所以事实证明你需要看看这里,然后看看 tfvars。

是否有可能将一切都集中在一处?

是的,tfvars 就是当你只有一个代码时。 它被用在几个不同的地方,有不同的细微差别。 然后你会抛出 tfvars 并得到你的细微差别。 我们是最纯粹形式的基础设施即代码。 我一看就明白了。

你好! 您是否遇到过云提供商干扰您制作的 Terraform 的情况? 假设我们编辑元数据。 有 ssh 密钥。 谷歌不断地将其元数据和密钥放在那里。 Terraform 总是写它有变化。 每次运行后,即使没有任何变化,他总是说他现在就更新这个字段。

有了密钥,但是,是的,部分基础设施受到了这个东西的影响,即 Terraform 无法改变任何东西。 我们也无法用手改变任何事情。 我们暂时就接受它。

就是你遇到了这样的事情,但是没有想出什么办法,他是怎么做的,自己是怎么做的?

不幸的是,是的。

你好! 我的名字是斯塔科​​夫·斯坦尼斯拉夫。 邮件。 茹集团. 怎么解决在…上生成标签的问题,怎么传进去呢? 据我了解,通过User-data来指定主机名,设置Puppet on? 以及问题的第二部分。 你如何在SG中解决这个问题,即当你生成SG时,数百个相同类型的实例,它们的正确名称是什么?

那些对我们非常重要的实例,我们会用漂亮的名字来命名。 那些不需要的,有一个注释,这是一个自动缩放组。 从理论上讲,您可以将其固定下来并购买新的。

至于标签的问题,不存在这样的问题,但是有这样的任务。 我们非常非常频繁地使用标签,因为基础设施庞大且昂贵。 我们需要了解资金的去向,因此标签可以让我们详细了解资金的去向。 因此,寻找一些意味着很多钱的东西都花在这里。

问题还涉及什么?

当SG创建数百个实例时,是否需要以某种方式区分它们?

不,不要。 在每个实例上都有一个代理报告我遇到了问题。 如果代理报告,则该代理知道他,并且至少知道他的 IP 地址存在。 你已经可以逃跑了。 其次,我们使用 Consul 进行发现,而 Kubernetes 则没有。 Consul 还显示实例的 IP 地址。

也就是说,您是否特别关注 IP,而不是主机名?

无法通过主机名进行导航,即主机名有很多。 有实例标识符-AE等。你可以在某个地方找到它,你可以把它扔到搜索中。

你好! 我意识到 Terraform 是一个好东西,专为云量身定制。

不仅如此。

这正是我感兴趣的问题。 例如,如果您决定将所有实例全部迁移到裸机? 会不会有什么问题? 或者您仍然需要使用其他产品,例如此处提到的同一个 Ansible?

Ansible 还涉及其他一些事情。 也就是说,当实例启动时,Ansible 就已经可以工作了。 Terraform 在实例启动之前工作。 切换到裸机 - 不。

不是现在,但生意会过来并说:“来吧。”

切换到另一个云——是的,但这里有一个稍微不同的技巧。 您需要以这样的方式编写 Terraform 代码,以便您可以轻松地切换到其他云。

最初,设定的任务是我们整个基础设施是不可知的,即任何云都应该适合,但在某个时候业务放弃了并说:“好吧,在接下来的 N 年内我们不会去任何地方,我们可以使用服务来自亚马逊“

Terraform 允许您创建前端作业、配置 PagerDuty、数据文档等。它有很多尾巴。 他几乎可以掌控整个世界。

感谢您的报告! 我使用 Terraform 已有 4 年了。 在平稳过渡到 Terraform、基础设施、声明性描述的阶段,我们面临着这样一种情况:有人手工做某事,而你试图制定计划。 我在那里遇到了某种错误。 您如何处理此类问题? 如何找到已列出的丢失资源?

主要是用我们的手和眼睛,如果我们在报告中看到一些奇怪的东西,那么我们就会分析那里发生了什么,或者干脆杀人。 一般来说,拉取请求是很常见的事情。

如果出现错误,是否回滚? 你尝试过这样做吗?

不,这是一个人看到问题那一刻的决定。

来源: habr.com