如何将Terraform与DigitalOcean一起使用

来自菜鸟教程
跳转至:导航、​搜索

介绍

Terraform 是一种以有组织的方式构建和管理基础设施的工具。 除了其他提供商提供的大量服务外,您还可以使用它来管理 DigitalOcean Droplets、负载均衡器甚至 DNS 条目。 Terraform 使用命令行界面,可以从您的桌面或远程服务器运行。

Terraform 通过读取描述构成应用程序环境或数据中心的组件的配置文件来工作。 根据配置,它生成一个执行计划,描述它将做什么来达到所需的状态。 然后,您使用 Terraform 执行此计划以构建基础架构。 当配置发生更改时,Terraform 可以生成并执行增量计划,以将现有基础架构更新到新描述的状态。

在本教程中,您将安装 Terraform 并使用它在 DigitalOcean 上创建一个基础架构,该基础架构由两个 Nginx 服务器组成,这些服务器由 DigitalOcean 负载均衡器 进行负载均衡。 然后,您将使用 Terraform 在 DigitalOcean 上添加一个指向您的负载均衡器的 DNS 条目。 这将帮助您开始使用 Terraform,并让您了解如何使用它来管理和部署满足您自己需求的基于 DigitalOcean 的基础架构。

注意: 本教程已使用 Terraform 1.1.3 进行测试。


先决条件

要完成本教程,您需要:

  • 一个 DigitalOcean 帐户。 如果您没有,注册一个新帐户
  • DigitalOcean 个人访问令牌,您可以通过 DigitalOcean 控制面板创建它。 可以在以下位置找到相关说明:如何创建个人访问令牌
  • 添加到您的 DigitalOcean 帐户的无密码 SSH 密钥,您可以按照 How To Use SSH Keys with DigitalOcean Droplets 创建该密钥。 当您将密钥添加到您的帐户时,请记住您给它的名称,因为您将在本教程中使用它。 (要让 Terraform 接受您的密钥名称,它必须以字母或下划线开头,并且只能包含字母、数字、下划线和破折号。)
  • 个人域指向 DigitalOcean 的名称服务器,您可以按照教程 如何从公共域注册商 指向 DigitalOcean 名称服务器。

第 1 步 — 安装 Terraform

Terraform 是您在桌面或远程服务器上运行的命令行工具。 要安装它,您将下载它并将其放在您的 PATH 上,这样您就可以在您正在工作的任何目录中执行它。

首先,从官方下载页面下载适合你的操作系统和架构的包。 如果您使用的是 macOS 或 Linux,则可以使用 curl 下载 Terraform。

在 macOS 上,使用此命令下载 Terraform 并将其放在您的主目录中:

curl -o ~/terraform.zip https://releases.hashicorp.com/terraform/1.1.3/terraform_1.1.3_darwin_amd64.zip 

在 Linux 上,使用以下命令:

curl -o ~/terraform.zip https://releases.hashicorp.com/terraform/1.1.3/terraform_1.1.3_linux_amd64.zip 

创建~/opt/terraform目录:

mkdir -p ~/opt/terraform

然后,使用 unzip 命令将 Terraform 解压缩到 ~/opt/terraform。 在 Ubuntu 上,您可以使用 apt 安装 unzip

sudo apt install unzip

使用它将下载的存档解压缩到 ~/opt/terraform 目录,方法是运行:

unzip ~/terraform.zip -d ~/opt/terraform

最后,将 ~/opt/terraform 添加到您的 PATH 环境变量中,这样您就可以在不指定可执行文件的完整路径的情况下执行 terraform 命令。

在 Linux 上,您需要在 .bashrc 中重新定义 PATH,它会在新 shell 打开时运行。 通过运行打开它进行编辑:

nano ~/.bashrc

注意:在 macOS 上,如果使用 Bash,则将路径添加到文件 .bash_profile,如果使用 ZSH,则添加到文件 .zshrc


要将 Terraform 的路径附加到 PATH,请在文件末尾添加以下行:

.bashrc

