К сожалению, Terraform не предназначен для такого случая использования, когда вам нужно только создавать новые вещи, а затем оставлять их для управления в другом месте. Вместо этого модель Terraform - это управление долгоживущими объектами, когда вам может потребоваться вносить в них изменения с течением времени, еще находясь в Terraform.
Внутренне Terraform связывает каждый экземпляр ресурса, объявленный в вашей конфигурации, с удаленным объектом в поставщике. удаленный API. В вашем случае каждый из vsphere_virtual_machine.test_vm
экземпляров (которые Terraform вызывает vsphere_virtual_machine.small_vm[0]
, vsphere_virtual_machine.small_vm[1]
, et c в зависимости от вашего значения count
) связан с одной реальной виртуальной машиной в vSphere, и когда вы позже внесите изменения в конфигурацию. Terraform планирует обновить или заменить удаленные объекты, чтобы удаленная система соответствовала изменениям в конфигурации.
Я думаю, что наиболее близкий образец использования, которого вы хотите достичь, определить входную переменную, которая представляет собой карту описаний виртуальных машин, которые должны существовать, например:
variable "virtual_machines" {
type = map(object({
num_cpus = number
}))
default = {
tests01 = {
num_cpus = 2
}
testm01 = {
num_cpus = 1
}
}
}
Я включил этот атрибут num_cpus
в объекты только для иллюстрации того, как вы можете определить атрибуты для представления значений, отличных от имени, которые могут потребоваться для разных виртуальных машин. (Если вам не нужно, чтобы эти виртуальные машины отличались каким-либо образом , кроме их имен, вы можете установить тип на map(object({}))
, чтобы использовать пустые объекты на данный момент, поэтому у вас есть место для расширения позже .)
С этой переменной вы можете использовать for_each
вместо count
, чтобы сказать Terraform, что нужно создать один экземпляр виртуальной машины для каждого элемента в карте var.virtual_machines
:
resource "vsphere_virtual_machine" "test_vms" {
for_each = var.virtual_machines
name = each.key
resource_pool_id = data.vsphere_compute_cluster.cluster.resource_pool_id
datastore_id = data.vsphere_datastore.datastore.id
num_cpus = each.value.num_cpus
memory = var.memory
guest_id = "ubuntu64Guest"
folder = var.vmfolder
cpu_hot_add_enabled = var.cpu_hot_add_enabled
memory_hot_add_enabled = var.memory_hot_add_enabled
scsi_type = data.vsphere_virtual_machine.template.scsi_type
wait_for_guest_net_timeout = -1
network_interface {
network_id = data.vsphere_network.network[1].id
adapter_type = data.vsphere_virtual_machine.template.network_interface_types[0]
}
disk {
label = "disk0"
size = var.disk_size
thin_provisioned = data.vsphere_virtual_machine.template.disks[0].thin_provisioned
}
clone {
template_uuid = data.vsphere_virtual_machine.template.id
customize {
dns_server_list = var.dns_server_list
dns_suffix_list = var.dns_suffix_list
ipv4_gateway = var.gateway_app
linux_options {
host_name = each.key
domain = var.vmdomain
}
network_interface {
ipv4_address = "${var.ips_test}${var.test_index + count.index}"
ipv4_netmask = var.netmask_app
}
}
}
}
Внутри блока resource "vsphere_virtual_machine" "test_vms"
я использовал each.key
для доступа к каждому ключу из var.virtual_machines
(в данном случае имен виртуальных машин) и each.value
для доступа к соответствующему объекту, который содержит атрибут num_cpus
.
Учитывая значение по умолчанию var.virtual_machines
, которое я объявил выше, Terraform будет интерпретировать это как запрос на создание двух виртуальных машин со следующими адресами отслеживания:
vsphere_virtual_machine.test_vms["tests01"]
(с двумя ЦП) vsphere_virtual_machine.test_vms["testm01"]
(с одним ЦП)
Обратите внимание, что Terraform использует ключи с карты для отслеживания каждого отдельного экземпляра этого ресурса. Если вы хотите добавить новую виртуальную машину, не мешая другим, вы можете добавить новую запись к значению var.virtual_machines
, , оставив все существующие элементы в покое . Каждый раз, когда вы добавляете новый элемент на эту карту и снова запускаете terraform apply
, Terraform планирует создать новый экземпляр виртуальной машины. Аналогичным образом, если вы удалите или отредактируете запись в этой карте, Terraform планирует уничтожить или обновить / заменить соответствующую виртуальную машину.
Для проблемы сред , в частности, вместо отдельных виртуальных машин обратите внимание, что обычно лучше создать отдельную конфигурацию Terraform для каждой среды, чтобы вы могли обновлять каждую отдельно и не рисковать обновлениями одной, внося непреднамеренные изменения в другую.
Общий подход для этого использовать конфигурацию, которую вы уже написали как общий модуль , и затем для каждой новой среды, которую вы хотите создать, вы можете написать небольшую новую конфигурацию, которая содержит только один вызов этого модуля с настройками которые применяются к этой указанной c среде:
module "environment1" {
# This is a relative path to whatever directory contains
# the module whose configuration we've been discussing so far.
source = "../../modules/environment"
virtual_machines = {
env1foo = {
num_cpus = 2
}
env1bar = {
num_cpus = 2
}
}
vmfolder = "example"
cpu_hot_add_enabled = false
# (and so on, for all of the other environment-specific variables
# you need to override)
}
Каждый отдельный модуль Terraform является отдельным каталогом, поэтому вы можете сформировать структуру каталогов примерно так, например:
- environments/
- environment1/
- environment.tf
- environment2/
- environment.tf
- modules
- environment
- variables.tf
- main.tf
- (etc)
Чтобы создать новую среду, вы должны сделать новый подкаталог environments
и запишите туда новый environment.tf
, затем переключитесь в этот каталог и запустите Terraform:
cd environments/environment1
terraform init
terraform apply
Terraform отслеживает объекты для каждой конфигурации отдельно в отдельном состоянии снимок, поэтому, имея отдельный каталог конфигурации для каждого, вы можете работать с каждой средой отдельно, не привлекая конфигурацию от других. Однако каждый из них будет использовать один и тот же модуль «среда», и поэтому все они будут построены из одного определения, и вы можете обновить этот общий модуль «среда» в любое время, когда захотите внести изменения, которые должны применяться ко всем ваше окружение.