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

Объединяющим принципом Heat, Ansible и Terraform является рассмотрение определений инфраструктуры как кода, хранящегося в Git (или другой системе контроля версий). В этом суть GitOps: репозиторий Git является «источником истины» для всей среды.

Основные принципы GitOps

  • Git как единственный источник правды: Вся конфигурация инфраструктуры хранится в Git.
  • Декларативное описание: Желаемое состояние системы описывается декларативно.
  • Автоматическое применение: Изменения в Git автоматически синхронизируются с реальной инфраструктурой.
  • Непрерывная сверка: Система постоянно проверяет соответствие реального состояния желаемому.

Преимущества использования Git для инфраструктуры как кода

  1. История изменений: Каждый коммит действует как снимок, поэтому команды могут откатиться к предыдущим версиям, просто отменив коммит или повторно развернув более старый тег.
  2. Контрольный след: Все изменения документируются в логах Git, обеспечивая прозрачность («кто что изменил и когда»).
  3. Коллективная работа: Несколько инженеров могут работать над различными функциями в параллельных ветках, систематически объединять их и выявлять конфликты на ранней стадии.
  4. Проверка кода: Изменения проходят рецензирование через pull/merge requests, как и код приложения.
  5. Воспроизводимость: Инфраструктура становится воспроизводимой, поскольку история Git точно её определяет.
  6. Простота отката: Откат изменений осуществляется переключением на предыдущий коммит.

Ключевые практики GitOps для инфраструктуры

Создание веток и запросы на слияние

Работайте над новыми функциями или исправлениями в ветках, посвященных новым функциям, а затем объединяйте их с основной веткой после одобрения.

# Создание ветки для новой функциональности
git checkout -b feature/new-network-configuration

# Внесение изменений в шаблоны Heat/Terraform/Ansible
git add templates/network.yaml
git commit -m "Add new network configuration for production"

# Отправка изменений и создание merge request
git push origin feature/new-network-configuration

Каждая ветка может представлять собой среду:

  • dev — среда разработки
  • staging — предпроизводственная среда
  • production — производственная среда

IaC как проверка кода

Рассматривайте шаблоны Heat, плейбуки Ansible и файлы Terraform как код приложения, используя единый процесс проверки.

# .gitlab-ci.yml для проверки шаблонов Heat
stages:
  - validate
  - plan
  - apply

validate-heat:
  stage: validate
  script:
    - openstack stack validate -t templates/production.yaml

validate-terraform:
  stage: validate
  script:
    - terraform init
    - terraform validate

validate-ansible:
  stage: validate
  script:
    - ansible-lint playbooks/*.yml

Удаленное хранение состояния и секретов

Файлы состояния (для Terraform) или стеки (для Heat) могут находиться в удаленном бэкенде с системой версий.

# Удаленное состояние Terraform в GitLab
terraform {
  backend "http" {
    address = "https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/terraform/state/${CI_COMMIT_REF_NAME}"
    lock_address = "https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/terraform/state/${CI_COMMIT_REF_NAME}/lock"
    unlock_address = "https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/terraform/state/${CI_COMMIT_REF_NAME}/lock"
  }
}

Хранение секретов в GitLab CI:

variables:
  TF_VAR_os_password: $OS_PASSWORD  # переменная, защищенная в GitLab

Декларативные среды

Содержимое ветки определяет желаемую среду. Основная ветка может отражать производственную топологию, а ветка разработки позволяет тестировать изменения.

Пример структуры репозитория:

infrastructure-repo/
├── environments/
│   ├── dev/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   └── outputs.tf
│   ├── staging/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   └── outputs.tf
│   └── production/
│       ├── main.tf
│       ├── variables.tf
│       └── outputs.tf
├── modules/
│   ├── network/
│   ├── compute/
│   └── storage/
└── playbooks/
    └── ansible/

Автоматизация с помощью CI/CD

Команда git push может запустить конвейер GitLab (или Jenkins/GitHub Actions), который выполняет проверку синтаксиса, линтинг и планирование изменений.

Пример полного конвейера GitLab CI для GitOps

stages:
  - validate
  - plan
  - approve
  - apply

variables:
  TF_ROOT: ${CI_PROJECT_DIR}/environments/${CI_COMMIT_REF_NAME}
  TF_ADDRESS: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/${CI_COMMIT_REF_NAME}

cache:
  key: "${CI_COMMIT_REF_SLUG}"
  paths:
    - ${TF_ROOT}/.terraform

before_script:
  - cd ${TF_ROOT}
  - terraform init -backend-config=address=${TF_ADDRESS}

validate:
  stage: validate
  script:
    - terraform validate
    - tflint

plan:
  stage: plan
  script:
    - terraform plan -out=plan.tfplan
  artifacts:
    paths:
      - ${TF_ROOT}/plan.tfplan

approve:
  stage: approve
  script:
    - echo "Approving changes for ${CI_COMMIT_REF_NAME}"
  only:
    - production
  when: manual
  environment:
    name: production

apply:
  stage: apply
  script:
    - terraform apply plan.tfplan
  dependencies:
    - plan
  only:
    - main
    - production
  when: manual
  environment:
    name: production
  needs:
    - job: approve
      optional: true

Пример для OpenStack Heat

stages:
  - validate
  - deploy

validate-heat:
  stage: validate
  script:
    - openstack stack validate -t ${STACK_TEMPLATE} -e ${ENVIRONMENT_FILE}

deploy-heat:
  stage: deploy
  script:
    - openstack stack create --wait -t ${STACK_TEMPLATE} -e ${ENVIRONMENT_FILE} ${STACK_NAME}
  only:
    - main
  environment:
    name: production/${STACK_NAME}

Пример для Ansible

stages:
  - syntax-check
  - dry-run
  - deploy

syntax-check:
  stage: syntax-check
  script:
    - ansible-playbook --syntax-check playbooks/site.yml

dry-run:
  stage: dry-run
  script:
    - ansible-playbook --check --diff playbooks/site.yml

deploy:
  stage: deploy
  script:
    - ansible-playbook playbooks/site.yml
  only:
    - main
  when: manual

Интеграция с рабочими процессами запросов на слияние

1. Разработчик создает ветку `feature/new-instance-type`
2. Вносит изменения в шаблоны инфраструктуры
3. Создает Merge Request в GitLab
4. CI/CD автоматически запускает `validate` и `plan`
5. Результаты `plan` публикуются в комментариях к MR
6. Команда рецензирует изменения
7. После одобрения MR сливается с основной веткой
8. CI/CD автоматически применяет изменения к production среде

Преимущества внедрения GitOps в OpenStack

  • Единый процесс: Инфраструктура проходит те же процессы проверки, что и код приложения.
  • Прозрачность: Все изменения документированы и отслеживаемы.
  • Безопасность: Изменения проходят рецензирование перед применением.
  • Скорость: Автоматизация ускоряет развертывание.
  • Надежность: Минимизация ручных ошибок.
  • Демократизация: Любой квалифицированный член команды может внести изменения через код.