如何与团队一起使用Terraform

作者选择了自由开源基金作为为捐赠而写计划的一部分来接受捐赠。

介绍

当多人同时从不同地点处理同一Terraform项目时,正确处理基础设施代码和项目状态以避免覆盖错误非常重要。解决方案是远程存储状态而不是本地存储。一个远程系统可供团队中的所有成员使用,并且他们可以在工作时锁定状态。

其中一种远程后端是pg,它将状态存储在PostgreSQL数据库中。在本教程中,您将使用它与DigitalOcean托管数据库一起,以确保数据可用性。

Terraform还支持Hashicorp提供的官方托管云服务,称为Terraform云,这是一个专有应用程序,将您团队的工作同步到一个地方,并提供配置和管理的用户界面。

在本教程中,您将在 Terraform Cloud 中创建一个组织,并将您的项目连接到该组织。然后,您将使用您的组织来设置工作区和资源。您将在托管云中存储您的状态,以便随时可用。您还将使用附带的托管 PostgreSQL 数据库设置 pg 后端。

先决条件

  • A DigitalOcean Personal Access Token, which you can create via the DigitalOcean Control Panel. You can find instructions in the DigitalOcean product documents, How to Create a Personal Access Token.
  • 您的本地机器上已安装了 Terraform。完成了 如何使用 Terraform 与 DigitalOcean 教程的 第 1 步
  • 如果您想要使用 pg 后端,您需要创建一个可访问的 托管 PostgreSQL 数据库集群。欲了解更多信息,请访问 快速入门指南。您可以为本教程使用单独的数据库。
  • 如果您想要使用 Hashicorp 的托管云,您需要一个带有 Terraform Cloud 账户。您可以在他们的 注册页面 上创建一个账户。

注意: 我们特意使用 Terraform 1.1.3 对本教程进行了测试。

在托管的PostgreSQL数据库中存储状态

在这一部分,您将设置一个项目,部署一个Droplet,并使用pg提供程序将状态存储在DigitalOcean托管的PostgreSQL数据库中。该提供程序支持状态锁定,因此状态永远不会被同时发生的两个或更多变化覆盖。

首先创建一个名为terraform-team-pg的目录,您将在其中存储项目:

  1. mkdir ~/terraform-team-pg

导航到该目录:

  1. cd ~/terraform-team-pg

您首先定义提供程序,然后传入数据库的连接字符串和digitalocean模块。创建并打开provider.tf以进行编辑:

  1. 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 控制面板中找到的托管数据库连接字符串,方法是按操作,选择连接详细信息,然后从下拉菜单中选择连接字符串。然后保存并关闭文件

警告:要继续,在您的数据库设置中,请确保将正在运行 Terraform 的机器的 IP 地址添加到允许列表中。

通过运行以下命令初始化项目:

  1. terraform init

输出将类似于以下内容:

Output
Initializing 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。通过运行以下命令创建并打开它进行编辑:

  1. 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,运行 Ubuntu 20.04,配置为 1GB RAM 和一个 CPU 核心。这就是您需要定义的所有内容,因此请保存并关闭文件。

您需要将您的 DigitalOcean 令牌放入一个环境变量中。创建一个,将your_do_token替换为您的令牌:

  1. export DO_PAT="your_do_token"

为了检查与数据库的连接是否正常工作,请尝试规划配置:

  1. terraform plan -var "do_token=${DO_PAT}"

输出将类似于以下内容:

Output
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 将被创建 + 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驱动的工作流程选项。然后,输入工作区名称并将描述留空。

输入您选择的工作区名称(我们将其称为sammy),然后单击创建工作区以完成组织创建过程。然后系统将引导您到工作区设置页面。

您现在已创建了工作区,它是您组织的一部分。由于您刚刚创建了它,因此您的工作区不包含任何基础架构代码。在界面的中心部分,Terraform Cloud为您提供了连接到此工作区的起始说明。

