Terraformer-要编码的基础结构

图片
我想谈谈我为解决一个旧问题而编写的新CLI工具。

问题


Terraform长期以来一直是Devops / Cloud / IT社区的标准。 这对于将基础结构用作代码非常方便且有用。 Terraform中有很多魅力,还有许多叉子,锋利的刀子和耙子。
使用Terraform,可以很方便地进行新事物,然后进行管理,更改或删除。 那些在云中拥有庞大基础架构但又不是通过Terraform创建的人又如何呢? 重写和重新创建整个云在某种程度上是昂贵且不安全的。
我在2部作品中遇到了这样的问题,最简单的示例是当您希望所有内容都以terraform文件的形式出现时,并且您拥有250多个存储桶并用手编写了很多用于terraform的文件。
自2014 以来,terrafom中出现一个问题,问题已于2016年关闭,希望会有进口。

一般而言,所有内容都只从右到左如图所示


警告:撰文人在俄罗斯一生中没有半生,也很少写俄语。 注意拼写错误。

解决方案


1.有适用于AWS terraforming的交钥匙和旧解决方案。 当我尝试通过250多个存储桶时,我意识到那里的一切都很糟糕。 AWS很久以来就已经提出了许多新选项,而terraforming对此一无所知,并且总的来说,它的ruby 模板看起来很差 。 晚上2点之后,我发送了一个Pull请求要求在那里添加更多功能,并且意识到这种解决方案根本不合适。
terraforming的工作方式是,它从AWS开发工具包获取数据,并通过模板生成tf和tfstate。
有3个问题:
1.更新中总会有积压
2. tf文件有时会坏掉
3. tfstate与tf分开收集,并不总是收敛
通常,很难得到“地形计划”将说没有变化的结果

2.`terraform import`-terraform中的内置命令。 如何运作?
您用资源的名称和类型编写一个空的TF文件,然后运行“ terraform import”并传递资源的ID。 terraform调用提供者接收数据并制作一个tfstate文件。
有3个问题:
1.我们只得到tfstate文件,而tf空必须用tfstate写入或转换
2.每次只能使用一种资源,并且不支持所有资源。 250桶以上我该怎么办
3.您需要知道资源ID-也就是说,您需要将其包装在提取资源列表的代码中
通常,结果是不完整的,无法很好地扩展

我的决定

要求:
1.能够按资源创建tf和tfstate文件。 例如,下载所有存储桶/安全组/负载平衡器,并且“ terraform plan”返回没有任何更改
2.需要2个GCP + AWS云
3.易于每次更新且不会浪费3天工作时间在每种资源上的时间的全局解决方案
4.开源-每个人都有这样的问题

Go语言-这就是我喜欢它的原因,它有一个用于创建在terraform中使用的HCL文件的库以及许多在terraform中可用的代码

方式


第一次尝试
开始一个简单的选择。 通过SDK访问所需资源的云,并将其转换为用于Terraform的字段。 尝试立即在安全组上终止,因为我不愿意花1.5天的时间只转换安全组(并且有很多资源)。 长,然后字段可以更改/添加

