Tutorial

Импорт существующих ресурсов DigitalOcean в Terraform

DigitalOcean Cloud FirewallsTerraformCloud Computing

Автор выбрал фонд Free and Open Source Fund для получения пожертвования в рамках программы Write for DOnations.

Введение

Terraform — созданный HashiCorp инструмент на базе модели «инфраструктура как код». Он помогает разработчикам эффективно развертывать, обновлять и удалять различные ресурсы инфраструктуры и обеспечивает поддержку масштабирования.

Разработчики могут использовать Terraform для организации различных сред, отслеживания изменений посредством контроля версий и автоматизации повторяющихся задач для предотвращения человеческих ошибок. Также Terraform позволяет командам совместно работать над совершенствованием инфраструктуры посредством общих конфигураций.

В этом обучающем руководстве мы импортируем существующую инфраструктуру DigitalOcean в Terraform. К завершению этого обучающего руководства вы сможете использовать Terraform для всей своей инфраструктуры, а также создавать новые ресурсы.

Предварительные требования

Шаг 1 — Локальная установка Terraform

На первом шаге следует установить Terraform на локальный компьютер. На этом шаге описывается установка двоичного файла Linux. Если вы используете операционную систему Windows или Mac, вы можете воспользоваться страницей загрузки Terraform на сайте Terraform.

Перейдите в папку на локальном компьютере, куда вы хотите загрузить Terraform, а затем используйте утилиту wget для загрузки двоичного файла Terraform 0.12.12:

  • cd /tmp
  • wget https://releases.hashicorp.com/terraform/0.12.12/terraform_0.12.12_linux_amd64.zip

Чтобы проверить соответствие контрольной суммы sha256 указанному на сайте Terraform значению, загрузите файл контрольной суммы с помощью следующей команды:

  • wget -q https://releases.hashicorp.com/terraform/0.12.12/terraform_0.12.12_SHA256SUMS

Затем запустите следующую команду для проверки контрольных сумм:

  • sha256sum -c --ignore-missing terraform_0.12.12_SHA256SUMS

В загруженном вами файле SHA256SUMS содержится список имен файлов и значений хэш-сумм для этих файлов. Эта команда ищет локальный файл terraform_0.12.12_SHA256SUMS и проверяет соответствие хэш-сумм, используя флаг -c. Поскольку у этого файла имеется несколько имен файла, и указана его платформа, используйте флаг --ignore-missing для предотвращения ошибок, поскольку у вас нет копий других файлов.

Вы увидите следующий результат:

Output
terraform_0.12.12_linux_amd64.zip: OK

Используйте unzip для распаковки двоичного файла:

  • sudo unzip terraform_0.12.12_linux_amd64.zip -d /usr/local/bin/

Убедитесь в правильности установки Terraform посредством проверки версии:

  • terraform version

Результат будет выглядеть примерно так:

Output
Terraform v0.12.12

Мы установили Terraform на локальном компьютере и можем перейти к подготовке файлов конфигурации.

Шаг 2 — Подготовка файлов конфигурации Terraform

На этом шаге мы импортируем в Terraform имеющиеся ресурсы посредством создания директории проекта и записи файлов конфигурации. Поскольку Terraform не поддерживает генерирование конфигураций из команды import, эти конфигурации следует создать вручную.

Запустите следующую команду для создания директории вашего проекта:

  • mkdir -p do_terraform_import

Затем перейдите в эту директорию:

  • cd do_terraform_import

На этом шаге мы создадим три дополнительных файла, в которых будут содержаться требуемые конфигурации. Структура директорий этого проекта будет выглядеть следующим образом:

├── digitalocean_droplet.tf
├── digitalocean_firewall.tf
└── provider.tf

Для начала мы создадим файл provider.tf для определения токена доступа DigitalOcean как переменной среды вместо его программирования в конфигурации.