export PATH=$PATH:~/opt/terraform

完成后保存并关闭文件。

现在,您所有的新 shell 会话都将能够找到 terraform 命令。 要将新的 PATH 加载到当前会话中,如果您在 Linux 系统上使用 Bash,请运行以下命令:

. ~/.bashrc

如果您在 macOS 上使用 Bash,请改为执行以下命令:

. .bash_profile

如果您使用的是 ZSH,请运行以下命令:

. .zshrc

要验证您是否已正确安装 Terraform,请运行不带参数的 terraform 命令:

terraform

您将看到类似于以下内容的输出:

OutputUsage: terraform [global options] <subcommand> [args]

The available commands for execution are listed below.
The primary workflow commands are given first, followed by
less common or more advanced commands.

Main commands:
  init          Prepare your working directory for other commands
  validate      Check whether the configuration is valid
  plan          Show changes required by the current configuration
  apply         Create or update infrastructure
  destroy       Destroy previously-created infrastructure

All other commands:
  console       Try Terraform expressions at an interactive command prompt
  fmt           Reformat your configuration in the standard style
  force-unlock  Release a stuck lock on the current workspace
  get           Install or upgrade remote Terraform modules
  graph         Generate a Graphviz graph of the steps in an operation
  import        Associate existing infrastructure with a Terraform resource
  login         Obtain and save credentials for a remote host
  logout        Remove locally-stored credentials for a remote host
  output        Show output values from your root module
  providers     Show the providers required for this configuration
  refresh       Update the state to match remote systems
  show          Show the current state or a saved plan
  state         Advanced state management
  taint         Mark a resource instance as not fully functional
  test          Experimental support for module integration testing
  untaint       Remove the 'tainted' state from a resource instance
  version       Show the current Terraform version
  workspace     Workspace management

Global options (use these before the subcommand, if any):
  -chdir=DIR    Switch to a different working directory before executing the
                given subcommand.
  -help         Show this help output, or the help for a specified subcommand.
  -version      An alias for the "version" subcommand.

这些是 Terraform 接受的命令。 输出为您提供了简要说明,您将在本教程中了解有关它们的更多信息。

现在安装了 Terraform,让我们配置它以使用 DigitalOcean 的资源。

第 2 步 — 为 DigitalOcean 配置 Terraform

Terraform 支持多种服务提供者,通过 providers 可以安装。 每个提供商都有自己的规范,这些规范通常映射到其各自服务提供商的 API。

DigitalOcean 提供者 让 Terraform 与 DigitalOcean API 交互以构建基础设施。 此提供程序支持创建各种 DigitalOcean 资源,包括以下内容:

  • digitalocean_droplet:Droplet(服务器)
  • digitalocean_loadbalancer:负载均衡器
  • digitalocean_domain:DNS 域条目
  • digitalocean_record:DNS 记录

Terraform 将使用您的 DigitalOcean 个人访问令牌与 DigitalOcean API 通信并管理您帐户中的资源。 不要与他人共享此密钥,并将其置于脚本和版本控制之外。 通过运行将您的 DigitalOcean 个人访问令牌导出到名为 DO_PAT 的环境变量:

export DO_PAT="your_personal_access_token"

这将使在后续命令中更容易使用它,并将其与您的代码分开。

注意:如果您将经常使用 Terraform 和 DigitalOcean,请使用与上一步中修改 PATH 环境变量相同的方法将此行添加到您的 shell 配置文件中。


通过运行以下命令创建一个目录来存储您的基础架构配置:

mkdir ~/loadbalance

导航到新创建的目录:

cd ~/loadbalance

Terraform 配置是以 .tf 文件扩展名结尾的文本文件。 它们是人类可读的,并且支持评论。 (Terraform 也支持 JSON 格式的配置文件,但这里不做介绍。) Terraform 将以声明的方式读取您工作目录中的所有配置文件,因此资源和变量定义的顺序无关紧要。 您的整个基础架构可以存在于单个配置文件中,但您应该按资源类型分隔配置文件以保持清晰。

