Terraform + vCenter: Полная автоматизация развёртывания VM

From wiki.baghirzade.pro
Revision as of 09:52, 21 October 2025 by Sadmin (talk | contribs)
Jump to navigation Jump to search

Введение

Мне нужно было автоматизировать создание виртуальных машин в VMware vSphere, чтобы не клонировать их вручную через vCenter каждый раз. Я решил использовать Terraform, чтобы одной командой создавать сразу несколько ВМ с нужным именем, статическим IP, hostname и готовой инфраструктурой для будущих кластеров (PostgreSQL, Docker, Kubernetes и т. д.).

Моя цель: с нуля поднять окружение (vCenter → Template → Terraform) и в итоге автоматически получать, например, ubuntu-node1..3 с готовой сетью и именами.

Подготовка vCenter и инфраструктуры

  1. Я установил vCenter.
  2. Создал Datacenter.
  3. Создал Cluster.
  4. Перетащил ESXi внутрь Cluster.
  5. Включил DRS (иначе Terraform не видел resource pool, ошибка spec.pool). Именно Cluster нужен Terraform, потому что он работает не с host-level пулом, а с resource pool на уровне кластера.

Подготовка шаблона Ubuntu (template)

  1. Установил Ubuntu 22.04 вручную.
  2. Установил open-vm-tools (обязательно, иначе customization не работает):
sudo apt update
sudo apt install -y open-vm-tools
sudo systemctl enable --now open-vm-tools

3. Погасил VM (Power Off).

4. Превратил её в Template.

Создание каталога Terraform

На машине, с которой работаю:

mkdir terraform-vcenter
cd terraform-vcenter

provider.tf

terraform {

 required_providers {
   vsphere = {
     source  = "hashicorp/vsphere"
     version = "2.5.0"
   }
 }

}

provider "vsphere" {

 vsphere_server       = var.vcenter
 user                 = var.vcenter_user
 password             = var.vcenter_password
 allow_unverified_ssl = true

}

variables.tf

variable "vcenter" { default = "10.10.70.9" } variable "vcenter_user" { default = "[email protected]" } variable "vcenter_password" { default = "PASTE_YOUR_PASSWORD_HERE" }

variable "datacenter" { default = "Datacenter" } variable "cluster" { default = "Cluster" } variable "datastore" { default = "datastore1" } variable "network" { default = "VM Network" }

variable "template" { default = "ubuntu-template" }

variable "vm_count" { default = 3 } variable "ip_start" { default = 50 }

variable "gateway" { default = "10.10.70.1" } variable "dns_server" { default = "8.8.8.8" } variable "netmask_prefix" { default = 24 }

main.tf (рабочий, финальный, автоматизация 3 VM с hostname + static IP)

locals {

 base_ip = "10.10.70"

}

data "vsphere_datacenter" "dc" {

 name = var.datacenter

}

data "vsphere_compute_cluster" "cluster" {

 name          = var.cluster
 datacenter_id = data.vsphere_datacenter.dc.id

}

data "vsphere_datastore" "datastore" {

 name          = var.datastore
 datacenter_id = data.vsphere_datacenter.dc.id

}

data "vsphere_network" "network" {

 name          = var.network
 datacenter_id = data.vsphere_datacenter.dc.id

}

data "vsphere_virtual_machine" "template" {

 name          = var.template
 datacenter_id = data.vsphere_datacenter.dc.id

}

resource "vsphere_virtual_machine" "vm" {

 count            = var.vm_count
 name             = "ubuntu-node${count.index + 1}"
 resource_pool_id = data.vsphere_compute_cluster.cluster.resource_pool_id
 datastore_id     = data.vsphere_datastore.datastore.id
 num_cpus  = 2
 memory    = 2048
 guest_id  = "ubuntu64Guest"
 scsi_type = "pvscsi"
 network_interface {
   network_id   = data.vsphere_network.network.id
   adapter_type = "vmxnet3"
 }
 disk {
   label            = "disk0"
   size             = 16
   thin_provisioned = true
 }
 clone {
   template_uuid = data.vsphere_virtual_machine.template.id
   customize {
     linux_options {
       host_name = "ubuntu-node${count.index + 1}"
       domain    = "local"
     }
     network_interface {
       ipv4_address = "${local.base_ip}.${var.ip_start + count.index}"
       ipv4_netmask = var.netmask_prefix
     }
     ipv4_gateway     = var.gateway
     dns_server_list  = [var.dns_server]
   }
 }

}

Deploy

terraform init terraform plan terraform apply

В результате у меня создаются три VM:

ubuntu-node1 → 10.10.70.50

ubuntu-node2 → 10.10.70.51

ubuntu-node3 → 10.10.70.52

Как увеличить количество машин

Открываю variables.tf и меняю:

variable "vm_count" { default = 5 }

Как изменить имя VM В main.tf:

name = "ubuntu-node${count.index + 1}"

Меняю, например, на:

name = "db-node${count.index + 1}"

Как изменить IP диапазон В variables.tf:

ip_start = 100

или меняю base_ip в main.tf, если другая сеть.

Важно помнить

  1. Шаблон всегда должен быть Powered Off.
  2. В шаблоне должны быть open-vm-tools.
  3. ESXi должен быть внутри Cluster.
  4. Без DRS будет ошибка spec.pool.
  5. customization не применится, если нет open-vm-tools.

На будущее (Ansible)

Следующим шагом я могу добавить auto-provision:

  • установка Docker
  • установка Kubernetes
  • установка Zabbix agent
  • установка PostgreSQL
  • выкатывание конфигов

Делается так:

terraform apply
ansible-playbook site.yml -i inventory.ini

Теперь у меня есть полностью рабочая автоматизация vSphere с Terraform.

В любой момент я могу развернуть кластер за пару минут вместо ручного клонирования VM.