如何将现有的 DigitalOcean 资产导入 Terraform

作者选择了 自由和开源基金作为 写给捐款计划的一部分接受捐款。

介绍

Terraform是由HashiCorp(https://www.hashicorp.com/)创建的基础设施代码工具,可帮助开发人员以更高效、更可扩展的方式部署、更新和删除基础设施中的不同资产。

开发人员可以使用Terraform来组织不同的环境,通过版本控制跟踪更改,并自动重复工作,以限制人为错误。

在本教程中,您将导入现有的DigitalOcean基础设施到Terraform. 在本教程结束时,您将能够使用Terraform用于所有现有的基础设施,除了创建新的资产。

前提条件

  • 您可以通过DigitalOcean控制面板创建的DigitalOcean个人访问令牌,您可以在DigitalOcean产品文件中找到指示

【如何创建个人访问代码】(https://www.digitalocean.com/docs/api/create-personal-access-token/)

您可以使用以下指南: 如何从DigitalOcean控制面板创建一个Droplet)。在本教程中使用的标签是 terraform-testing.

  • 将DigitalOcean Cloud Firewall应用于您的Droplet。您可以使用指南: How To Create Firewalls。 防火墙名称 testing-terraform-firewall用于本教程的目的
  • 在本地机器上安装的DigitalOcean命令行客户端,您可以通过在 doctlGitHub 页面上的安装说明来完成。 您可以阅读本教程: [How To Use Doctl, the Official DigitalOcean

本教程是使用Terraform 1.0.10测试的。

步骤一:本地安装地板

在此第一步中,您将在本地计算机上安装 Terraform. 此步骤详细介绍了在 Linux 发行版上安装 Terraform. 如果您使用的是 Windows 或 MacOS,您可以在 Terraform 网站上查看 下载 Terraform 页面

安装步骤在 HashiCorp 网站上描述。

<$>[注] **注:通常在同一命令中直接从互联网下载的对象/可执行程序的管道运行通常是不好的做法,但由于HashiCorp是值得信赖的来源,我们将在这里做例外 如果你觉得不舒服这样做,先下载对象,检查它,然后继续前进,如果一切看起来很好 <$>

安装在 Ubuntu 20.04 上

HashiCorp 数字签名其存储库,因此您需要添加其 GNU 隐私保护程序 (GPG) 密钥,这提供了合理的保证,该存储库实际上由 HashiCorp 拥有和维护:

1curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -

将官方 HashiCorp 存储库添加到系统:

1sudo apt-add-repository "deb [arch=$(dpkg --print-architecture)] https://apt.releases.hashicorp.com $(lsb_release -cs) main"

安装地形:

1sudo apt update; sudo apt install terraform=1.0.10

安装在 Fedora 34 上

为了添加 HashiCorp 存储库,您需要将其添加到您的存储库列表中。 DNF 核心插件 config-manager 用于此目的,并由 dnf-plugins-core 包提供。

1sudo dnf install -y dnf-plugins-core

将官方 HashiCorp 存储库添加到系统:

1sudo dnf config-manager --add-repo https://rpm.releases.hashicorp.com/fedora/hashicorp.repo

安装地形:

1sudo dnf install terraform-1.0.10-1

遵循您的操作系统的安装指示后,通过检查版本来检查Terraform是否正确安装:

1terraform version

结果将看起来像这样:

1[secondary_label Output]
2Terraform v1.0.10
3on linux_amd64

您已在本地机器上安装了 Terraform. 接下来,您将准备配置文件。

步骤 2 – 准备 Terraform 配置文件

在此步骤中,您将通过创建项目目录和编写配置文件来导入现有资产到Terraform。

运行以下命令来创建您的项目目录:

1mkdir -p do_terraform_import

然后进入该目录:

1cd do_terraform_import

启动一个新的 Terraform 工作空间:

1terraform workspace new do_terraform_import

查看您是否正在使用新创建的工作区:

1terraform workspace list

结果将类似于此:

1[secondary_label Output]
2  default
3* do_terraform_import

在此步骤中,您将创建三个附加文件,其中包含所需的配置. 此项目的目录结构将如下:

1├── digitalocean_droplet.tf
2├── digitalocean_firewall.tf
3├── provider.tf
4├── .terraform
5└── terraform.tfstate.d

首先,您将创建provider.tf文件,将您的 DigitalOcean Access Token 定义为环境变量,而不是将其硬编码到您的配置中。

<$>[警告] 警告:您的访问令牌可以访问您的完整基础设施,无限制访问,因此,请确保您是唯一可以访问该令牌存储的机器的人。

在本教程中,它是digitalocean。 对于有用的数据源和资源的完整列表,DigitalOcean with Terraform,请访问他们的网站上的提供者页面(https://www.terraform.io/docs/providers/do/index.html)。

使用以下命令创建和编辑 provider.tf:

1nano provider.tf

将以下内容添加到provider.tf文件中:

 1[label provider.tf]
 2terraform {
 3  required_providers {
 4    digitalocean = {
 5      source = "digitalocean/digitalocean"
 6      version = "2.15.0"
 7    }
 8  }
 9}
10
11variable "do_token" {}
12
13provider "digitalocean" {
14  token = var.do_token
15}

在此文件中,您将您的 DigitalOcean Access Token 添加为变量,而 Terraform 将其用作 DigitalOcean API 的标识。

保存并关闭文件。

现在你将创建的 digitalocean_droplet.tf 文件. 在这里,你将指定你要使用的资源,在这种情况下: droplet

此文件应复制现有资源,以便在以后的步骤中成功导入 Terraform 状态。

使用以下命令创建文件:

1nano digitalocean_droplet.tf

添加以下配置,在必要时更新以匹配您的现有资源:

1[label digitalocean_droplet.tf]
2resource "digitalocean_droplet" "do_droplet" {
3    name   = "testing-terraform"
4    region = "fra1"
5    tags   = ["terraform-testing"]
6    count  = "1"
7}

在这里,您指定了四个参数,这些参数应匹配您的现有资源:

  • 名称: Droplet 名称
  • 区域: Droplet 所在的区域
  • 标签:将应用于此 Droplet 的标签列表
  • `数:此配置所需的资源数量

保存并关闭文件。

接下来,您将为您的防火墙创建一个配置文件. 使用以下命令创建文件 digitalocean_firewall.tf:

1nano digitalocean_firewall.tf

将以下内容添加到文件中:

1[label digitalocean_firewall.tf]
2resource "digitalocean_firewall" "do_firewall" {
3  name  = "testing-terraform-firewall"
4  tags  = ["terraform-testing"]
5}

在这里,您指定您要导入的防火墙的名称以及适用于防火墙规则的 Droplets 标签。

保存并关闭文件。

<$>[注] :您也可以将防火墙资源包含在 digitalocean_droplet.tf 文件中;但是,如果您有多个环境,其中多个 Droplets 共享相同的防火墙,如果您只想删除单个 Droplet,则最好将它们分开。

现在是时候初始化这些更改,以便Terraform可以下载所需的依赖性,您将使用terraform init命令,这将允许您初始化包含Terraform配置文件的工作目录。

从您的项目目录中运行此命令:

1terraform init

您将看到以下输出:

1[secondary_label Output]
2Terraform has been successfully initialized!

Terraform通过下载插件,搜索模块等成功准备了工作目录,接下来您将开始导入您的资产到Terraform。

步骤 3 – 将您的资产导入 Terraform

在此步骤中,您将将您的 DigitalOcean 资产导入 Terraform. 在导入资产之前,您将使用doctl查找您的 Droplets 的 ID 号码。

首先,您将将您的 DigitalOcean Access Token 导出为环境变量,然后在运行时将其注入到 Terraform。

将其作为环境变量导出到当前壳会话中,使用以下命令:

1export DO_TOKEN="YOUR_TOKEN"

为了导入现有的 Droplet 和防火墙,您需要他们的 ID 号码,您可以使用doctl,这是 DigitalOcean API 的命令行界面。

运行以下命令列出您的 Droplets 并访问他们的 ID:

1doctl compute droplet list

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

1[secondary_label Output]
2ID Name Public IPv4
3DROPLET-ID DROPLET-NAME DROPLET-IPv4
4DROPLET-ID DROPLET-NAME DROPLET-IPv4
5DROPLET-ID DROPLET-NAME DROPLET-IPv4

请注意您要导入的资源的 Droplet ID,因为您将在以后的命令中需要这样做。

接下来,运行以下命令列出您的防火墙并访问他们的ID:

1doctl compute firewall list

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

1[secondary_label Output]
2ID Name Status
3FIREWALL-ID FIREWALL-NAME succeeded

请注意您要导入的资源的防火墙 ID,因为您将在以后的命令中需要这样做。

将现有 Droplet 导入 Terraform,以您的 Droplet ID 代替 DROPLET-ID:

1terraform import -var "do_token=${DO_TOKEN}" digitalocean_droplet.do_droplet DROPLET-ID

您使用-var旗帜来指定您之前向壳会话导出的DigitalOcean Access Token值,这需要DigitalOcean API来验证您是谁,并对您的基础设施进行更改。

现在为您的防火墙运行相同的命令,将FIREWALL ID替换为您的防火墙ID:

1terraform import -var "do_token=${DO_TOKEN}" digitalocean_firewall.do_firewall FIREWALL-ID

您可以通过使用terraform 显示命令检查导入是否成功. 此命令可为基础设施状态提供可人读的输出。

在这种情况下, state 是指将您的 DigitalOcean 资产与您编写的 Terraform 配置进行映射,以及跟踪元数据,这使您能够确认您想要导入的现有 DigitalOcean 资产与 Terraform 正在跟踪的资产之间没有差异:

1terraform show

结果将看起来像这样:

 1[secondary_label Output]
 2. . .
 3# digitalocean_droplet.do_droplet:
 4resource "digitalocean_droplet" "do_droplet" {
 5    backups            = false
 6    created_at         = "2020-02-03T16:12:02Z"
 7    disk               = 25
 8    id                 = "DROPLET-ID"
 9    image              = "DROPLET-IMAGE"
10    ipv4_address       = "DROPLET-IP"
11    ipv6               = false
12    locked             = false
13    memory             = 1024
14    monitoring         = false
15    name               = "testing-terraform-0"
16    price_hourly       = 0.00744
17    price_monthly      = 5
18    private_networking = false
19    region             = "fra1"
20    resize_disk        = true
21    size               = "s-1vcpu-1gb"
22    status             = "active"
23    tags               = [
24        "terraform-testing",
25    ]
26    urn                = "DROPLET-URN"
27    vcpus              = 1
28    volume_ids         = []
29. . .
30}

您将在输出中看到两个资源及其属性。

将您的 Droplet 和防火墙导入 Terraform 状态后,您需要确保配置代表已导入资产的当前状态。 要做到这一点,您将指定您的 Droplet 的图像大小

打开digitalocean_droplet.tf文件:

1nano digitalocean_droplet.tf

在本教程中:

  • 现有 Droplet 所使用的操作系统图像为 ubuntu-20-04-x64.
  • Droplet 所在的区域为 fra1. *现有 Droplet 的 Droplet 标签为 terraform-testing.

<$>[注] :您的操作系统、区域、滴滴的大小和其他资源可能有所不同,请确保更新文件以反映您的值 <$> 为了确保 `digitalocean_droplet.tf 中的配置匹配进口滴滴的当前状态,它需要被更新以显示如下:

1[label digitalocean_droplet.tf]
2resource "digitalocean_droplet" "do_droplet" {
3    image   = "ubuntu-20-04-x64"
4    name    = "testing-terraform"
5    region  = "fra1"
6    size    = "s-1vcpu-1gb"
7    tags    = ["terraform-testing"]
8}

如有必要,更新配置以匹配您导入的 Droplet。

接下来,您将添加防火墙规则。在我们的示例中,入口流量的开放端口为22,80443

打开digitalocean_firewall.tf:

1nano digitalocean_firewall.tf

添加以下配置:

 1[label digitalocean_firewall.tf]
 2resource "digitalocean_firewall" "do_firewall" {
 3  name  = "testing-terraform-firewall"
 4  tags  = ["terraform-testing"]
 5
 6  inbound_rule {
 7      protocol                = "tcp"
 8      port_range              = "22"
 9      source_addresses        = ["0.0.0.0/0", "::/0"]
10    }
11  inbound_rule {
12      protocol                = "tcp"
13      port_range              = "80"
14      source_addresses        = ["0.0.0.0/0", "::/0"]
15    }
16  inbound_rule {
17      protocol                = "tcp"
18      port_range              = "443"
19      source_addresses        = ["0.0.0.0/0", "::/0"]
20    }
21
22  outbound_rule {
23      protocol                = "tcp"
24      port_range              = "all"
25      destination_addresses   = ["0.0.0.0/0", "::/0"]
26    }
27  outbound_rule {
28      protocol                = "udp"
29      port_range              = "all"
30      destination_addresses   = ["0.0.0.0/0", "::/0"]
31    }
32  outbound_rule {
33      protocol                = "icmp"
34      destination_addresses   = ["0.0.0.0/0", "::/0"]
35    }
36}

这些规则复制现有示例防火墙的状态. 如果您想限制流量到不同的 IP 地址、不同的端口或不同的协议,您可以调整文件以复制现有防火墙。

保存并关闭文件。

更新 Terraform 文件后,您将使用计划命令查看所做的更改是否复制了 DigitalOcean 上现有资产的状态。

使用此命令,您可以检查Terraform要做的更改是否是您想要做的更改。

运行terraform计划以如下方式:

1terraform plan -var "do_token=$DO_TOKEN"

如果没有检测到任何变化,输出将看起来像这样:

1[secondary_label Output]
2No changes. Infrastructure is up-to-date.

如果检测到更改,Terraform输出将显示它们,以便您相应审查和调整。

您已成功将现有的 DigitalOcean 资产导入 Terraform,现在您可以通过 Terraform 对您的基础设施进行更改,而无需意外删除或修改现有资产的风险。

第4步:通过Terraform创建新资产

在此步骤中,您将添加两个额外的 Droplets 到您的现有基础设施. 以此方式添加资产到您的现有基础设施可以是有用的,例如,如果您有一个实时网站,而不想在工作时对该网站进行任何潜在的破坏性更改。

打开digitalocean_droplet.tf以添加新 Droplets 的规则:

1nano digitalocean_droplet.tf

将突出的行添加到您的文件中:

 1[label digitalocean_droplet.tf]
 2resource "digitalocean_droplet" "do_droplet" {
 3    image   = "ubuntu-20-04-x64"
 4    name    = "testing-terraform"
 5    region  = "fra1"
 6    size    = "s-1vcpu-1gb"
 7    tags    = ["terraform-testing"]
 8    count   = "1"
 9}
10
11resource "digitalocean_droplet" "do_droplet_new" {
12    image   = "ubuntu-20-04-x64"
13    name    = "testing-terraform-${count.index}"
14    region  = "fra1"
15    size    = "s-1vcpu-1gb"
16    tags    = ["terraform-testing"]
17    count   = "2"
18}

您可以使用计数元参数告诉Terraform您想要的相同规格的 Droplets 数目。

应用这些规则来检查您在digitalocean_droplet.tf中指定的更改:

1terraform plan -var "do_token=$DO_TOKEN"

检查您要做的更改是否在该命令的输出中复制。

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

 1. . .
 2[secondary_label Output]
 3# digitalocean_droplet.do_droplet_new[1] will be created
 4  + resource "digitalocean_droplet" "do_droplet_new" {
 5      + backups              = false
 6      + created_at           = (known after apply)
 7      + disk                 = (known after apply)
 8      + id                   = (known after apply)
 9      + image                = "ubuntu-20-04-x64"
10      + ipv4_address         = (known after apply)
11      + ipv4_address_private = (known after apply)
12      + ipv6                 = false
13      + ipv6_address         = (known after apply)
14      + ipv6_address_private = (known after apply)
15      + locked               = (known after apply)
16      + memory               = (known after apply)
17      + monitoring           = false
18      + name                 = "testing-terraform-1"
19      + price_hourly         = (known after apply)
20      + price_monthly        = (known after apply)
21      + private_networking   = true
22      + region               = "fra1"
23      + resize_disk          = true
24      + size                 = "s-1vcpu-1gb"
25      + status               = (known after apply)
26      + tags                 = [
27          + "terraform-testing",
28        ]
29      + urn                  = (known after apply)
30      + vcpus                = (known after apply)
31      + volume_ids           = (known after apply)
32    }
33
34Plan: 2 to add, 1 to change, 0 to destroy.

一旦您对输出满意,请使用terraform apply命令将您指定的更改应用到配置状态:

1terraform apply -var "do_token=$DO_TOKEN"

通过在命令行中输入来确认更改,成功执行后,您将看到类似于以下的输出:

 1[secondary_label Output]
 2. . .
 3digitalocean_droplet.do_droplet_new[1]: Creating...
 4digitalocean_droplet.do_droplet_new[0]: Creating...
 5digitalocean_firewall.do_firewall[0]: Modifying... [id=FIREWALL-ID]
 6digitalocean_firewall.do_firewall[0]: Modifications complete after 1s [id=FIREWALL-ID]
 7digitalocean_droplet.do_droplet_new[0]: Still creating... [10s elapsed]
 8digitalocean_droplet.do_droplet_new[1]: Still creating... [10s elapsed]
 9digitalocean_droplet.do_droplet_new[0]: Creation complete after 16s [id=DROPLET-ID]
10digitalocean_droplet.do_droplet_new[1]: Still creating... [20s elapsed]
11digitalocean_droplet.do_droplet_new[1]: Creation complete after 22s [id=DROPLET-ID]
12
13Apply complete! Resources: 2 added, 1 changed, 0 destroyed.

You'll see two new Droplets in your DigitalOcean web panel: New Droplets

You'll also see them attached to your existing firewall: Existing Firewall

您已使用 Terraform 创建新资产,使用现有资产. 要了解如何破坏这些资产,您可以选择完成下一步。

步骤 5 – 销毁已导入和创建的资产(可选)

在此步骤中,您将使用Terraform的摧毁选项来摧毁您导入和创建的资产。

要摧毁由 Terraform 处理的资产,请执行以下命令:

1terraform destroy -var "do_token=${DO_TOKEN}"

Terraform 将要求您确认您是否想要摧毁 Droplets 和防火墙. 这将摧毁您通过 Terraform 导入和创建的所有资产,因此请确保在键入之前继续。

结果将看起来像这样:

 1[secondary_label Output]
 2. . .
 3digitalocean_droplet.do_droplet[0]: Destroying... [id=YOUR-DROPLET-ID]]
 4digitalocean_droplet.do_droplet_new[0]: Destroying... [id=YOUR-DROPLET-ID]
 5digitalocean_droplet.do_droplet_new[1]: Destroying... [id=YOUR-DROPLET-ID]
 6digitalocean_firewall.do_firewall[0]: Destroying... [id=YOUR-FIREWALL-ID]
 7digitalocean_firewall.do_firewall[0]: Destruction complete after 1s
 8digitalocean_droplet.do_droplet_new[1]: Still destroying... [id=YOUR-DROPLET-ID, 10s elapsed]
 9digitalocean_droplet.do_droplet[0]: Still destroying... [id=YOUR-DROPLET-ID, 10s elapsed]
10digitalocean_droplet.do_droplet_new[0]: Still destroying... [id=YOUR-DROPLET-ID, 10s elapsed]
11digitalocean_droplet.do_droplet_new[1]: Still destroying... [id=YOUR-DROPLET-ID, 20s elapsed]
12digitalocean_droplet.do_droplet_new[0]: Still destroying... [id=YOUR-DROPLET-ID, 20s elapsed]
13digitalocean_droplet.do_droplet[0]: Still destroying... [id=YOUR-DROPLET-ID, 20s elapsed]
14digitalocean_droplet.do_droplet_new[1]: Destruction complete after 22s
15digitalocean_droplet.do_droplet[0]: Destruction complete after 22s
16digitalocean_droplet.do_droplet_new[0]: Destruction complete after 22s
17
18Apply complete! Resources: 0 added, 0 changed, 4 destroyed.

您已成功删除由 Terraform 管理的所有资产。

结论

在本教程中,您安装了Terraform,导入了现有资产,创建了新资产,并可选地摧毁了这些资产。您可以将此工作流程扩展到更大的项目,例如部署一个生产准备的Kubernetes集群。使用Terraform,您可以管理所有节点,DNS条目,防火墙,存储和其他资产,以及使用版本控制来跟踪变化并与团队合作。

要探索其他 Terraform 功能,请阅读他们的 文档。你也可以阅读 DigitalOcean 的 Terraform 内容 有关进一步的教程和问答。

Published At
Categories with 技术
comments powered by Disqus