使用 Terraform 构建基础架构的第一步是定义您要使用的提供程序。

要将 DigitalOcean 提供程序与 Terraform 一起使用,您必须告知 Terraform 并使用正确的凭据变量配置插件。 创建一个名为 provider.tf 的文件,它将存储提供程序的配置:

nano provider.tf

将以下行添加到文件中以告诉 Terraform 您要使用 DigitalOcean 提供程序,并指示 Terraform 在哪里可以找到它:

~/loadbalance/provider.tf

terraform {
  required_providers {
    digitalocean = {
      source = "digitalocean/digitalocean"
      version = "~> 2.0"
    }
  }
}

然后,在文件中定义以下变量,以便您可以在其余配置文件中引用它们:

  • do_token:您的 DigitalOcean 个人访问令牌。
  • pvt_key:私钥位置,因此 Terraform 可以使用它来登录新的 Droplets 并安装 Nginx。

您将在运行时将这些变量的值传递到 Terraform,而不是在此处硬编码这些值。 这使得配置更便携。

要定义这些变量,请将这些行添加到文件中:

~/loadbalance/provider.tf

...
variable "do_token" {}
variable "pvt_key" {}

然后,添加这些行以配置 DigitalOcean 提供程序,并通过将 do_token 分配给提供程序的 token 参数来指定您的 DigitalOcean 帐户的凭据:

~/loadbalance/provider.tf

...
provider "digitalocean" {
  token = var.do_token
}

最后,您需要让 Terraform 自动将您的 SSH 密钥添加到您创建的任何新 Droplet。 当您将 SSH 密钥添加到 DigitalOcean 时,您给它起了一个名字。 Terraform 可以使用此名称来检索公钥。 添加这些行,将 terraform 替换为您在 DigitalOcean 帐户中提供的密钥名称:

~/loadbalance/provider.tf

...
data "digitalocean_ssh_key" "terraform" {
  name = "terraform"
}

您完成的 provider.tf 文件将如下所示:

~/loadbalance/provider.tf

terraform {
  required_providers {
    digitalocean = {
      source = "digitalocean/digitalocean"
      version = "~> 2.0"
    }
  }
}

variable "do_token" {}
variable "pvt_key" {}

provider "digitalocean" {
  token = var.do_token
}

data "digitalocean_ssh_key" "terraform" {
  name = "terraform"
}

完成后,保存并关闭文件。

注意:将 TF_LOG 环境变量设置为 1 将启用 Terraform 尝试执行的详细日志记录。 您可以通过运行来设置它:

export TF_LOG=1

通过运行以下命令为您的项目初始化 Terraform:

terraform init

这将读取您的配置并为您的提供商安装插件。 您将在输出中看到记录:

OutputInitializing the backend...

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!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

如果您碰巧卡住了,并且 Terraform 没有按预期工作,您可以通过删除 terraform.tfstate 文件并手动销毁创建的资源(例如,通过控制面板)重新开始。

现在已配置 Terraform,可以连接到您的 DigitalOcean 帐户。 在下一步中,您将使用 Terraform 定义将运行 Nginx 服务器的 Droplet。

第三步——定义第一个 Nginx 服务器

您可以使用 Terraform 创建一个 DigitalOcean Droplet 并在 Droplet 启动后安装软件。 在此步骤中,您将配置一个 Ubuntu 20.04 Droplet 并使用 Terraform 安装 Nginx Web 服务器。

创建一个名为 www-1.tf 的新 Terraform 配置文件,它将保存 Droplet 的配置:

nano www-1.tf

插入以下行来定义 Droplet 资源:

~/loadbalance/www-1.tf

