作者|Sumeet Ninawe
翻译|Seal 软件
链接|https://spacelift.io/blog/terraform-environments
通常咱们应用 Terraform 将咱们的基础设施定义为代码,而后用 Terraform CLI 在咱们抉择的云平台中创立制订的基础设施组件。从外表上看,整个过程看起来仿佛不须要破费太多精力。然而当咱们深入研究将其用于实在场景时,很快就会遇到无关治理子生产和生产环境的问题。
在这篇文章中,咱们将重点关注如何应用 Terraform Workspace 和 Git 分支来无效治理多个环境。
多环境基础设施
上面列出了应用 IaC 治理多个环境的基础设施的冀望和要求:
- 能够应用雷同的 IaC 配置来治理生产和非生产环境。
- 某些非生产环境,如开发、QA、测试版或 UAT 应该与生产的雷同和放大版本并永恒存在。
- 团队成员可能创立、治理和销毁与生产雷同的长期环境。
- 所有环境并不是在同一个云帐户或订阅中创立的。
这里的关键点在于对所有环境中的基础设施应用雷同的 Terraform 配置模板。
Terraform Workspace
Terraform 提供了一个工作区性能,应用该性能能够应用雷同的配置创立和治理多个雷同的、按比例放大的环境。以这种形式创立的多个环境是齐全隔离的,不会以任何形式互相烦扰。这是咱们须要的要害性能。一起看看如何利用这个性能来满足咱们的要求。
Terraform Workspace 不同于 Terraform Cloud Workspace。在 Terraform Cloud 中,工作空间相似于一个“我的项目”,对应于 Terraform 配置存储库。除了存储和治理状态信息外,还治理变量、凭证、历史跟踪等,以反对端到端的 Terraform Cloud CI/CD 工作流。
用于解决工作区的 Terraform CLI 命令
下表示意 Terraform 工作区命令的根本用法。每个命令都遵循如下简略格局:terraform workspace <command>
上面的 CLI 输入显示了管理工作区的示例。简而言之,咱们查看以后抉择的工作空间——默认,而后创立一个名为 beta 的新工作空间,列出所有工作空间,并删除 beta 工作空间。
% terraform workspace show
default
% terraform workspace new beta
Created and switched to workspace "beta"!
You're now on a new, empty workspace. Workspaces isolate their state,
so if you run "terraform plan" Terraform will not see any existing state
for this configuration.
% terraform workspace list
default
* beta
% terraform workspace select default
Switched to workspace "default".
% terraform workspace delete beta
Releasing state lock. This may take a few moments...
Deleted workspace "beta"!
% terraform workspace list
* default
工作区插值
要应用雷同的配置管理多个按比例放大的环境,须要有一种办法让 Terraform 晓得咱们正在应用哪个工作区,这有助于正确设置配置。例如,咱们可能心愿为特定工作区治理的环境提供更多的 EC2 实例,为其余环境提供更少的实例。
Terraform 工作空间插值序列为咱们提供了一种实现这种动态变化的办法。通过拜访所选工作区的值,咱们能够应用多个结构和运算符来创立具备所需规模和其余自定义属性的环境。
思考上面的例子。在这里,Terraform 配置旨在在 AWS 中创立 EC2 实例。然而,基于所选工作区的计数属性定义了要创立的实例数。这里,“terraform.workspace”插值序列用于拜访它。
resource "aws_instance" "my_vm" {
count = terraform.workspace == "default" ? 3 : 1
ami = var.ami //Ubuntu AMI
instance_type = var.instance_type
tags = {Name = format("%s_%s_%s", var.name_tag, terraform.workspace, count.index)
}
}
如果抉择“默认”工作区,则将创立三个 EC2 实例,否则只创立一个。当然,这只是一个例子。咱们能够应用更简单的变量和运算符来治理更多的环境。
基础设施和利用程序开发
端到端产品开发波及几个方面——基础设施和要部署在基础设施上的应用程序。通常,会有对应的集体团队来负责相应的工作。在微服务中,因为依赖性和资源限度,在本地机器上测试和开发应用程序可能并不总是可行的。应用程序团队成员可能须要调整长期环境来运行他们的测试用例,甚至在将更改部署到“永恒”开发环境之前。
在这种状况下,无需放心 Terraform 源代码,因为他们能够简略地克隆存储库,而后应用工作区性能创立本人的长期环境。这种能力对于利用程序开发团队来说十分有用,能够在将更改合并到 dev 并将它们向前推动之前独自运行他们的测试用例。
帐户和凭据
多个环境通常应用多个云帐户或订阅进行治理。云平台还施行了“组织”概念,以从单个根帐户治理多个帐户。此根帐户负责所有治理流动,如计费、拜访配置等。当 Terraform 配置被“利用”时,更改将依据其提供者配置为指标帐户进行验证和执行。
provider "aws" {shared_config_files = ["/path/to/.aws/conf"]
shared_credentials_files = ["/path/to/.aws/creds"]
profile = "profile_name"
}
在这里,咱们对配置文件名称进行了硬编码,以便 Terraform 为指标帐户应用适当的凭据。在这里,咱们还能够利用工作区插值序列从共享凭证文件中动静抉择配置文件名称。
Terraform Workspace 小结
在应用 Terraform 治理多个环境时,Terraform 中的状态治理可能是一个敏感话题。不过 Terraform 提供的工作区治理能够通过在以后设置的后端中创立子目录来在后盾解决此问题。状态治理也可能是一个限度因素,因为所有状态文件都存储在同一个后端目录中。这意味着所有用于 terraform 配置的插件也会在每个工作区中被复制。
Terraform 工作区提供了一种创立瞬态环境的好办法,只需学习一些命令即可测试基础设施的变动。依附外部布线——应用插值序列。如果代码曾经构建,引入工作空间插值依赖性可能须要一些致力。
Git 分支
在本节中,咱们将摸索应用 Git 分支治理多个环境的可能性,并理解为什么它可能不是最佳策略。下图旨在满足本博文介绍中所述的要求。
开发的两个方面——基础设施和应用程序,别离以绿色和蓝色显示。此处示意的分支策略是将 Terraform 配置用于各种目标的利用。咱们将深入探讨 Git 分支的各个局部。
Git 的目标
简而言之,Git 旨在协调整个团队的开发工作。它为部署保护各种版本的源代码和包版本。主分支通常蕴含通过充沛测试的性能,实用于任何给定软件的个别用处。
执行开发流动或以谬误修复、性能或加强的模式引入任何更改——创立主分支的正本,在其上执行批改、重建、部署到子生产环境,并在合并之前进行彻底测试对次要分支的更改。
环境的 Git 分支
思考到这一点,应用 Git 分支来治理多个环境也是能够的,每个环境一个分支是十分现实的。在给定的图表中,infra-dev 团队在三个分支上工作:
- Main – 用于治理生产基础设施设置。
- QA – 用于治理 QA 基础设施设置,合格用户在其中执行 UAT 测试。
- Dev – 用于治理开发基础架构设置,其中首先公布性能并进行单元测试。
在高层次上,从主分支分出并创立雷同配置的正本以创立 QA 和开发环境是有意义的。
存在的问题
然而,当咱们将 Terraform 的更深层次视为 IaC 时,咱们须要关注一些点:
- 状态文件治理和关联的近程后端。
- 缩放转化为环境特定属性方面。
- 多个帐户的凭据。
这里思考的环境是独自的基础设施部署。这些环境都有自有的状态信息,须要对其进行近程平安治理。近程后端在 terraform 资源块中定义。
上面的示例应用 AWS S3 后端。
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.18.0"
}
}
backend "s3" {
bucket = "tf-state-bucket"
key = "terraform.tfstate"
region = "eu-central-1"
dynamodb_table = "tf_state_lock"
}
}
假如这是生产环境应用的配置,即主分支。当咱们从主分支分进去时,后端配置也会被复制。所有 Terraform CLI 命令都假设尔后端对于所有其余正本(分支)都雷同,但这是不可取的,而且可能是十分危险的。事实上,运行任何 Terraform 命令(如 plan、apply、destroy)将援用生产状态文件,甚至对生产执行操作。
如果咱们手动批改后端配置,为 QA 和开发环境应用不同的后端,那么它就违反了 Git 的初衷。Git 合并会产生抵触,并要求开发人员通过抉择后端来解决这些抵触。
这个状况也实用于.tfvars 文件中定义的特定于环境的属性值。各种环境的扩大方面是通过变量治理的——更具体地说,是 .tfvars 文件。古代 Git 工作流通常须要在任何分支上进行推送和拉取。在这种办法中可能是不可行的。
提供商配置可能蕴含多个别名以示意多个云提供商帐户和区域中的部署。这也被 Git 的长处所笼罩。
CI/CD 流水线
大多数近程 Git 存储库都提供了以 CI/CD 流水线的模式引入自动化的能力。值得注意的是 GitHub Actions 和 Gitlab CI/CD。就源代码版本控制而言,应用近程 Git 存储库并定义解决凭据的自动化流水线是有意义的。在咱们的示例中,如果咱们在特定分支上进行提交或批准拉取申请,则能够运行特定于分支的管道,该管道应用特定于环境的凭证将更改利用到正确的指标环境。
然而,即便这解决了凭据问题,特定于环境的提供程序配置和属性依然是 Git 工作流程的一部分。这与 Terraform 冀望这些配置用于咱们想要的更改形式不统一。此外,CI/CD 流水线性能是任何其余 Terraform 工作流都能够利用的性能。所以这不会减少依赖 Git 分支的任何特定劣势。
利用开发
古代利用程序开发基于微服务、容器和函数。通常,本地开发环境是开发团队遇到的一个问题,具体取决于各种因素。一个简略的例子——当运行一组相互依赖和其余因素的容器时,可能会发现开发机器上可用的资源不够用。
应用 Terraform 作为 IaC 的确有助于旋转长期和隔离的环境来为开发人员执行单元测试。还能够从所需的源分支(主分支、QA 分支或开发分支)创立一个长期 Git 分支,并创立一个隔离的放大环境——如上图中的“Temp2”部署所示。
此外,假如任何应用程序性能都依赖于仍在开发中的特定根底结构组件。在这种状况下,应用程序团队能够抉择从基础架构开发的“dev”分支分支进去,其中蕴含预期的更改。它由图中的“Temp1”部署示意。
应该留神的是,应用 Git 分支策略管理环境应用了一个总体上的假如,即领有正确的分支策略。例如,利用程序开发团队创立的分支不能合并到任何基础设施开发团队的分支中。如果 Terraform 有方法晓得以后检出哪个分支,那么采纳 Git 分支策略会更有意义。在应用 Terraform 工作空间时,工作空间插值序列提供了这个确切的性能。