Предупреждение. Токен доступа предоставляет неограниченный доступ ко всей вашей инфраструктуре, поэтому с ним следует обращаться осторожно. Убедитесь, что доступ к компьютеру, где хранится токен, имеется только у вас.

Помимо токена доступа также следует указать, какого провайдера вы хотите использовать. Для целей данного обучающего руководства мы используем digitalocean. Полный список доступных источников данных и ресурсов для DigitalOcean с Terraform можно найти на странице провайдеров на соответствующем сайте.

Создайте файл provider.tf и откройте его для редактирования:

  • nano provider.tf

Добавьте в файл provider.tf следующие строки:

provider.tf
variable "do_token" {}

provider "digitalocean" {
    token   = "${var.do_token}"
    version = "1.9.1"
    }

В этом файле вы добавляете свой токен доступа DigitalOcean как переменную, которую Terraform будет использовать для идентификации в DigitalOcean API. Также вы указываете версию плагина провайдера DigitalOcean. Terraform рекомендует указать используемую версию провайдера, чтобы будущие обновления не нарушили имеющуюся систему.

Далее мы создадим файл digitalocean_droplet.tf. Здесь мы указываем, какие ресурсы будем использовать. В данном случае это droplet.

Создайте файл с помощью следующей команды:

  • nano digitalocean_droplet.tf

Добавьте следующую конфигурацию:

digitalocean_droplet.tf
resource "digitalocean_droplet" "do_droplet" {
    name   = "testing-terraform"
    region = "fra1"
    tags   = ["terraform-testing"]
    count  = "1"
}

Здесь задается четыре параметра:

  • name: имя дроплета.

  • region: регион местонахождения дроплета.

  • tags: перечень всех тегов, применяемых к этому дроплету.

  • count: количество ресурсов, требуемых для этой конфигурации.

Далее мы создадим файл конфигурации брандмауэра. Создайте файл digitalocean_firewall.tf с помощью следующей команды:

  • nano digitalocean_firewall.tf

Добавьте в файл следующие строки:

digitalocean_firewall.tf
resource "digitalocean_firewall" "do_firewall" {
  name  = "testing-terraform-firewall"
  tags  = ["terraform-testing"]
  count = "1"
}

Здесь указывается имя брандмауэра, который вы хотите импортировать, а также теги дроплетов, к которым применяются правила брандмауэра. Наконец, значение count 1 определяет требуемое количество соответствующего ресурса.

Примечание. Вы можете включить ресурсы брандмауэра в файл digitalocean_droplet.tf, однако если вы используете несколько сред, где несколько дроплетов используют один брандмауэр, лучше разделить их на случай, если вы захотите удалить один из дроплетов. Это не повлияет на вывод брандмауэра.

Теперь следует инициализировать эти изменения, чтобы у Terraform была возможность загрузить требуемые зависимости. Для этого используется команда terraform init, позволяющая инициализировать рабочую директорию с файлами конфигурации Terraform.

Запустите в директории проекта следующую команду:

  • terraform init

Вывод должен выглядеть так:

Output
Terraform has been successfully initialized!

Terraform успешно подготовил рабочую директорию, выполнив загрузку плагинов, поиск модулей и т. д. Теперь мы можем начать импорт ресурсов в Terraform.

Шаг 3 — Импорт ресурсов в Terraform

На этом шаге вы импортируете ресурсы DigitalOcean в Terraform. Используйте doctl для определения идентификационных номеров дроплетов, прежде чем начать импорт ресурсов. Также вы можете проверить конфигурацию импорта с помощью команд terraform show и terraform plan.

Для начала экспортируйте токен доступа DigitalOcean как переменную среды, которая будет использоваться Terraform во время выполнения.

Экспортируйте ее как переменную среды текущего сеанса оболочки с помощью следующей команды:

  • export DO_TOKEN="YOUR_TOKEN"

