云服务器价格_云数据库_云主机【优惠】最新活动-搜集站云资讯

微软云_找不到服务器应用程序_便宜的

小七 141 0

HashiCorp Terraform:模块作为基础设施的构建块

运营商采用HashiCorp Terraform这样的工具来提供管理基础设施的简单工作流。用户编写配置并运行一些命令来测试和应用更改。然而,基础设施管理通常超出了简单的配置,我们需要一个工作流来构建、发布和共享定制、验证和版本控制的配置。这个工作流的成功实现从可重用配置开始,在这篇文章中,我们将研究模块、它们解决的问题,以及如何利用它们来为基础设施构建构件。Terraform模块提供了一种将公共配置块抽象为可重用基础设施元素的简单方法。要编写模块,您可以应用与任何配置相同的概念。模块是包含资源、输入变量和输出的.tf文件的集合,这些文件位于配置的根文件夹之外。类似应用程序代码的基础结构代码受益于由三个步骤组成的管理良好的方法:编写、测试和重构。模块可以帮助实现这一点,因为它们可以显著减少重复、启用隔离并增强可测试性。模块也有助于理解。以consur集群为例。如果要在GCP中创建consur集群,那么最低配置将需要一个实例组管理器、实例模板和多个防火墙规则。一旦在Terraform配置中对这些资源进行了编码,我们如何将资源集标识为consur集群?我们可以使用一个通用的命名约定,或者我们可以读取配置并尝试破译它们的意图,但是,这些都不是特别明显的。如果我们将这些资源写在地形配置中,它们看起来像这样:资源"google_compute_instance_group_manager""consul_server"{名称="${var.cluster_名称}-ig"# ...}resource"google_compute_instance_template""执政者服务器""私有"{count="${1-var.assign_public_ip_地址}"# ...}资源"谷歌计算防火墙""允许集群内领事"{名称="${var.cluster_名称}-规则群集"网络="${网络名称}"# ...}资源"google_compute_firewall""允许_inboud_http_api"{count="${length(变量允许的入站cidr阻止dns)+长度(变量允许的\u入站标记\u dns)>0?1:0}"# ...}代码片段中的配置在某种程度上是可以理解的;但是,当您查看未桥接的版本时,需要时间来推断其含义。完整的实现包含在下面的文件中。地形谷歌执政官/主.tf在master·hashicorp/terraform谷歌领事·GitHub就我个人而言,如果没有事先的了解,很难确定它正在创建一个执政官集群。像软件一样,你花在阅读配置上的时间比写东西的时间要多,声明性基础结构代码的一个主要好处就是这种理解。可维护的基础设施代码的关键是确保代码在以后的某个日期是可以理解的,并且可能被不是原始作者的读者理解。复制呢?如果您管理一个大型基础设施,则可能有多个集群。如果创建集群的资源是在多个地形配置中复制的,而您必须更改某些内容,则需要多次执行此操作。如果您在一个全球分布的团队中工作,协调工作以避免重复可能是一个挑战,团队a构建他们的应用程序配置,其中包括CONSUR;团队B构建另一个包括CONSUR的应用程序配置。现在,甚至在我们讨论代码库的一致性之前,您已经重复了工作并浪费了时间。另一个主要的问题是测试基础设施配置,配置越复杂,包含的资源越多,测试就越具有挑战性和耗时性。小型模块化组件允许您隔离测试。例如,您要升级consur版本,需要修改实例模板。当定义conver集群的资源没有模块化时,您可能需要创建整个堆栈来测试一个小组件。尽管Terraform在分析依赖关系和并行化资源创建方面令人印象深刻,但它仍然需要时间,如果您正在测试和调整基础结构更改,那么您可能需要多次执行应用/销毁步骤,因此您需要确保这一步尽可能快。最后是版本控制;使用单个mono配置,您必须将所有版本固定在一起。例如,您有一个Nomad集群和一个consur集群,并且目前正在考虑升级它们,如果您不采用模块化方法,那么您将绑定到一个连续的工作流。维护多个分支时考虑到所有不同的可能组合可能是一个挑战。它还使得合并和回滚任何更改的过程比仅仅更改版本号要复杂得多。»救援模块让我们看看模块如何帮助解决所有这些问题。模块是存在于根配置文件夹之外的Terraform文件的集合,可以是子文件夹,也可以是git存储库或Terraform模块注册表。模块还可以有输入和输出变量,这些变量充当其他Terraform元素的接口,并允许您设计适当级别的抽象地形只解析执行terraform命令的当前文件夹中扩展名为.tf的文件,它不会递归到子文件夹中。正因为如此,将现有配置划分为模块变得非常容易。实际上,运行terraform命令的文件夹也是一个模块,它恰好是根模块。下面的例子是集群的Terraform模块表示。"执政官"模块{source="hashicorp/consur/google"版本="0.0.1"consur_server_source_image="abc1235.img"consur_client_cluster_tag_name="应用程序群集"}我们马上就有了正确的抽象层次来理解配置在做什么。它告诉我们这个Terraform计划定义了一个conver集群,它还告诉我们我们使用的是配置的0.0.1版本。我们还在为模块资源设置rasonable默认值。当然,使用者可以通过显式设置模块变量来覆盖默认值,但这不是必需的。我们还解决了复制问题,因为我们将配置包含在一个模块中,通过添加指向同一源的其他模块,可以方便地重用。此外,我们还可以解决版本控制问题;模块还接受各种不同的源选项,这些选项允许版本控制、GitHub、bitbuck和Terraform模块注册表等。您可以将一个模块固定到一个标记或分支上,这样就可以升级模块的特定实例,而无需为所有使用者强制使用特定的版本。它还允许您在登台环境中高效地运行模块的不同版本,以方便简单的升级测试。模块源-HashiCorp Terraform从测试的角度来看,我们已经本地化了与consur集群相关的资源,这意味着我们可以在一个孤立的环境中测试这些资源。»创建模块关于模块最好的地方是你需要学习的东西很少,如果你已经在写Terraform,那么你已经可以写模块了。与根模块一样,您可以使用变量和输出节为模块指定输入和输出。让我们创建一个简单的模块,看看它是如何工作的。我用以下结构建立我的项目;我有一个主.tf它包含我的提供者和一个子文件夹modules/instance,其中包含在GCP中创建实例的terraform配置。$树.├── 自述文件.md├── 主.tf———模块├—实例├── 自述文件.md├── 主.tf├── 输出.tf└── 变量.tf在我们的文件模块/实例中/主.tf,我们创建定义实例的资源。我们不需要添加提供程序,因为它是从根模块获取的。资源"google_compute_instance""default"{name="测试"机器类型="${可变机器类型}"区域="${可变区}"启动磁盘{初始化参数{图像="${var.boot_映像}"}}网络接口{network="默认值"}元数据{foo="酒吧"}metadata_startup_script="echo hi>/测试.txt"服务账户{scopes=userinfo email","compute ro","storage ro"]}}要指定要用于实例的映像,可以创建另一个文件模块/实例/变量.tf并为引导映像、机器类型和区域定义变量。变量"boot_image"{description="实例的镜像ID"default="debian云/debian-8"}变量"机器类型"{description="实例的机器类型"默认值="n1-标准-1"}可变"区域"{description="要将实例部署到的区域"默认值="us-central1-a"}我们还需要将有关此资源的一些信息返回给根模块,因此让我们在modules/instance中创建一个输出/输出.tf输出"id"{value="${google_计算_instance.default.instance_标识}"我们现在需要做的就是从根目录引用我们的模块,为此我们使用模块节。在我们的简单示例中,我们可以这样写:提供商"谷歌云"{}"实例"模块{source="../modules/instance"boot_image="ubuntu os云/ubuntu-1604-lts"}我们声明模块并将源设置为本地文件夹;我们还需要设置所需的变量,这是通过向模块节添加键和值来实现的。因为我们为模块变量设置了代表合理默认值的默认值,所以我们不需要设置任何东西。但是,我们可以选择覆盖它们,我将引导映像从默认的debian-8更改为ubuntu-1604-lts。f