resource "digitalocean_droplet" "www-1" {
    image = "ubuntu-20-04-x64"
    name = "www-1"
    region = "nyc3"
    size = "s-1vcpu-1gb"
    ssh_keys = [
      data.digitalocean_ssh_key.terraform.id
    ]

在上述配置中,第一行定义了一个名为 www-1digitalocean_droplet 资源。 其余的行指定了 Droplet 的属性,包括它将驻留的数据中心以及标识要配置的 Droplet 大小的 slug。 在这种情况下,您使用的是 s-1vcpu-1gb,它将创建一个具有一个 CPU 和 1GB RAM 的 Droplet。 (访问 this size slug chart 查看您可以使用的可用 slug。)

ssh_keys 部分指定要添加到 Droplet 的公钥列表。 在这种情况下,您要指定在 provider.tf 中定义的键。 确保此处的名称与您在 provider.tf 中指定的名称匹配。

当您针对 DigitalOcean API 运行 Terraform 时,它将收集有关 Droplet 的各种信息,例如其公共和私有 IP 地址。 此信息可供配置中的其他资源使用。

如果您想知道 Droplet 资源需要或可选哪些参数,请参阅 Terraform 官方文档:DigitalOcean Droplet Specification

要设置 Terraform 可用于通过 SSH 连接到服务器的 connection,请在文件末尾添加以下行:

~/loadbalance/www-1.tf

...
connection {
    host = self.ipv4_address
    user = "root"
    type = "ssh"
    private_key = file(var.pvt_key)
    timeout = "2m"
  }

这些行描述了 Terraform 应该如何连接到服务器,因此 Terraform 可以通过 SSH 连接以安装 Nginx。 请注意私有密钥变量 var.pvt_key 的使用——您将在运行 Terraform 时传递它的值。

现在您已经建立了连接,配置 remote-exec 供应商,您将使用它来安装 Nginx。 将以下行添加到配置中以执行此操作:

~/loadbalance/www-1.tf

...
provisioner "remote-exec" {
    inline = [
      "export PATH=$PATH:/usr/bin",
      # install nginx
      "sudo apt update",
      "sudo apt install -y nginx"
    ]
  }
}

请注意,inline 数组中的字符串是 root 用户将运行以安装 Nginx 的命令。

完成的文件如下所示:

~/loadbalance/www-1.tf

resource "digitalocean_droplet" "www-1" {
  image = "ubuntu-20-04-x64"
  name = "www-1"
  region = "nyc3"
  size = "s-1vcpu-1gb"
  ssh_keys = [
    data.digitalocean_ssh_key.terraform.id
  ]
  
  connection {
    host = self.ipv4_address
    user = "root"
    type = "ssh"
    private_key = file(var.pvt_key)
    timeout = "2m"
  }
  
  provisioner "remote-exec" {
    inline = [
      "export PATH=$PATH:/usr/bin",
      # install nginx
      "sudo apt update",
      "sudo apt install -y nginx"
    ]
  }
}

保存文件并退出编辑器。 您已经定义了服务器,并准备好部署它,现在您将执行此操作。

第 4 步 — 使用 Terraform 创建 Nginx 服务器

您当前的 Terraform 配置描述了单个 Nginx 服务器。 您现在将完全按照定义部署 Droplet。

运行 terraform plan 命令以查看 执行计划 ,或者 Terraform 将尝试做什么来构建您描述的基础设施。 您必须指定 DigitalOcean 访问令牌的值和私钥的路径,因为您的配置使用此信息来访问您的 Droplet 以安装 Nginx。 运行以下命令以创建计划:

terraform plan \
  -var "do_token=${DO_PAT}" \
  -var "pvt_key=$HOME/.ssh/id_rsa" 

Warningterraform plan命令支持-out参数保存计划。 但是,该计划将存储 API 密钥,并且 Terraform 不会加密此数据。 使用此选项时,如果您打算将此文件发送给其他人或长时间保持静止,则应探索加密此文件。


