Зарегистрируйтесь, чтобы продолжить обучение

Архитектура 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 опишите конфигурацию сервера для любого вашего приложения.

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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