在连接到它之前,您需要配置云将用于执行命令的Terraform的版本。要设置它,请单击概述旁边的设置下拉菜单,然后从列表中选择常规。页面打开后,转到Terraform版本下拉菜单,并选择1.1.3(本教程使用的版本)。

然后,点击保存设置按钮以保存更改。

要将您的项目连接到您的组织和工作空间,您首先需要使用命令行登录。在运行命令之前,请导航到令牌页面以为您的服务器创建一个新的访问令牌,该令牌将提供对您账户的访问权限。您将收到一个提示来创建一个 API 令牌。

默认描述是可以的,所以点击创建 API 令牌来创建它。

点击令牌值,或者在其后的图标,以复制 API 令牌。您将使用此令牌将您的项目连接到 Terraform Cloud 账户。

在命令行中,运行以下命令以登录:

  1. terraform login

您将收到以下输出:

Output
Terraform 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的目录:

  1. mkdir ~/terraform-team-cloud

进入该目录:

  1. cd ~/terraform-team-cloud

为了设置您的项目,您需要:

  • 定义和配置与Terraform Cloud交互的cloud提供程序。
  • 要能够部署DigitalOcean资源,需要引入digitalocean提供程序。
  • 定义并初始化您将使用的变量。

您将在名为provider.tf的文件中存储提供程序和模块要求的规范。通过运行以下命令创建并打开它进行编辑:

  1. 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。对于organizationworkspaces.name,请用您指定的名称替换高亮显示的值。

接下来,定义一个名为do_token的变量,并将其传递给创建后的digitalocean提供程序。您现在已配置好连接到您的组织的项目,因此保存并关闭该文件。

使用以下命令初始化您的项目:

  1. terraform init

输出将类似于此:

Output
Initializing 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定义与之前的项目相同,您可以通过运行以下命令将其复制过来:

  1. cp ../terraform-team-pg/droplets.tf .

最后,您将定义变量值。 cloud 提供商不支持通过命令行传递变量值,因此您必须使用变量文件或在 Terraform Cloud 中设置它们。Terraform 从以 .auto.tfvars 结尾的文件中读取变量值。创建并打开一个名为 vars.auto.tfvars 的文件进行编辑,在其中您将定义 do_token 变量:

  1. nano vars.auto.tfvars

添加以下行,将 your_do_token 替换为您的 DigitalOcean API 令牌:

vars.auto.tfvars
do_token = "your_do_token"

完成后,保存并关闭文件。Terraform 在规划操作时会自动读取此文件。

您的项目现在已经完成,并设置为使用 Terraform Cloud 作为其后端。现在,您将计划并应用 Droplet,并查看其在 Cloud 应用程序中的反映。

应用配置

在本教程的步骤 1中,您使用 terraform plan 命令规划了一个项目。由于 Terraform Cloud 项目已定义了相同的资源,因此您可以跳过再次规划它,直接将其应用于 Terraform Cloud。

通过运行以下命令来应用该项目以进行更新:

  1. terraform apply

您会注意到,当您将local作为后端时,输出与使用

Output
Running 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将被创建 + 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网站上的工作区,发现它已经应用了一个新的操作。

您现在可以通过运行以下命令销毁已部署的资源:

  1. terraform destroy

在本节中,您已将项目连接到了Terraform Cloud,使项目的状态可以在一个中心位置对团队可访问。这允许状态被分享和同步,适用于所有有权访问项目的人,从而带来更顺畅的体验。

结论

在本教程中,您使用了两种不同的后端:Terraform Cloud,这是Hashicorp为Terraform提供的托管云服务;以及pg,它允许您将项目状态存储在PostgreSQL数据库中。您使用了来自DigitalOcean的托管PostgreSQL数据库,您可以在几分钟内使用Terraform进行设置和使用。

要了解更多有关 Terraform Cloud 功能的信息,请访问官方文档

本教程是使用 Terraform 管理基础设施的方法系列的一部分。该系列涵盖了许多 Terraform 主题,从首次安装 Terraform 到管理复杂项目。

Source:
https://www.digitalocean.com/community/tutorials/how-to-use-terraform-within-your-team