Чтобы импортировать существующие дроплет и брандмауэр, вам потребуются их идентификационные номера. Вы можете использовать doctl, интерфейс командной строки DigitalOcean API. Запустите следующую команду для вывода списка дроплетов и получения доступа к их идентификаторам:

  • doctl compute droplet list

Результат будет выглядеть примерно так:

Output
ID Name Public IPv4 Private IPv4 Public IPv6 Memory VCPUs Disk Region Image Status Tags Features Volumes DROPLET-ID DROPLET-NAME DROPLET-IPv4 1024 1 25 fra1 Ubuntu 18.04.3 (LTS) x64 active DROPLET-ID DROPLET-NAME DROPLET-IPv4 2048 1 50 fra1 Ubuntu 18.04.3 (LTS) x64 active DROPLET-ID DROPLET-NAME DROPLET-IPv4 1024 1 25 fra1 Ubuntu 18.04.3 (LTS) x64

Теперь вы импортируете существующий дроплет и брандмауэр в Terraform:

  • terraform import -var "do_token=${DO_TOKEN}" digitalocean_droplet.do_droplet DROPLET_ID

Мы используем флаг -var, чтобы задать токен доступа DigitalOcean, который вы ранее экспортировали в сеанс оболочки. Это требуется, чтобы DigitalOcean API мог проверить вашу личность и применить изменения к инфраструктуре.

Теперь запустите эту же команду для вашего брандмауэра:

  • terraform import -var "do_token=${DO_TOKEN}" digitalocean_firewall.do_firewall FIREWALL_ID

Команда terraform show позволяет проверить, был ли импорт выполнен успешно. Эта команда позволяет получить удобочитаемые данные по состоянию инфраструктуры. Ее можно использовать для проверки плана, чтобы обеспечить выполнение желаемых изменений, или для проверки текущего состояния с точки зрения Terraform.

В этом контексте state означает сопоставление ресурсов DigitalOcean с записанной конфигурацией Terraform и отслеживание метаданных. Это позволяет подтвердить отсутствие различий между существующими ресурсами DigitalOcean, которые вы хотите импортировать, и ресурсами, которые отслеживает Terraform:

  • terraform show

Вывод будет выглядеть следующим образом:

Output
. . . # digitalocean_droplet.do_droplet: resource "digitalocean_droplet" "do_droplet" { backups = false created_at = "2020-02-03T16:12:02Z" disk = 25 id = "DROPLET-ID" image = "DROPLET-IMAGE" ipv4_address = "DROPLET-IP" ipv6 = false locked = false memory = 1024 monitoring = false name = "testing-terraform-0" price_hourly = 0.00744 price_monthly = 5 private_networking = false region = "fra1" resize_disk = true size = "s-1vcpu-1gb" status = "active" tags = [ "terraform-testing", ] urn = "DROPLET-URN" vcpus = 1 volume_ids = [] . . . }

В результатах вы увидите два ресурса совместно с атрибутами.

После импорта дроплета и брандмауэра в состояние Terraform необходимо убедиться, что конфигурации представляют текущее состояние импортируемых ресурсов. Для этого следует указать образ Droplet и его размер. Эти два значения можно увидеть в результатах выполнения команды terraform show для ресурса digitalocean_droplet.do_droplet.

Откройте файл digitalocean_droplet.tf:

  • nano digitalocean_droplet.tf

В этом обучающем руководстве:

  • Образ операционной системы, используемый для нашего дроплета: ubuntu-16-04-x64.
  • Регион, где находится ваш дроплет: fra1.
  • Тег существующего дроплета: terraform-testing.

Дроплет, импортированный с помощью конфигурации в digitalocean_droplet.tf, будет выглядеть следующим образом:

digitalocean_droplet.tf
resource "digitalocean_droplet" "do_droplet" {
    image   = "ubuntu-16-04-x64"
    name    = "testing-terraform"
    region  = "fra1"
    size    = "s-1vcpu-1gb"
    tags    = ["terraform-testing"]
}

