<$>[注]
注:这是导航员指南书的内容的早期版本,这是数字海洋解决方案工程师的报价。本书的目的是帮助企业客户规划他们的基础设施需求,提供沿途的工作示例,并包括技术细节和为什么
使一些决定比其他更好。
该书和附加代码将在GitHub存储库中公开获取,因为这是一个早期版本,该书尚未完成,存储库尚未公开,但保持定制! <$>
上一节使用了Terraform和Ansible来提供资源(Droplets,负载平衡器和保留IP)并部署您的WordPress应用程序。
Terraform 使用 main.tf
文件创建了这些资源. 目前,该文件中的所有资源都单独列出. 环境越复杂,您将需要的资源就越多,并且这个文件将越长,更复杂。
在本附加部分中,我们讨论了使用Terraform模块和独立的基础设施环境来简化此配置的一些方法. 在本节中没有执行代码,也没有进行更改,但构建真实世界设置时,这些概念很重要。
了解 Terraform 模块
使用Terraform自己的模块描述:
Terraform 中的模块是 Terraform 配置的自包含包,作为一个组被管理,模块用于在 Terraform 中创建可重复使用的组件以及基本的代码组织。
模块可以创建可重复使用的基础设施块,可以接收输入和提供输出,就像高级编程语言中的函数一样。我们可以创建模块,为我们基础设施的类似部分接受可选输入参数,并为这些输入参数设置默认值。这有助于组织和简化您的配置。您可以在 Terraform 的模块文档中了解更多关于模块的信息。
对于一个完整的示例,请看 main.tf
文件. 最后一部分实际上已经使用了 Terraform 模块:
1module "sippin_db" {
2 source = "github.com/cmndrsp0ck/galera-tf-mod.git?ref=v1.0.6"
3 ...
4}
您可以将此部分与wp_node
资源块对比到文件的顶部,该文件有更多的代码行,并且更难遵循。您会注意到该模块使用远程 git 存储库进行调用。您可以使用本地文件路径,这可以为一些快速的开发和测试工作,但使用远程 git repo 将您的环境隔离一步进一步。这在运行多个基础设施环境时尤其有用,例如舞台制作和生产时。当使用本地文件路径使用多个基础设施环境时,您可以最终做出改变,目的仅是影响阶段化,但如果您要在 prod上运行一个应用程序,并且模块文件路径正在共享,那么您可能会最终破坏某些东西。如果您有每个环境的专门目录,那么您最终将不得不保留两份或多个脚本,
使用远程 git 存储库并为模块指定版本号可以避免此问题,正如前面提到的,如果有任何错误,还可以更容易返回已知的工作版本,从而提高您管理事件和中断的能力(我们将在第 9 章中详细介绍)。
这个模块不仅仅是创建一个单一的Droplet。它创建了Droplet标签、Galera集群节点、负载平衡器和保留的IP。你可以把地形模块看作是包装组件或整个服务的好方法,这也意味着你可以将更多的资源添加到一个模块,或者你可以创建模块输出,这些输出可以用作你正在开发的其他模块的输入。当创建新模块有意义时,例如在新服务中添加,或者你想要分离的某些支持功能,你可以绝对在模块中创建输出,并且它们将被存储为你的状态的一部分。如果你使用远程状态,模块输出可以非常有益,当你想在基础设施的不同组件之间分享信息,或者提供外部服务以获取信息
简单地说,如果你认为Terraform计划中的资源部分像Lego砖,你的模块将是预装的部分,这比在任何地方跟踪Lego砖要好得多,并且可能采取一个步骤。
建立基础设施环境
在大多数专业项目中,您将与三个不同的环境合作:开发,舞台制作和生产。
您的开发环境通常是本地的,并为您提供空间,在您工作时独立地进行Tinker和测试,而您的舞台和生产环境则将位于共享或公共空间中,并使用像Terraform这样的自动化过程提供。
从仔细规划的部署工作流程开始,将有助于防止头痛,其中一部分包括隔离环境。Terraform的工作空间功能使terraform.tfstate
文件因环境分开,但对描述资源的Terraform文件所做的更改并非如此。
以下是示例目录树,描述了如何使用目录设置环境隔离:
1.
2├── ansible.cfg
3├── bin/
4├── environments/
5│ ├── config/
6│ │ └── cloud-config.yaml
7│ │
8│ ├── dev/
9│ ├── prod/
10│ │ ├── config -> ../config
11│ │ ├── group_vars
12│ │ ├── host_vars
13│ │ ├── main.tf
14│ │ ├── terraform.tfvars
15│ │ ├── terraform-inventory -> ../terraform-inventory
16│ │ └── variables.tf
17│ │
18│ ├── staging/
19│ │ ├── config -> ../config
20│ │ ├── group_vars
21│ │ ├── host_vars
22│ │ ├── main.tf
23│ │ ├── terraform.tfvars
24│ │ ├── terraform-inventory -> ../terraform-inventory
25│ │ └── variables.tf
26│ │
27│ └── terraform-inventory
28│
29├── site.yml
30├── wordpress.yml
31│
32└── roles/
这种布局背后的关键逻辑是将属于相似组件的文件在不同的环境中彼此隔离。
例如,在环境
目录中,我们为我们想要的三个环境中的每一个都有一个子目录:dev
,staging
和prod
。这种隔离有助于防止在错误的地方意外运行 Ansible 或 Terraform 脚本。
有许多关于这个话题的伟大写作(https://blog.gruntwork.io/a-comprehensive-guide-to-terraform-b3d32832baca)在线,其中一本实际上变成了 Yevgeniy Brikman 的书 _Terraform: Up & Running。
用于环境的模块版本化
Terraform 模块还可以帮助您进行更改,而不会影响其他环境,例如,看看这两个模块。
一个为舞台环境(例如,‘staging/main.tf’):
1module "sippin_db" {
2 source = "github.com/cmndrsp0ck/galera-tf-mod.git?ref=v1.0.8"
3 project = "${var.project}"
4 region = "${var.region}"
5 keys = "${var.keys}"
6 private_key_path = "${var.private_key_path}"
7 ssh_fingerprint = "${var.ssh_fingerprint}"
8 public_key = "${var.public_key}"
9 ansible_user = "${var.ansible_user}"
10}
一个用于生产环境(例如, prod/main.tf
):
1module "sippin_db" {
2 source = "github.com/cmndrsp0ck/galera-tf-mod.git?ref=v1.0.6"
3 project = "${var.project}"
4 region = "${var.region}"
5 keys = "${var.keys}"
6 private_key_path = "${var.private_key_path}"
7 ssh_fingerprint = "${var.ssh_fingerprint}"
8 public_key = "${var.public_key}"
9 ansible_user = "${var.ansible_user}"
10}
它们之间的唯一区别是源
行末尾的ref
键的值,该值指定了要部署的版本。在阶段化中,它是v1.0.8
,在生产中,它是v1.0.6
。
目前,上一节中的实用设置不使用远程状态。在第6章中,我们使用远程状态后端(如Consul)进行覆盖,这在工作时至关重要。
什么是下一步?
一旦您了解如何通过模块化简化基础设施代码,以及如何隔离环境以便更安全地开发和部署,我们可以看看如何通过创建模板来提高部署速度。