Удобное руководство по переносу состояния Terraform в GitLab CI/CD

Удобное руководство по переносу состояния Terraform в GitLab CI/CD

22 февраля 2023 г.

Как профессионал в области программного обеспечения, работающий с инфраструктурой как кодом (IaC), скорее всего, вы много работаете с Terraform. Когда вы помогаете новым клиентам использовать IaC, обычно все упрощают, но управление файлом состояния Terraform — это первая проблема, с которой вы сталкиваетесь. По сути, состояние Terraform содержит конфиденциальную информацию, которая не должна храниться в системе управления версиями, но в то же время не будет масштабироваться, если у вас есть несколько пользователей, работающих с одним и тем же состоянием Terraform. Ответ на это? Серверные части.

Важно отметить, что вы можете хранить этот файл состояния в корзине S3 и использовать DynamoDB для управления состоянием блокировки. Однако такой подход заставит вас создавать дополнительные ресурсы, что усложняет вариант, особенно если клиент использует GitLab. GitLab недавно снизил входной барьер для интеграции Terraform, предоставив способ хранения и управления состоянием Terraform, а также простой способ настроить CI вокруг него.

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

Содержание

  • Что такое состояние Terraform?
  • Как заставить GitLab управлять состоянием Terraform
  • Как заставить GitLab запускать ваш IaC через конвейер непрерывной интеграции
  • Дополнительный совет: Infracost
  • Заключение

Что такое Terraform State?

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

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

{
    "version": 4,
    "terraform_version": "0.12.0",
    "serial": 1,
    "lineage": "1f2087f9-4b3c-1b66-65db-8b78faafc6fb",
    "outputs": {},
    "resources": [
      {
        "mode": "managed",
        "type": "aws_instance",
        "name": "example",
        "provider": "provider.aws",
        "instances": [
          {
            "schema_version": 1,
            "attributes": {
              "ami": "ami-0c55b159cbfafe1f0",
              "availability_zone": "us-west-2a",
              "id": "i-00a123a0accffffff",
              "instance_state": "running",
              "instance_type": "t2.micro",
              "(...)": "(truncated)"
            }
          }
        ]
      }
    ]
  }

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

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

Как заставить GitLab управлять состоянием Terraform

Поскольку Terraform считается стандартом для предоставления облачной инфраструктуры, прошел год или около того с тех пор, как GitLab начал предлагать способ хранения и управления вашим состоянием Terraform. По этой причине мы хотели поделиться с вами процессом миграции, так как недавно начали использовать GitLab для управления нашим IaC.

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

Во-первых, вам необходимо изменить файл backend.tf для использования HTTP.

terraform {
  backend "http" {}
}

Далее вам нужно будет настроить 4 переменные в вашем терминале:

  • PROJECT_ID: его легко найти, перейдя к своему репозиторию на странице обзора проекта.

Terraform project backend

  • TF_USERNAME: имя пользователя Gitlab, у которого есть доступ к репозиторию, над которым вы работаете.
  • TF_PASSWORD: токен доступа, сгенерированный вашим пользователем GitLab.
  • TF_ADDRESS: URL серверной части удаленного состояния

PROJECT_ID="28450092"
TF_USERNAME="florianpialoux"
TF_PASSWORD="123456789"
TF_ADDRESS="https://gitlab.com/api/v4/projects/${PROJECT_ID}/terraform/state/aws-buckets"

Теперь вы можете запустить команду миграции, которая переместит ваше состояние Terraform из его предыдущего местоположения в GitLab с помощью следующей команды:

terraform init 
  -migrate-state 
  -backend-config=address=${TF_ADDRESS} 
  -backend-config=lock_address=${TF_ADDRESS}/lock 
  -backend-config=unlock_address=${TF_ADDRESS}/lock 
  -backend-config=username=${TF_USERNAME} 
  -backend-config=password=${TF_PASSWORD} 
  -backend-config=lock_method=POST 
  -backend-config=unlock_method=DELETE 
  -backend-config=retry_wait_min=5

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

Terraform local state example

Пример s3 для GitLab

S3 to Gitlab Migrate State Example

Теперь вы можете перейти в раздел Инфраструктура > Terraform из интерфейса GitLab и посмотрите свое состояние:

Gitlab Infrastructure Interface

Я заметил, что некоторые из файлов состояния, которые у меня были с s3, будут пустыми даже после использования ранее запущенной команды migrate-state, в этом случае вы можете запустить это:

terraform state pull > aws-buckets.json

Скопируйте и вставьте содержимое из состояния s3 и запустите push:

terraform state push -lock=true aws-buckets.json

GitLab поддерживает управление версиями для вашего файла состояния Terraform, но для просмотра/восстановления старых версий через веб-интерфейс вам потребуется план GitLab Premium<. /а>. Если нет, вам потребуется сделать запрос API GraphQL.

Как заставить GitLab запускать ваш IaC через конвейер непрерывной интеграции

GitLab предоставляет образ Docker, содержащий GitLab-Terraform, который является тонкий скрипт-обертка вокруг официального бинарного файла Terraform. В качестве альтернативы вы можете использовать официальный образ Docker от Hashicorp. Дополнительную информацию об образе Terraform GitLab можно найти здесь.

После запуска задания terraform apply вы сможете увидеть, когда использовалось состояние и с каким конвейером.

terraform apply job in gitlab interface

Подробнее о том, как выглядит наш gitlab-ci.yml здесь. Ниже приведены переменные, которые необходимо определить на уровне проекта:

GitLab-ci.yml project variables

Дополнительный совет: Infracost

Как вы могли заметить, глядя на наш gitlab-ci.yaml, мы добавили Infracost, что позволяет нам, чтобы иметь больший контроль над нашим облачным биллингом, поскольку он дает вам оценку стоимости всякий раз, когда вы определяете новый ресурс для своего IaC. Чтобы узнать больше об Infracost, вы можете прочитать нашу подробную статью о том, что это влечет за собой, и наше пошаговое руководство о том, как интегрировать его с Terraform.

Заключение

Выполнение состояния Terraform и непрерывной интеграции в Gitlab — отличный способ следовать рекомендациям GitOps. Оба они отлично подходят для разработки и развертывания IaC. Поскольку большинство из вас, возможно, уже используют GitLab для своих репозиториев, становится намного проще разместить IaC под одной крышей и позволить GitLab управлять вашим состоянием Terraform, поддерживая шифрование при передаче и хранении, а также управление версиями, блокировку и разблокировку состояние.

:::информация Также опубликовано здесь.

:::


Оригинал