如何与您的团队一起使用Terraform
作为 Write for DOnations 计划的一部分,作者选择了 Free and Open Source Fund 来接受捐赠。
介绍
当多人同时从不同位置处理同一个 Terraform 项目时,正确处理基础设施代码和项目状态以避免覆盖错误非常重要。 解决方案是远程存储状态而不是本地存储。 您团队的所有成员都可以使用远程系统,并且他们可以在工作时锁定状态。
一个这样的远程后端是 pg
,它将状态存储在 PostgreSQL 数据库中。 在本教程的过程中,您将使用 DigitalOcean 托管数据库 来确保数据可用性。
Terraform 还支持由 Hashicorp 提供的名为 Terraform Cloud 的官方托管云产品,这是一款专有应用程序,可将您团队的工作同步到一个地方,并提供用于配置和管理的用户界面。
在本教程中,您将在 Terraform Cloud 中创建一个组织,并将您的项目连接到该组织。 然后,您将使用您的组织来设置工作区和资源。 您将在托管云中存储您的状态,以便它始终可用。 您还将使用随附的托管 PostgreSQL 数据库设置 pg
后端。
先决条件
- DigitalOcean 个人访问令牌,您可以通过 DigitalOcean 控制面板创建它。 您可以在 DigitalOcean 产品文档中找到说明,如何创建个人访问令牌。
- Terraform 安装在本地计算机上。 完成 How To Use Terraform with DigitalOcean 教程的 Step 1。
- 如果您想使用
pg
后端,则需要创建并访问 Managed PostgreSQL 数据库集群。 有关详细信息,请访问 快速入门指南 。 您可以在本教程中使用单独的数据库。 - 如果您想使用 Hashicorp 的托管云,您需要一个具有 Terraform Cloud 的帐户。 您可以在他们的 注册页面 上创建一个。
注意: 我们使用 Terraform 1.1.3
专门测试了本教程。
在托管 PostgreSQL 数据库中存储状态
在本节中,您将设置一个项目,该项目使用 pg
提供程序部署 Droplet 并将状态存储在 DigitalOcean Managed PostgreSQL 数据库中。 此提供程序支持 状态锁定 ,因此状态永远不会被同时发生的两个或多个更改覆盖。
首先创建一个名为 terraform-team-pg
的目录,您将在其中存储项目:
mkdir ~/terraform-team-pg
导航到它:
cd ~/terraform-team-pg
您将首先定义提供程序,然后传入数据库和 digitalocean
模块的连接字符串。 创建并打开provider.tf
进行编辑:
nano provider.tf
添加以下行:
~/terraform-team-pg/provider.tf
terraform { required_providers { digitalocean = { source = "digitalocean/digitalocean" version = "~> 2.0" } } backend "pg" { conn_str = "your_db_connection_string" } } variable "do_token" {} provider "digitalocean" { token = var.do_token }
在这里,您需要 digitalocean
提供程序并定义 pg
后端,它接受连接字符串。 然后,定义 do_token
变量并将其传递给 digitalocean
提供程序的实例。
请记住将 your_db_connection_string
替换为 DigitalOcean 控制面板 中托管数据库的连接字符串,您可以通过按 Actions 找到它,选择 Connection Details[ X211X],然后从下拉菜单中选择 连接字符串 。 然后保存并关闭文件
警告: 要继续,请在数据库的 设置 中,确保您在允许列表中拥有运行 Terraform 的机器的 IP 地址。
通过运行初始化项目:
terraform init
输出将类似于以下内容:
OutputInitializing the backend... Successfully configured the backend "pg"! Terraform will automatically use this backend unless the backend configuration changes. Initializing provider plugins... - Finding digitalocean/digitalocean versions matching "~> 2.0"... - Installing digitalocean/digitalocean v2.16.0... - Installed digitalocean/digitalocean v2.16.0 (signed by a HashiCorp partner, key ID F82037E524B9C0E8) Partner and community providers are signed by their developers. If you'd like to know more about provider signing, you can read about it here: https://www.terraform.io/docs/cli/plugins/signing.html Terraform has created a lock file .terraform.lock.hcl to record the provider selections it made above. Include this file in your version control repository so that Terraform can guarantee to make the same selections by default when you run "terraform init" in the future. Terraform has been successfully initialized! ...
Terraform 成功初始化了后端,这意味着它已连接到数据库。
接下来,在名为 droplets.tf
的文件中定义 Droplet。 通过运行创建并打开它进行编辑:
nano droplets.tf
添加以下行:
~/terraform-team-pg/droplets.tf
resource "digitalocean_droplet" "web" { image = "ubuntu-20-04-x64" name = "web-1" region = "fra1" size = "s-1vcpu-1gb" }
此代码将在 fra1
区域部署一个名为 web-1
的 Droplet,在 1GB RAM 和一个 CPU 内核上运行 Ubuntu 20.04。 这就是您需要定义的所有内容,因此请保存并关闭文件。
您需要在环境变量中使用 DigitalOcean 令牌。 创建一个,将 your_do_token
替换为您的令牌:
export DO_PAT="your_do_token"
要检查与数据库的连接是否正常,请尝试规划配置:
terraform plan -var "do_token=${DO_PAT}"
输出将类似于以下内容:
OutputTerraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # digitalocean_droplet.web will be created + resource "digitalocean_droplet" "web" { + backups = false + created_at = (known after apply) + disk = (known after apply) + graceful_shutdown = false + id = (known after apply) + image = "ubuntu-20-04-x64" + ipv4_address = (known after apply) + ipv4_address_private = (known after apply) + ipv6 = false + ipv6_address = (known after apply) + locked = (known after apply) + memory = (known after apply) + monitoring = false + name = "web-1" + price_hourly = (known after apply) + price_monthly = (known after apply) + private_networking = (known after apply) + region = "fra1" + resize_disk = true + size = "s-1vcpu-1gb" + status = (known after apply) + urn = (known after apply) + vcpus = (known after apply) + volume_ids = (known after apply) + vpc_uuid = (known after apply) } Plan: 1 to add, 0 to change, 0 to destroy. ...
Terraform 没有报告任何错误,并像往常一样计划了行动。 它成功连接到您的 PostgreSQL 数据库并存储了它的状态。 现在,多个人可以同时处理此项目,而项目保持同步。
在 Terraform Cloud 中存储状态
在此步骤中,您将创建一个部署 Droplet 的项目,并使用 Terraform Cloud 作为其后端,并使用 cloud
提供程序。 这需要在 Terraform Cloud 中创建组织和 工作区 ,编写基础架构代码并进行规划。
创建组织
Terraform Cloud 允许您拥有多个 组织,其中包含您的工作区和模块。 付费计划组织可以拥有多个具有访问级别控制功能的团队,而您将使用的免费计划仅为每个组织提供一个团队。 您可以邀请团队成员加入组织。
首先前往 Terraform Cloud 并登录。 如果您尚未创建组织,它会提示您创建。
输入您选择的组织名称,并记住它在 Terraform Cloud 中的所有名称中必须是唯一的。 如果名称已存在,您将收到错误消息。 电子邮件地址应该已经填写了您的帐户地址。 完成后,单击 创建组织 按钮继续。
然后它会要求您选择工作区的类型。
由于您将使用命令行与 Terraform Cloud 交互,因此单击 CLI-driven workflow 选项。 然后,输入工作空间的名称并将描述留空。
输入您选择的工作区名称(我们将其称为 sammy
),然后单击 创建工作区 以完成组织创建过程。 然后它将引导您进入工作区设置页面。
您现在已经创建了您的工作区,它是您组织的一部分。 由于您刚刚创建它,因此您的工作区不包含基础架构代码。 在界面的中心部分,Terraform Cloud 为您提供连接到此工作区的启动说明。
在连接到它之前,您需要配置云将用于执行命令的 Terraform 版本。 要设置它,请单击 Overview 旁边的 Settings 下拉菜单,然后从列表中选择 General。 当页面打开时,导航到 Terraform 版本 下拉菜单并选择 1.1.3
(对于本教程)。
然后,单击保存设置按钮保存更改。
要将您的项目连接到您的组织和工作区,您首先需要使用命令行登录。 在运行命令之前,导航到 令牌页面 为您的服务器创建一个新的访问令牌,这将提供对您帐户的访问权限。 您将收到创建 API 令牌的提示。
默认描述是好的,所以点击创建API令牌创建它。
单击令牌值或其后面的图标以复制 API 令牌。 您将使用此令牌将您的项目连接到您的 Terraform Cloud 帐户。
在命令行中,运行以下命令登录:
terraform login
您将收到以下输出:
OutputTerraform will request an API token for app.terraform.io using your browser. If login is successful, Terraform will store the token in plain text in the following file for use by subsequent commands: /home/sammy/.terraform.d/credentials.tfrc.json Do you want to proceed? Only 'yes' will be accepted to confirm. ...
Terraform 警告您令牌将存储在本地。 提示时输入yes
:
Output--------------------------------------------------------------------------------- Open the following URL to access the tokens page for app.terraform.io: https://app.terraform.io/app/settings/tokens?source=terraform-login --------------------------------------------------------------------------------- Generate a token using your browser, and copy-paste it into this prompt. Terraform will store the token in plain text in the following file for use by subsequent commands: /home/sammy/.terraform.d/credentials.tfrc.json Token for app.terraform.io: Enter a value:
粘贴您复制的令牌并使用 ENTER
确认。 Terraform 将显示一条成功消息:
Output... - ----- - --------- -- --------- - ----- --------- ------ ------- ------- --------- ---------- ---- ---------- ---------- -- ---------- ---------- Welcome to Terraform Cloud! - ---------- ------- --- ----- --- Documentation: terraform.io/docs/cloud -------- - ---------- ---------- --------- ----- - New to TFC? Follow these steps to instantly apply an example configuration: $ git clone https://github.com/hashicorp/tfc-getting-started.git $ cd tfc-getting-started $ scripts/setup.sh
您已配置本地 Terraform 安装以访问您的 Terraform Cloud 帐户。 您现在将创建一个部署 Droplet 的项目,并将其配置为使用 Terraform Cloud 来存储其状态。
设置项目
首先,创建一个名为 terraform-team-cloud
的目录,您将在其中存储项目:
mkdir ~/terraform-team-cloud
导航到它:
cd ~/terraform-team-cloud
要设置您的项目,您需要:
- 定义和配置与 Terraform Cloud 接口的
cloud
提供程序。 - 要求
digitalocean
提供者能够部署 DigitalOcean 资源。 - 定义和初始化您将使用的变量。
您将把提供者和模块需求规范存储在一个名为 provider.tf
的文件中。 通过运行创建并打开它进行编辑:
nano provider.tf
添加以下行:
~/terraform-team-cloud/provider.tf
terraform { required_providers { digitalocean = { source = "digitalocean/digitalocean" version = "~> 2.0" } } cloud { organization = "your_organization_name" workspaces { name = "your_workspace_name" } } } variable "do_token" {} provider "digitalocean" { token = var.do_token }
在这里,您首先指定您的 Terraform 版本。 然后,根据需要指定 digitalocean
提供程序并将后端设置为 cloud
。 对于 organization
和 workspaces.name
,将突出显示的值替换为您指定的名称。
接下来,定义一个名为 do_token
的变量,将其传递给在它之后创建的 digitalocean
提供程序。 您现在已将项目配置为连接到您的组织,因此请保存并关闭文件。
使用以下命令初始化您的项目:
terraform init
输出将与此类似:
OutputInitializing Terraform Cloud... Initializing provider plugins... - Finding digitalocean/digitalocean versions matching "~> 2.0"... - Installing digitalocean/digitalocean v2.18.0... - Installed digitalocean/digitalocean v2.18.0 (signed by a HashiCorp partner, key ID F82037E524B9C0E8) Partner and community providers are signed by their developers. If you'd like to know more about provider signing, you can read about it here: https://www.terraform.io/docs/cli/plugins/signing.html Terraform has created a lock file .terraform.lock.hcl to record the provider selections it made above. Include this file in your version control repository so that Terraform can guarantee to make the same selections by default when you run "terraform init" in the future. Terraform Cloud has been successfully initialized! ...
由于 Droplet 定义与上一个项目中的相同,您可以通过运行将其复制过来:
cp ../terraform-team-pg/droplets.tf .
最后,您将定义变量值。 cloud
提供程序不支持通过命令行将值传递给变量,因此您必须使用变量文件传递它们或在 Terraform Cloud 中设置它们。 Terraform 从文件名以 .auto.tfvars
结尾的文件中读取变量值。 创建并打开一个名为 vars.auto.tfvars
的文件进行编辑,您将在其中定义 do_token
变量:
nano vars.auto.tfvars
添加以下行,将 your_do_token
替换为您的 DigitalOcean API 令牌:
vars.auto.tfvars
do_token = "your_do_token"
完成后,保存并关闭文件。 Terraform 将在计划操作时自动读取此文件。
您的项目现已完成并设置为使用 Terraform Cloud 作为其后端。 您现在将计划和应用 Droplet 并查看它在 Cloud 应用程序中的反映方式。
应用配置
在本教程的 Step 1 中,您使用 terraform plan
命令规划了一个项目。 由于 Terraform Cloud 项目定义了相同的资源,因此您可以跳过再次计划并将其直接应用到 Terraform Cloud。
您可以通过运行以下命令来应用项目来更新它:
terraform apply
您会注意到输出不同于使用 local
作为后端时的输出:
OutputRunning apply in Terraform Cloud. Output will stream here. Pressing Ctrl-C will cancel the remote apply if it's still pending. If the apply started it will stop streaming the logs, but will not stop the apply running remotely. Preparing the remote apply... To view this run in a browser, visit: https://app.terraform.io/app/sammy-shark/sammy/runs/run-euVu9t1yUtuq5sy9 Waiting for the plan to start... Terraform v1.1.3 on linux_amd64 Configuring remote state backend... Initializing Terraform configuration... Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # digitalocean_droplet.web will be created + resource "digitalocean_droplet" "web" { + backups = false + created_at = (known after apply) + disk = (known after apply) + graceful_shutdown = false + id = (known after apply) + image = "ubuntu-20-04-x64" + ipv4_address = (known after apply) + ipv4_address_private = (known after apply) + ipv6 = false + ipv6_address = (known after apply) + locked = (known after apply) + memory = (known after apply) + monitoring = false + name = "web-1" + price_hourly = (known after apply) + price_monthly = (known after apply) + private_networking = (known after apply) + region = "fra1" + resize_disk = true + size = "s-1vcpu-1gb" + status = (known after apply) + urn = (known after apply) + vcpus = (known after apply) + volume_ids = (known after apply) + vpc_uuid = (known after apply) } Plan: 1 to add, 0 to change, 0 to destroy. ...
使用 cloud
后端时,Terraform 不会从本地计算机规划或应用配置。 相反,它将这些任务委托给 Terraform Cloud,并且只将输出实时流式传输到控制台。
出现提示时输入 yes
。 Terraform 将很快完成应用配置,您可以导航到 Terraform Cloud 网站上的工作区,发现它已应用新操作。
您现在可以通过运行以下命令来销毁已部署的资源:
terraform destroy
在本部分中,您已将项目连接到 Terraform Cloud,使您的团队可以在一个中心位置访问您的项目状态。 这允许每个有权访问项目的人共享和同步状态,从而获得更流畅的体验。
结论
在本教程中,您使用了两种不同的后端: Terraform Cloud,它是 Hashicorp 为 Terraform 提供的托管云产品; 和 pg
,它允许您将项目的状态存储在 PostgreSQL 数据库中。 您使用了来自 DigitalOcean 的托管 PostgreSQL 数据库,您可以在几分钟内配置和使用 Terraform。
更多关于 Terraform Cloud 功能的信息,请访问【X70X】官方文档【X87X】。
本教程是 How To Manage Infrastructure with Terraform 系列的一部分。 该系列涵盖了许多 Terraform 主题,从首次安装 Terraform 到管理复杂的项目。