Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Архитектура Terraform: Основы

Провайдером в Terraform может быть не только облако. Любой сервис или инструмент может быть реализован в виде провайдера, если есть подходящее HTTP API. Так через Terraform можно управлять мессенджерами, Docker, кластером Kubernetes, DNS, настройкой алертов в системах мониторинга и многим другим. Ниже пример алерта для мониторинга в сервисе DataDog:

resource "datadog_monitor" "foo" {
  name               = "Name for monitor foo"
  type               = "metric alert"
  message            = "Monitor triggered. Notify: @hipchat-channel"
  escalation_message = "Escalation message @pagerduty"

  query = "avg(last_1h):avg:aws.ec2.cpu{environment:foo,host:foo} by {host} > 4"

  monitor_thresholds {
    warning           = 2
    warning_recovery  = 1
    critical          = 4
    critical_recovery = 3
  }
}

Terraform постепенно превратился в универсальный инструмент управления сервисами и многими инструментами, такими как, Kubernetes. Практически все, что имеет подходящее HTTP API, может быть добавлено в Terraform.

Архитектура

Для лучшего понимания того, как применять Terraform в разных ситуациях, нужно немного посмотреть на то как он работает и почему он работает.

Принцип работы Terraform

Высокоуровнево работа Terraform выглядит просто. Мы описываем нужные нам ресурсы в виде кода, а он выполняет необходимые HTTP-запросы, для создания этих ресурсов. А что в случае удаления или модификации ресурсов? Как Terraform понимает что ресурс уже есть и его нужно модифицировать, а не создавать заново? И здесь в игру вступает главная особенность Terraform - контроль состояния уже созданных ресурсов.

После добавления нового ресурса, Terraform записывает информацию о нем в файл terraform.tfstate. Информация о том, что из себя представляет текущая инфраструктура, называется состоянием. Главная задача состояния, соотносить ресурсы описанные в Terraform с реальной инфраструктурой.

{
  "version": 4,
  "terraform_version": "1.1.7",
  "serial": 4,
  "lineage": "8fe92982-746c-4949-3dc9-df002ccc8a59",
  "outputs": {},
  "resources": [
    {
      "mode": "managed",
      "type": "hcloud_server",
      "name": "devops-example-app",
      "provider": "provider[\"registry.terraform.io/hetznercloud/hcloud\"]",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "backups": false,
            "datacenter": "hel1-dc2",
            "delete_protection": false,
            "id": "18500771",
            "image": "docker-ce",
            "ipv6_network": "2a01:4f9:c010:eaa9::/64",
            "location": "hel1",
            "name": "devops-example-app",
            "server_type": "cx11",
            "ssh_keys": [
              "c66_92dfbc9c0eebec890868a1c4cb98977a",
              "c66_8ea2516260858e697f3c80dbe578657b",
            ],
            "status": "running",
          },
          "dependencies": [
            "data.hcloud_ssh_keys.all_keys"
          ]
        }
      ]
    }
  ]
}

Затем, когда ресурс изменяется, Terraform сравнивает, что было и что нужно было получить. На основе этого строит план, по которому видно, как ресурсы будут изменяться, что придется добавить, изменить или удалить. И если план нас устраивает, то Terraform формирует и выполняет HTTP-запросы в API нужного сервиса или инструмента. Как только изменения сделаны, они отражаются на файле с состоянием.

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

С другой стороны, Terraform не отслеживает ресурсы, которые были добавлены в обход. Если создать сервер руками, то Terraform его проигнорирует.

Изменение и удаление ресурсов

Благодаря наличию состояния, Terraform сам определяет как произвести изменения. Для удаления ресурса из инфраструктуры, достаточно удалить его описание из Terraform, для изменения - достаточно поменять его описание.

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

Но бывает и наоборот, Terraform может и пытается обновить ресурс без пересоздания, когда мы хотим пересоздания. В такой ситуации поможет команда terraform taint, которая указывает на ресурс, требующий пересоздания:

# <address> - это адрес ресурса в конфигурации
# например hcloud_server.devops-example-app
terraform taint [options] <address>

Список всех ресурсов и их адресов можно посмотреть командой terraform state list

terraform state list
data.hcloud_ssh_keys.all_keys
hcloud_server.devops-example-app

Импортирование ресурсов

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

# Виртуальная машина импортируется по id, который можно получить в интерфейсе Yandex Cloud
terraform import yandex_compute_instance.default 12342345345

Эта команда ничего не меняет в самом Yandex Cloud. С ее помощью Terraform извлекает информацию о ресурсе по API и добавляет ее в файл с состоянием.


Самостоятельная работа

  1. С помощью Terraform опишите конфигурацию сервера для любого вашего приложения. Используйте любое облако на своё усмотрение. Это может быть как DigitalOcean, так и, например, Yandex Cloud.

  2. Запушьте изменения на гитхаб


Дополнительные материалы

  1. О состоянии
  2. Как Terraform применяет новую конфигурацию

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Об обучении на Хекслете

Для полного доступа к курсу нужен базовый план

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

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»