Далее вы добавите правила брандмауэра. В нашем примере для входящего трафика открыты порты 22, 80 и 443. Все порты открыты для исходящего трафика. Вы можете изменить конфигурацию в зависимости от состава и количества открытых портов.

Откройте файл digitalocean_firewall.tf:

  • nano digitalocean_firewall.tf

Добавьте следующую конфигурацию:

digitalocean_firewall.tf
resource "digitalocean_firewall" "do_firewall" {
  name  = "testing-terraform-firewall"
  tags  = ["terraform-testing"]
  count = "1"

  inbound_rule {
      protocol                = "tcp"
      port_range              = "22"
      source_addresses        = ["0.0.0.0/0", "::/0"]
    }
  inbound_rule {
      protocol                = "tcp"
      port_range              = "80"
      source_addresses        = ["0.0.0.0/0", "::/0"]
    }
  inbound_rule {
      protocol                = "tcp"
      port_range              = "443"
      source_addresses        = ["0.0.0.0/0", "::/0"]
    }

  outbound_rule {
      protocol                = "tcp"
      port_range              = "all"
      destination_addresses   = ["0.0.0.0/0", "::/0"]
    }
  outbound_rule {
      protocol                = "udp"
      port_range              = "all"
      destination_addresses   = ["0.0.0.0/0", "::/0"]
    }
  outbound_rule {
      protocol                = "icmp"
      destination_addresses   = ["0.0.0.0/0", "::/0"]
    }
}

Эти правила воспроизводят состояние существующего образца брандмауэра. Если вы хотите ограничить трафик для других IP-адресов, портов или протоколов, вы можете изменить файл для соответствия настройкам вашего брандмауэра.

После обновления файлов Terraform используйте команду plan, чтобы увидеть, соответствуют ли внесенные изменения состоянию существующих ресурсов в DigitalOcean.

Команда terraform plan используется для пробного прогона. С ее помощью вы можете проверить, соответствуют ли вносимые Terraform изменения желаемым. Эту команду всегда полезно запускать для подтверждения перед применением изменений.

Запустите команду terraform plan со следующим синтаксисом:

  • terraform plan -var "do_token=$DO_TOKEN"

Вы увидите следующие результаты:

Output
No changes. Infrastructure is up-to-date.

Вы успешно импортировали существующие ресурсы DigitalOcean в Terraform и теперь можете вносить через Terraform изменения в инфраструктуру без риска случайного удаления или изменения существующих ресурсов.

Шаг 4 — Создание новых ресурсов через Terraform

На этом шаге мы добавляем два дополнительных дроплета в существующую инфраструктуру. Например, такое добавление ресурсов в существующую инфраструктуру может быть полезным, если у вас запущен сайт и вы не хотите нарушить его работу во время внесения изменений. Вместо этого вы можете добавить еще один дроплет в качестве среды разработки и поработать над проектом в той же среде, где находится производственный дроплет, без каких-либо потенциальных рисков.

Откройте файл digitalocean_droplet.tf для добавления правил для новых дроплетов:

  • nano digitalocean_droplet.tf

Добавьте в файл следующие строки:

digitalocean_droplet.tf
resource "digitalocean_droplet" "do_droplet" {
    image   = "ubuntu-16-04-x64"
    name    = "testing-terraform"
    region  = "fra1"
    size    = "s-1vcpu-1gb"
    tags    = ["terraform-testing"]
    count   = "1"
}

resource "digitalocean_droplet" "do_droplet_new" {
    image   = "ubuntu-18-04-x64"
    name    = "testing-terraform-${count.index}"
    region  = "fra1"
    size    = "s-1vcpu-1gb"
    tags    = ["terraform-testing"]
    count   = "2"
}

Вы используете мета-аргумент count, чтобы указать Terraform, сколько дроплетов с такими же спецификациями вам потребуется. Эти новые дроплеты также будут добавлены в брандмауэр, поскольку вы указываете тот же тег, что и для брандмауэра.

