Многооблачное развертывание с помощью Terraform

В то время как Heat и Ansible ориентированы на OpenStack, Terraform предоставляет облачно-независимый подход IaC, который может быть нацелен на OpenStack и другие облака в рамках одной и той же структуры.

Основные возможности Terraform

Terraform использует язык конфигурации HashiCorp (HCL) для объявления ресурсов и модель «провайдера» на основе плагинов. Провайдер Terraform для OpenStack реализует такие ресурсы, как openstack_compute_instance_v2, openstack_networking_network_v2 и другие, что позволяет программировать развертывания OpenStack.

Примечание

Модель выполнения Terraform (plan и apply) делает упор на прозрачность: команда terraform plan точно показывает, что будет создано, изменено или уничтожено, а terraform apply выполняет эти изменения.

Настройка провайдера OpenStack

provider "openstack" {
  cloud = "my_openstack"
}

Где clouds.yaml (или переменные окружения) содержат информацию для аутентификации для my_openstack.

Пример создания ресурсов в OpenStack

# Создание сети
resource "openstack_networking_network_v2" "network" {
  name           = "terraform-network"
  admin_state_up = "true"
}

# Создание подсети
resource "openstack_networking_subnet_v2" "subnet" {
  name       = "terraform-subnet"
  network_id = openstack_networking_network_v2.network.id
  cidr       = "192.168.10.0/24"
  ip_version = 4
}

# Создание виртуальной машины
resource "openstack_compute_instance_v2" "instance" {
  name       = "terraform-instance"
  image_name = "Ubuntu-22.04"
  flavor_name = "m1.medium"
  network {
    uuid = openstack_networking_network_v2.network.id
  }
}

Управление состоянием

Состояние Terraform хранится в JSON-файле (terraform.tfstate), который команды обычно хранят удаленно в бэкенде для совместной работы.

terraform {
  backend "s3" {
    bucket = "my-terraform-state"
    key    = "openstack/terraform.tfstate"
    region = "us-east-1"
  }
}

# Альтернативный бэкенд - GitLab
terraform {
  backend "http" {
    address = "https://gitlab.com/api/v4/projects/123/terraform/state/my-state"
    lock_address = "https://gitlab.com/api/v4/projects/123/terraform/state/my-state/lock"
    unlock_address = "https://gitlab.com/api/v4/projects/123/terraform/state/my-state/lock"
  }
}

Модули Terraform

Ключевой особенностью Terraform являются модули — многократно используемые, совместно используемые пакеты кода Terraform.

module "web_app" {
  source = "github.com/example/terraform-openstack-modules//web-app"
  version = "1.2.0"

  instance_count = 3
  flavor_name    = "m1.medium"
  image_name     = "Ubuntu-22.04"
  network_name   = "private-net"
  security_groups = ["web", "ssh"]
}

Для OpenStack существует множество модулей от сообщества для:

  • загрузки образов Glance
  • создания пар ключей
  • определения типов образов
  • создания сетей и групп безопасности
  • развертывания многовиртуальных экземпляров с подключенными томами Cinder

Пример модуля для загрузки образа в Glance

module "ubuntu_image" {
  source = "terraform-openstack-modules/glance-image/local"

  image_name  = "Ubuntu-22.04"
  image_file  = "/path/to/ubuntu-22.04.qcow2"
  visibility  = "public"
  disk_format = "qcow2"
  min_disk    = 10
  min_ram     = 2048
}

Многооблачное развертывание

Terraform по своей сути является мультиоблачным инструментом. Вы можете использовать несколько блоков провайдеров в одной конфигурации для одновременного развертывания ресурсов AWS, Azure и OpenStack.

# Провайдер для OpenStack (основной регион)
provider "openstack" {
  alias = "region1"
  cloud = "openstack-region1"
}

# Провайдер для OpenStack (второй регион)
provider "openstack" {
  alias = "region2"
  cloud = "openstack-region2"
}

# Провайдер для AWS
provider "aws" {
  alias  = "aws"
  region = "us-west-2"
}

# Ресурсы в первом регионе OpenStack
resource "openstack_compute_instance_v2" "app_region1" {
  provider   = openstack.region1
  name       = "app-region1"
  image_name = "Ubuntu-22.04"
  flavor_name = "m1.medium"
}

# Ресурсы во втором регионе OpenStack
resource "openstack_compute_instance_v2" "app_region2" {
  provider   = openstack.region2
  name       = "app-region2"
  image_name = "Ubuntu-22.04"
  flavor_name = "m1.medium"
}

# Ресурсы в AWS
resource "aws_s3_bucket" "storage" {
  provider = aws.aws
  bucket   = "my-app-storage-bucket"
}

Гибридные сценарии

Terraform удобен в гибридных сценариях, где, например, приложение работает на виртуальных машинах в OpenStack, а хранилище — в AWS S3.

# Виртуальная машина в OpenStack
resource "openstack_compute_instance_v2" "app_server" {
  name       = "app-server"
  image_name = "Ubuntu-22.04"
  flavor_name = "m1.large"

  user_data = <<-EOF
             #!/bin/bash
             echo "Access key: ${aws_s3_bucket.app_storage.bucket}" > /home/ubuntu/config
             EOF
}

# S3 бакет в AWS для хранения данных
resource "aws_s3_bucket" "app_storage" {
  bucket = "my-app-data-${random_id.suffix.hex}"
  acl    = "private"
}

resource "random_id" "suffix" {
  byte_length = 4
}

Интеграция с CI/CD и GitOps

Terraform обладает функциями, дополняющими GitOps. Удаленное состояние в GitLab или Terraform Cloud обеспечивает блокировку и совместную работу команд.

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

stages:
  - validate
  - plan
  - apply

variables:
  TF_ROOT: ${CI_PROJECT_DIR}
  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

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

apply:
  stage: apply
  script:
    - terraform apply plan.tfplan
  dependencies:
    - plan
  only:
    - main
  when: manual

Преимущества использования Terraform для многооблачного развертывания

  1. Единый инструмент: Управление ресурсами в разных облаках с помощью одного синтаксиса и рабочего процесса.
  2. Прозрачность: Планирование изменений перед применением.
  3. Модульность: Повторное использование кода через модули.
  4. Управление состоянием: Отслеживание созданных ресурсов и их зависимостей.
  5. Интеграция с GitOps: Возможность автоматического развертывания из репозиториев.
  6. Расширяемость: Большое количество провайдеров и модулей от сообщества.