第二次尝试
基于此处介绍的思想。 只需将tfstate转换为tf。 所有数据都在那里,并且字段相同。 如何获得许多资源的完整tfstate? 然后,“ terraform refresh”命令进行了救援。 terraform在tfstate中获取所有资源,并按ID提取数据,并将所有内容写入tfstate。 也就是说,创建一个仅包含名称和ID的空tfstate,运行“ terraform refresh”,即可获得完整的tfstate。 万岁!
现在,让我们来做递归的色情作品,即为tfstate到tf编写一个转换器。 对于从未读过tfstate的用户,这是JSON,但很特殊。
这是它的重要部分属性
"attributes": { "id": "default/backend-logging-load-deployment", "metadata.#": "1", "metadata.0.annotations.%": "0", "metadata.0.generate_name": "", "metadata.0.generation": "24", "metadata.0.labels.%": "1", "metadata.0.labels.app": "backend-logging", "metadata.0.name": "backend-logging-load-deployment", "metadata.0.namespace": "default", "metadata.0.resource_version": "109317427", "metadata.0.self_link": "/apis/apps/v1/namespaces/default/deployments/backend-logging-load-deployment", "metadata.0.uid": "300ecda1-4138-11e9-9d5d-42010a8400b5", "spec.#": "1", "spec.0.min_ready_seconds": "0", "spec.0.paused": "false", "spec.0.progress_deadline_seconds": "600", "spec.0.replicas": "1", "spec.0.revision_history_limit": "10", "spec.0.selector.#": "1", 

有:
1. id-字符串
2.元数据-大小为1的数组,其中是一个带有字段的对象,下面将对此进行描述
3. spec-大小为1的哈希值,其键值为
简而言之,这是一种有趣的格式,所有内容都可以在多个层次上深入
  "spec.#": "1", "spec.0.min_ready_seconds": "0", "spec.0.paused": "false", "spec.0.progress_deadline_seconds": "600", "spec.0.replicas": "1", "spec.0.revision_history_limit": "10", "spec.0.selector.#": "1", "spec.0.selector.0.match_expressions.#": "0", "spec.0.selector.0.match_labels.%": "1", "spec.0.selector.0.match_labels.app": "backend-logging-load", "spec.0.strategy.#": "0", "spec.0.template.#": "1", "spec.0.template.0.metadata.#": "1", "spec.0.template.0.metadata.0.annotations.%": "0", "spec.0.template.0.metadata.0.generate_name": "", "spec.0.template.0.metadata.0.generation": "0", "spec.0.template.0.metadata.0.labels.%": "1", "spec.0.template.0.metadata.0.labels.app": "backend-logging-load", "spec.0.template.0.metadata.0.name": "", "spec.0.template.0.metadata.0.namespace": "", "spec.0.template.0.metadata.0.resource_version": "", "spec.0.template.0.metadata.0.self_link": "", "spec.0.template.0.metadata.0.uid": "", "spec.0.template.0.spec.#": "1", "spec.0.template.0.spec.0.active_deadline_seconds": "0", "spec.0.template.0.spec.0.container.#": "1", "spec.0.template.0.spec.0.container.0.args.#": "3", 

通常,想要面试的编程任务的人,只需要为此写一个解析器即可:)
长时间尝试编写没有错误的解析器后,我在terraform代码中找到了它的一部分,也是最重要的部分。 而且一切似乎都正常

尝试三
terraform provider是一个二进制文件,其中包含一个代码,其中包含使用云API的所有资源和逻辑。 每个云都有自己的提供程序,并且terraform本身仅通过两个进程之间的RPC协议来调用它们。
现在,我决定直接通过RPC调用来访问terraform提供程序。 事实证明,这很漂亮,并且可以在不更改代码的情况下将terraform提供程序更改为更新的提供程序并获得新的机会。 事实证明,并非tfstate中的所有字段都应该在tf中,但是我怎么知道呢? 只需向提供者询问。 然后,对正则表达式汇编的另一种递归色情从搜索开始 ,即在各个级别的tfstate内搜索字段。

最后,我们获得了一个有用的CLI工具,该工具具有适用于所有terraform提供商的通用基础架构,您可以轻松添加一个新的。 添加资源也占用很少的代码。 加上各种好处,例如资源之间的连接。 当然,存在许多无法描述的不同问题。
他称小动物Terrafomer。

决赛


使用Terrafomer,我们从两朵云中生成了500-70万行tf + tfstate代码。 他们可以采用旧有的东西,并仅通过terraform来接触它们,就像基础设施的最佳构想就是代码一样。 当您拿起巨大的云并通过命令以terraform工作文件的形式获取它时,这就是魔术。 然后grep / replace / git等。

他梳理并整理,得到许可。 于周四(05/02/19)在github上全部发布。 github.com/GoogleCloudPlatform/terraformer
已经收到600颗星,有2个请求请求增加了对openstack和kubernetes的支持。 好评价。 总的来说,该项目对人们有用
我建议每个想要开始使用Terraform而不是为此重写所有内容的人。
我很乐意提出要求,问题和建议。

演示版


更新:搞砸了对Openstack的最小支持,并且由于PR的支持,kubernetes的支持已经准备就绪

Source: https://habr.com/ru/post/zh-CN450410/


All Articles