Примените эти правила для проверки изменений, задаваемых в digitalocean_droplet.tf:

  • terraform plan -var "do_token=$DO_TOKEN"

Убедитесь, что желаемые изменения отражаются в результатах выполнения команды.

Результат будет выглядеть примерно так:

Output
. . . # digitalocean_droplet.do_droplet_new[1] will be created + resource "digitalocean_droplet" "do_droplet_new" { + backups = false + created_at = (known after apply) + disk = (known after apply) + id = (known after apply) + image = "ubuntu-18-04-x64" + ipv4_address = (known after apply) + ipv4_address_private = (known after apply) + ipv6 = false + ipv6_address = (known after apply) + ipv6_address_private = (known after apply) + locked = (known after apply) + memory = (known after apply) + monitoring = false + name = "testing-terraform-1" + price_hourly = (known after apply) + price_monthly = (known after apply) + private_networking = true + region = "fra1" + resize_disk = true + size = "s-1vcpu-1gb" + status = (known after apply) + tags = [ + "terraform-testing", ] + urn = (known after apply) + vcpus = (known after apply) + volume_ids = (known after apply) } Plan: 2 to add, 1 to change, 0 to destroy.

Когда вы будете довольны результатами, используйте команду terraform apply для применения указанных изменений к состоянию конфигурации:

  • terraform apply -var "do_token=$DO_TOKEN"

Подтвердите внесение изменений, введя yes в командной строке. После успешного выполнения вы увидите примерно следующее:

Output
. . . digitalocean_droplet.do_droplet_new[1]: Creating... digitalocean_droplet.do_droplet_new[0]: Creating... digitalocean_firewall.do_firewall[0]: Modifying... [id=FIREWALL-ID] digitalocean_firewall.do_firewall[0]: Modifications complete after 1s [id=FIREWALL-ID] digitalocean_droplet.do_droplet_new[0]: Still creating... [10s elapsed] digitalocean_droplet.do_droplet_new[1]: Still creating... [10s elapsed] digitalocean_droplet.do_droplet_new[0]: Creation complete after 16s [id=DROPLET-ID] digitalocean_droplet.do_droplet_new[1]: Still creating... [20s elapsed] digitalocean_droplet.do_droplet_new[1]: Creation complete after 22s [id=DROPLET-ID] Apply complete! Resources: 2 added, 1 changed, 0 destroyed.

Вы увидите два новых дроплета на веб-панели DigitalOcean: новые дроплеты

Также вы увидите, что они прикреплены к существующему брандмауэру: существующий брандмауэр

Вы создали с помощью Terraform новые ресурсы, использовав для этого имеющиеся ресурсы. На следующем шаге вы можете узнать, как уничтожить эти ресурсы.

Шаг 5 — Уничтожение импортированных и созданных ресурсов (необязательно)

На этом шаге мы уничтожим импортированные и созданные ресурсы посредством изменения конфигурации.

Откройте digitalocean_droplet.tf:

  • nano digitalocean_droplet.tf

Задайте в файле для параметра count значение 0, как показано здесь:

digitalocean_droplet.tf
resource "digitalocean_droplet" "do_droplet" {
    image   = "ubuntu-16-04-x64"
    name    = "testing-terraform"
    region  = "fra1"
    size    = "s-1vcpu-1gb"
    tags    = ["terraform-testing"]
    count   = "0"
}

resource "digitalocean_droplet" "do_droplet_new" {
    image   = "ubuntu-18-04-x64"
    name    = "testing-terraform-${count.index}"
    region  = "fra1"
    size    = "s-1vcpu-1gb"
    tags    = ["terraform-testing"]
    count   = "0"
}

Сохраните и закройте файл.

Откройте файл конфигурации брандмауэра и измените в нем параметр count:

  • nano digitalocean_firewall.tf

Задайте для параметра count значение 0, как в следующей строке:

digitalocean_firewall.tf
resource "digitalocean_firewall" "do_firewall" {
  name  = "testing-terraform-firewall"
  tags  = ["terraform-testing"]
  count = "0"

  inbound_rule {
      protocol                = "tcp"
      port_range              = "22"
      source_addresses        = ["0.0.0.0/0", "::/0"]
    }
  inbound_rule {
      protocol                = "tcp"
      port_range              = "80"
      source_addresses        = ["0.0.0.0/0", "::/0"]
    }
  inbound_rule {
      protocol                = "tcp"
      port_range              = "443"
      source_addresses        = ["0.0.0.0/0", "::/0"]
    }

  outbound_rule {
      protocol                = "tcp"
      port_range              = "all"
      destination_addresses   = ["0.0.0.0/0", "::/0"]
    }
  outbound_rule {
      protocol                = "udp"
      port_range              = "all"
      destination_addresses   = ["0.0.0.0/0", "::/0"]
    }
  outbound_rule {
      protocol                = "icmp"
      destination_addresses   = ["0.0.0.0/0", "::/0"]
    }
}

Сохраните и закройте файл.

Примените изменения с помощью следующей команды:

  • terraform apply -var "do_token=${DO_TOKEN}"

Terraform предложит подтвердить уничтожение дроплетов и брандмауэра. Эта команда уничтожит все ресурсы, импортированные и созданные с помощью Terraform, так что вводите yes, только если уверены, что хотите продолжить.

Результат будет выглядеть примерно так:

Output
. . . digitalocean_droplet.do_droplet[0]: Destroying... [id=YOUR-DROPLET-ID]] digitalocean_droplet.do_droplet_new[0]: Destroying... [id=YOUR-DROPLET-ID] digitalocean_droplet.do_droplet_new[1]: Destroying... [id=YOUR-DROPLET-ID] digitalocean_firewall.do_firewall[0]: Destroying... [id=YOUR-FIREWALL-ID] digitalocean_firewall.do_firewall[0]: Destruction complete after 1s digitalocean_droplet.do_droplet_new[1]: Still destroying... [id=YOUR-DROPLET-ID, 10s elapsed] digitalocean_droplet.do_droplet[0]: Still destroying... [id=YOUR-DROPLET-ID, 10s elapsed] digitalocean_droplet.do_droplet_new[0]: Still destroying... [id=YOUR-DROPLET-ID, 10s elapsed] digitalocean_droplet.do_droplet_new[1]: Still destroying... [id=YOUR-DROPLET-ID, 20s elapsed] digitalocean_droplet.do_droplet_new[0]: Still destroying... [id=YOUR-DROPLET-ID, 20s elapsed] digitalocean_droplet.do_droplet[0]: Still destroying... [id=YOUR-DROPLET-ID, 20s elapsed] digitalocean_droplet.do_droplet_new[1]: Destruction complete after 22s digitalocean_droplet.do_droplet[0]: Destruction complete after 22s digitalocean_droplet.do_droplet_new[0]: Destruction complete after 22s Apply complete! Resources: 0 added, 0 changed, 4 destroyed.

Вы удалили все ресурсы, управляемые Terraform. Это полезный рабочий процесс для удаления ненужных ресурсов или в случае уменьшения масштаба.

Заключение

В этом обучающем руководстве мы выполнили установку Terraform, импортировали существующие ресурсы, создали новые ресурсы и (при желании) уничтожили эти ресурсы. Вы можете использовать этот рабочий процесс и в более масштабном проекте, например для развертывания кластера Kubernetes в производственной среде. С помощью Terraform вы сможете управлять всеми узлами, записями DNS, брандмауэрами, ресурсами хранения и другими ресурсами, а также использовать систему контроля версий для отслеживания изменений и совместной работы в команде.

Дополнительные сведения о возможностях Terraform можно найти в документации. Также вы можете ознакомиться с другими обучающими руководствами и ответами на вопросы в материалах DigitalOcean по Terraform.

Creative Commons License