您将看到与此类似的输出:

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.www-1 will be created
  + resource "digitalocean_droplet" "www-1" {
      + 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                 = "www-1"
      + price_hourly         = (known after apply)
      + price_monthly        = (known after apply)
      + private_networking   = (known after apply)
      + region               = "nyc3"
      + resize_disk          = true
      + size                 = "s-1vcpu-1gb"
      + ssh_keys             = [
          + "...",
        ]
      + 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.

───────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

+ resource "digitalocean_droplet" "www-1" 行意味着 Terraform 将创建一个名为 www-1 的新 Droplet 资源,详细信息如下。 这正是应该发生的事情,所以运行 terraform apply 命令来执行当前计划:

terraform apply \
  -var "do_token=${DO_PAT}" \
  -var "pvt_key=$HOME/.ssh/id_rsa"

您将获得与以前相同的输出,但是这一次,Terraform 会询问您是否要继续:

Output...
Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

输入 yes 并按 ENTER。 Terraform 将配置您的 Droplet:

Outputdigitalocean_droplet.www-1: Creating...

一段时间后,您会看到 Terraform 使用 remote-exec 配置器安装 Nginx,然后该过程将完成:

Output
digitalocean_droplet.www-1: Provisioning with 'remote-exec'...

....

digitalocean_droplet.www-1: Creation complete after 1m54s [id=your_www-1_droplet_id]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
...

Terraform 创建了一个名为 www-1 的新 Droplet,并在其上安装了 Nginx。 如果您访问新 Droplet 的公共 IP 地址,您将看到 Nginx 欢迎屏幕。 创建 Droplet 时会显示公共 IP,但您始终可以通过查看 Terraform 的当前状态来查看它。 Terraform 每次执行计划或刷新其状态时都会更新状态文件 terraform.tfstate

要查看环境的当前状态,请使用以下命令:

terraform show terraform.tfstate

这将显示您的 Droplet 的公共 IP 地址。

Outputresource "digitalocean_droplet" "www-1" {
    backups              = false
    created_at           = "..."
    disk                 = 25
    id                   = "your_www-1_droplet_id"
    image                = "ubuntu-20-04-x64"
    ipv4_address         = "your_www-1_server_ip"
    ipv4_address_private = "10.128.0.2"
    ...

在浏览器中导航到 http://your_www-1_server_ip 以验证 Nginx 服务器是否正在运行。

注意:如果你在 Terraform 之外修改你的基础设施,你的状态文件将会过期。 如果您的资源在 Terraform 之外进行了修改,则需要刷新状态文件以使其保持最新状态。 此命令将从您的提供者那里提取更新的资源信息:

terraform refresh \
  -var "do_token=${DO_PAT}" \
  -var "pvt_key=$HOME/.ssh/id_rsa"

在此步骤中,您已部署在 Terraform 中描述的 Droplet。 您现在将创建第二个。

第 5 步 — 创建第二个 Nginx 服务器

现在您已经描述了 Nginx 服务器,您可以通过复制现有服务器的配置文件并替换 Droplet 资源的名称和主机名来快速添加第二个服务器。

您可以手动执行此操作,但使用 sed 命令读取 www-1.tf 文件,将 www-1 的所有实例替换为 www-2 并创建一个名为 www-2.tf 的新文件。 这是执行此操作的 sed 命令:

sed 's/www-1/www-2/g' www-1.tf > www-2.tf

您可以通过访问 Using sed 了解有关 sed 的更多信息。

再次运行 terraform plan 以预览 Terraform 将进行的更改:

terraform plan \
  -var "do_token=${DO_PAT}" \
  -var "pvt_key=$HOME/.ssh/id_rsa"

输出显示 Terraform 将创建第二个服务器 www-2

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.www-2 will be created
  + resource "digitalocean_droplet" "www-2" {
      + backups              = false
      + created_at           = (known after apply)
      + disk                 = (known after apply)
      + 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                 = "www-2"
      + price_hourly         = (known after apply)
      + price_monthly        = (known after apply)
      + private_networking   = true
      + region               = "nyc3"
      + resize_disk          = true
      + size                 = "s-1vcpu-1gb"
      + ssh_keys             = [
          + "...",
        ]
      + 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 apply 以创建第二个 Droplet:

terraform apply \
  -var "do_token=${DO_PAT}" \
  -var "pvt_key=$HOME/.ssh/id_rsa"

和以前一样,Terraform 会要求您确认是否要继续。 再次查看计划并键入 yes 以继续。

一段时间后,Terraform 将创建新服务器并显示结果:

Outputdigitalocean_droplet.www-2: Creation complete after 1m47s [id=your_www-2_droplet_id]
...
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Terraform 创建了新服务器,而不更改现有服务器。 您可以重复此步骤以添加其他 Nginx 服务器。

现在您有两个运行 Nginx 的 Droplet,您将定义并部署一个负载均衡器来拆分它们之间的流量。

第 6 步 — 创建负载均衡器

您将使用官方 Terraform 提供商支持的 DigitalOcean 负载均衡器 在两个 Web 服务器之间路由流量。

创建一个名为 loadbalancer.tf 的新 Terraform 配置文件:

nano loadbalancer.tf

添加以下行以定义负载均衡器:

~/loadbalance/loadbalancer.tf

resource "digitalocean_loadbalancer" "www-lb" {
  name = "www-lb"
  region = "nyc3"

  forwarding_rule {
    entry_port = 80
    entry_protocol = "http"

    target_port = 80
    target_protocol = "http"
  }

  healthcheck {
    port = 22
    protocol = "tcp"
  }

  droplet_ids = [digitalocean_droplet.www-1.id, digitalocean_droplet.www-2.id ]
}

负载均衡器定义指定了它的名称、它将位于的数据中心、它应该监听以平衡流量的端口、健康检查的配置以及它应该平衡的 Droplet 的 ID,您可以使用 Terraform 变量获取这些信息。 保存并关闭文件。

再次运行 terraform plan 命令查看新的执行计划:

terraform plan \
  -var "do_token=${DO_PAT}" \
  -var "pvt_key=$HOME/.ssh/id_rsa"

您将看到几行输出,包括以下几行:

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_loadbalancer.www-lb will be created
  + resource "digitalocean_loadbalancer" "www-lb" {
      + algorithm                        = "round_robin"
      + disable_lets_encrypt_dns_records = false
      + droplet_ids                      = [
          + ...,
          + ...,
        ]
      + enable_backend_keepalive         = false
      + enable_proxy_protocol            = false
      + id                               = (known after apply)
      + ip                               = (known after apply)
      + name                             = "www-lb"
      + redirect_http_to_https           = false
      + region                           = "nyc3"
      + size_unit                        = (known after apply)
      + status                           = (known after apply)
      + urn                              = (known after apply)
      + vpc_uuid                         = (known after apply)

      + forwarding_rule {
          + certificate_id   = (known after apply)
          + certificate_name = (known after apply)
          + entry_port       = 80
          + entry_protocol   = "http"
          + target_port      = 80
          + target_protocol  = "http"
          + tls_passthrough  = false
        }

      + healthcheck {
          + check_interval_seconds   = 10
          + healthy_threshold        = 5
          + port                     = 22
          + protocol                 = "tcp"
          + response_timeout_seconds = 5
          + unhealthy_threshold      = 3
        }

      + sticky_sessions {
          + cookie_name        = (known after apply)
          + cookie_ttl_seconds = (known after apply)
          + type               = (known after apply)
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.
...

这意味着 www-1www-2 Droplet 已经存在,Terraform 将创建 www-lb 负载均衡器。

运行 terraform apply 构建负载均衡器:

terraform apply \
  -var "do_token=${DO_PAT}" \
  -var "pvt_key=$HOME/.ssh/id_rsa"

Terraform 将再次要求您查看计划。 通过输入 yes 来批准计划以继续。

完成后,您将看到包含以下行的输出,为简洁起见被截断:

Output...
digitalocean_loadbalancer.www-lb: Creating...
...
digitalocean_loadbalancer.www-lb: Creation complete after 1m18s [id=your_load_balancer_id]
...
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
...

使用 terraform show terraform.tfstate 定位负载均衡器的 IP 地址:

terraform show terraform.tfstate

您将在 www-lb 条目下找到 IP:

Output...
# digitalocean_loadbalancer.www-lb:
resource "digitalocean_loadbalancer" "www-lb" {
    algorithm                = "round_robin"
    disable_lets_encrypt_dns_records = false
    droplet_ids              = [
        your_www-1_droplet_id,
        your_www-2_droplet_id,
    ]
    enable_backend_keepalive = false
    enable_proxy_protocol    = false
    id                       = "your_load_balancer_id"
    ip                       = "your_load_balancer_ip"
    name                     = "www-lb"
    ...

在浏览器中导航到 http://your_load_balancer_ip,您将看到 Nginx 欢迎屏幕,因为负载均衡器正在将流量发送到两个 Nginx 服务器之一。

您现在将学习如何使用 Terraform 为您的 DigitalOcean 帐户配置 DNS。

第 7 步 — 创建 DNS 域和记录

除了 Droplet 和负载均衡器,Terraform 还可以创建 DNS 域和记录域。 例如,如果您想将您的域指向您的负载均衡器,您可以编写描述该关系的配置。

<$>[注] 笔记: 使用您自己的唯一域名,否则 Terraform 将无法部署 DNS 资源。 确保您的域指向 DigitalOcean 名称服务器。 <$>

创建一个新文件来描述您的 DNS:

nano domain_root.tf

添加以下域资源,将 your_domain 替换为您的域名:

~/loadbalance/domain_root.tf

resource "digitalocean_domain" "default" {
   name = "your_domain"
   ip_address = digitalocean_loadbalancer.www-lb.ip
}

完成后保存并关闭文件。

您还可以添加将 www.your_domain 指向 your_domain 的 CNAME 记录。 为 CNAME 记录创建一个新文件:

nano domain_cname.tf

将这些行添加到文件中:

domain_cname.tf

resource "digitalocean_record" "CNAME-www" {
  domain = digitalocean_domain.default.name
  type = "CNAME"
  name = "www"
  value = "@"
}

完成后保存并关闭文件。

要添加 DNS 条目,请运行 terraform plan,然后运行 terraform apply,与其他资源一样。

导航到您的域名,您将看到 Nginx 欢迎屏幕,因为该域指向负载均衡器,该负载均衡器将流量发送到两个 Nginx 服务器之一。

第 8 步 — 破坏您的基础设施

虽然在生产环境中不常用,但 Terraform 也可以破坏它创建的基础设施。 这主要在多次部署和销毁的开发环境中有用。

首先,使用 terraform plan -destroy 创建一个执行计划来销毁基础设施:

terraform plan -destroy -out=terraform.tfplan \
  -var "do_token=${DO_PAT}" \
  -var "pvt_key=$HOME/.ssh/id_rsa"

Terraform 将输出一个计划,其中资源标记为红色,并以减号为前缀,表示它将删除您的基础设施中的资源。

然后,使用 terraform apply 运行计划:

terraform apply terraform.tfplan

Terraform 将继续销毁资源,如生成的计划中所示。

结论

在本教程中,您使用 Terraform 在 DigitalOcean 上构建负载平衡的 Web 基础架构,两个 Nginx Web 服务器在 DigitalOcean 负载均衡器后面运行。 您知道如何创建和销毁资源、查看当前状态以及使用 Terraform 配置 DNS 条目。

现在您了解了 Terraform 的工作原理,您可以创建配置文件来描述您自己的项目的服务器基础架构。 本教程中的示例是一个很好的起点,它演示了如何自动部署服务器。 如果您已经使用了供应工具,则可以将它们与 Terraform 集成以将服务器配置为创建过程的一部分,而不是使用本教程中使用的供应方法。

Terraform 具有更多功能,并且可以与其他提供商合作。 查看官方 Terraform 文档,了解更多关于如何使用 Terraform 来改进您自己的基础架构的信息。

本教程是 How To Manage Infrastructure with Terraform 系列的一部分。 该系列涵盖了许多 Terraform 主题,从首次安装 Terraform 到管理复杂的项目。