Как развернуть инфраструктуру на нескольких виртуальных машинах?

«Как развернуть инфраструктуру на нескольких виртуальных машинах?» — вопрос из категории Виртуализация, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Я подхожу к этому, используя принципы Infrastructure as Code (IaC) и конфигурационного менеджмента. Мой типичный стек для такой задачи: Terraform для provisioning (создания) виртуальных машин и Ansible для их последующей конфигурации.

1. Provisioning с помощью Terraform (пример для Yandex Cloud) Terraform позволяет декларативно описать всю инфраструктуру и создать идентичные ВМ в разных зонах.

# main.tf
provider "yandex" {
  token     = var.yc_token
  cloud_id  = var.yc_cloud_id
  folder_id = var.yc_folder_id
  zone      = "ru-central1-a"
}

resource "yandex_compute_instance" "app_vm" {
  count = 3  # Создаем 3 идентичные ВМ

  name        = "app-vm-${count.index + 1}"
  platform_id = "standard-v3"
  zone        = element(["ru-central1-a", "ru-central1-b", "ru-central1-c"], count.index)

  resources {
    cores  = 2
    memory = 4
  }

  boot_disk {
    initialize_params {
      image_id = "fd8vmcue7aajpmeo39kk" # Ubuntu 22.04
      size     = 20
    }
  }

  network_interface {
    subnet_id = yandex_vpc_subnet.app_subnet.id
    nat       = true
  }

  metadata = {
    ssh-keys = "ubuntu:${file("~/.ssh/id_rsa.pub")}"
  }
}

# Создаем динамический инвентарь для Ansible
output "vm_ips" {
  value = {
    for vm in yandex_compute_instance.app_vm :
    vm.name => vm.network_interface.0.nat_ip_address
  }
}

После terraform apply мы получаем три ВМ в трех разных зонах с публичными IP-адресами.

2. Конфигурация с помощью Ansible Используем вывод Terraform как динамический инвентарь или создаем статический файл.

# playbook.yml
- name: Configure application servers
  hosts: all
  become: yes
  tasks:
    - name: Update apt cache
      apt:
        update_cache: yes
        cache_valid_time: 3600

    - name: Install Nginx and Node.js
      apt:
        name:
          - nginx
          - nodejs
          - npm
        state: present

    - name: Deploy application code
      copy:
        src: ../app/
        dest: /opt/myapp/

    - name: Start application service
      systemd:
        name: myapp
        enabled: yes
        state: started

Запускаем конфигурацию: ansible-playbook -i inventory.ini playbook.yml.

Дополнительные инструменты и практики:

  • Packer: Для создания предварительно настроенных образов ВМ (Golden Images), что ускоряет развертывание.
  • CI/CD (GitLab CI, Jenkins): Для автоматизации всего пайплайна: запуск terraform plan на MR, apply на мерже, затем запуск Ansible.
  • Мониторинг: После развертывания сразу настраиваю сбор метрик (Prometheus node_exporter) и логов (Fluentd/Vector).
  • Для локальной разработки/тестирования: Использую Vagrant с мульти-машинной конфигурацией для эмуляции среды на VirtualBox или Libvirt.