Когда инфраструктура меняется вне вашего пайплайна: упражнение по обнаружению дрейфа

У вас есть Terraform-конфигурация, которая определяет security group. У нее правильное имя, корректные inbound-правила и нужные теги. Ваш пайплайн выполнился успешно, ресурс создан, state-файл чист. Все выглядит хорошо.

Затем кто-то заходит в облачную консоль и вносит небольшое изменение. Может быть, переименовывает security group, потому что имя было непонятным. Может быть, добавляет inbound-правило, чтобы быстро что-то протестировать. Или удаляет тег, который показался ненужным. Никаких изменений кода. Никакого запуска пайплайна. Просто ручная правка в консоли.

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

Как выглядит дрейф на самом деле

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

  • Кто-то исправляет срочную проблему прямо в продакшене, потому что пайплайн занял бы слишком много времени.
  • Облачный провайдер автоматически ротирует сертификат или меняет настройки по умолчанию.
  • Член команды случайно удаляет ресурс, наводя порядок в другом месте.
  • Автоматизированная политика вне вашего пайплайна изменяет ресурс по требованиям комплаенса.

Проблема не в том, что дрейф существует. Проблема в том, что вы не знаете о нем, пока что-то не сломается.

Простое упражнение для наблюдения дрейфа в действии

Вы можете смоделировать дрейф в своем окружении с минимальной подготовкой. Вам понадобится облачный аккаунт с ресурсами из free tier, или можно использовать локальный симулятор вроде LocalStack. Для обучения подойдет даже mock-файл состояния.

Начните с создания одного ресурса с помощью Terraform. Хорошо подойдет security group в AWS или storage bucket в любом облачном провайдере. Запустите пайплайн, пока ресурс не будет создан и файл состояния не сохранен. Убедитесь, что вы видите ресурс в облачной консоли.

Вот минимальная конфигурация Terraform, которую вы можете использовать:

# main.tf
provider "aws" {
  region = "us-east-1"
}

resource "aws_security_group" "web_sg" {
  name        = "web-server-sg"
  description = "Allow HTTP and SSH traffic"

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["10.0.0.0/8"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "web-server-sg"
    Env  = "test"
  }
}

Выполните terraform init и terraform apply, чтобы создать security group. Затем в консоли AWS вручную переименуйте security group в web-server-sg-manual и удалите тег Env. После этого запустите terraform plan, чтобы увидеть дрейф:

$ terraform plan
aws_security_group.web_sg: Refreshing state... [id=sg-0123456789abcdef0]

Terraform will perform the following actions:

  # aws_security_group.web_sg will be updated in-place
  ~ resource "aws_security_group" "web_sg" {
        id          = "sg-0123456789abcdef0"
      ~ name        = "web-server-sg-manual" -> "web-server-sg"
        tags        = {
          - "Env"  = "test" -> null
            "Name" = "web-server-sg"
        }
        # (6 unchanged attributes hidden)
    }

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

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

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

  • Переименуйте security group.
  • Добавьте inbound-правило, которого нет в вашем коде.
  • Удалите тег, который определен в коде.
  • Измените настройки публичного доступа к bucket.

Цель — создать ситуацию, когда фактический ресурс больше не соответствует вашему коду. Это и есть дрейф.

Следующая блок-схема иллюстрирует последовательность событий в этом упражнении по обнаружению дрейфа:

flowchart TD A[Желаемое состояние: Terraform Config] --> B[Пайплайн создает ресурс] B --> C[Фактическое состояние совпадает с конфигом] C --> D[Ручное изменение в консоли] D --> E[Фактическое состояние расходится с конфигом] E --> F[Запуск terraform plan] F --> G{План показывает изменения?} G -- Да --> H[Дрейф обнаружен] G -- Нет --> I[Дрейфа нет] H --> J{Решение о реконсилиации} J -- Принять изменение --> K[Обновить Terraform-код] J -- Вернуть конфиг --> L[Запустить terraform apply] K --> M[Пайплайн выполняется, состояние совпадает] L --> M

Запуск terraform plan после дрейфа

После того как вы внесли ручное изменение, выполните terraform plan в терминале. Внимательно посмотрите на вывод. Terraform сравнит ваш state-файл с фактическим ресурсом и покажет, что изменится, если запустить apply.

Обратите внимание на важный момент: план может показать изменения, которых вы не ожидали. Возможно, он хочет переименовать security group обратно в исходное имя. Возможно, удалить правило, которое кто-то добавил. Но он также может показать изменения других ресурсов, которые зависят от измененного вами. Простое переименование может повлиять на load balancer, target group или IAM-политику, которая ссылается на security group по имени.

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

Явное обнаружение дрейфа

В Terraform есть команда terraform refresh, которая обновляет state-файл в соответствии с фактическим состоянием ресурсов. Запустите ее, затем снова выполните terraform plan. Вы увидите тот же дрейф, но теперь ваш state-файл отражает реальность. Это полезно для понимания того, что изменилось, но не исправляет дрейф. Это просто его признание.

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

Запишите, какие ресурсы дрейфовали и что изменилось. Эта запись поможет вам подумать о следующем шаге.

Принятие решения о реконсилиации

Теперь у вас есть выбор. Вы знаете, что инфраструктура дрейфовала. Вы знаете, что изменилось. Что вы будете с этим делать?

Задайте себе эти вопросы:

  • Было ли ручное изменение намеренным? Сделал ли его кто-то по уважительной причине, например, для исправления срочной проблемы?
  • Нужно ли это изменение все еще? Возможно, чрезвычайная ситуация закончилась, и ресурс должен вернуться в исходное состояние.
  • Безопасно ли откатывать изменение? Откат может сломать то, что теперь зависит от новой конфигурации.
  • Знает ли кто-то в команде, почему было сделано изменение? Есть ли запись в тикете или чате?

Если вы решите выполнить реконсилиацию, запустите terraform apply. Ресурс должен вернуться в состояние, определенное в вашем коде. Проверьте, что все работает как ожидается.

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

Вариации для экспериментов

Как только вы освоите базовый сценарий, попробуйте более сложные вариации:

  • Сделайте временное изменение, например, увеличьте емкость инстанса во время всплеска трафика. Посмотрите, как обнаружение дрейфа сработает после того, как всплеск закончится.
  • Измените ресурс, у которого есть зависимости, например, измените конфигурацию load balancer, подключенного к target group. Посмотрите, как план покажет каскадные эффекты.
  • Создайте изменение, которое трудно откатить, например, удалите ресурс, от которого зависят другие. Посмотрите, как Terraform обрабатывает цепочку зависимостей.

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

Практический чек-лист для управления дрейфом

Прежде чем двигаться дальше, вот краткий чек-лист для применения в вашем окружении:

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

Чему учит это упражнение

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

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

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