The*_*707 43 foreach loops list object terraform
我需要部署 GCP 计算实例列表。我如何通过像这样的对象列表中的“vms”循环 for_each:
"gcp_zone": "us-central1-a",
"image_name": "centos-cloud/centos-7",
"vms": [
{
"hostname": "test1-srfe",
"cpu": 1,
"ram": 4,
"hdd": 15,
"log_drive": 300,
"template": "Template-New",
"service_types": [
"sql",
"db01",
"db02"
]
},
{
"hostname": "test1-second",
"cpu": 1,
"ram": 4,
"hdd": 15,
"template": "APPs-Template",
"service_types": [
"configs"
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
The*_*707 47
好像我找到了该怎么做。如果你传递的不是地图的地图而是地图列表,你可以使用这样的代码
resource "google_compute_instance" "node" {
for_each = {for vm in var.vms: vm.hostname => vm}
name = "${each.value.hostname}"
machine_type = "custom-${each.value.cpu}-${each.value.ram*1024}"
zone = "${var.gcp_zone}"
boot_disk {
initialize_params {
image = "${var.image_name}"
size = "${each.value.hdd}"
}
}
network_interface {
network = "${var.network}"
}
metadata = {
env_id = "${var.env_id}"
service_types = "${join(",",each.value.service_types)}"
}
}
Run Code Online (Sandbox Code Playgroud)
它将创建实际数量的实例,当您删除例如三个中的一个(如果您创建三个:))时,terraform 将删除我们要求的内容。
Tam*_*ász 24
从 Terraform 0.12 开始,您可以将 for_each 与如下模块一起使用:
variable "hosts" {
type = map(object({
hostname = string
cpu = number
ram = number
hdd = number
log_drive = number
template = string
service_types = list(string)
}))
}
Run Code Online (Sandbox Code Playgroud)
resource "google_compute_instance" "gcp_instance" {
for_each = var.hosts
hostname = each.value.repository_name
cpu = each.value.cpu
ram = each.value.ram
hdd = each.value.hdd
log_drive = each.value.log_drive
template = each.value.template
service_types = each.value.service_types
}
Run Code Online (Sandbox Code Playgroud)
module "gcp_instances" {
source = ./modules/google_compute_instance"
hosts = {
"test1-srfe" = {
hostname = "test1-srfe",
cpu = 1,
ram = 4,
hdd = 15,
log_drive = 300,
template = "Template-New",
service_types = ["sql", "db01", "db02"]
},
"test1-second" = {
hostname = "test1-second",
cpu = 1,
ram = 4,
hdd = 15,
log_drive = 300,
template = "APPs-Template",
service_types = ["configs"]
},
}
}
Run Code Online (Sandbox Code Playgroud)
当然,您可以根据需要添加任意数量的变量并在模块中使用它们。
Neb*_*tic 11
我经常使用 Terraform 中的迭代器。这总是让我头疼。因此,我确定了两种最常见的模式,即字符串列表和对象列表。对于字符串,你可以随时使用的列表toset()和循环遍历它for_each。处理对象列表时,您需要将其转换为键为唯一值的映射。对于唯一键,您可以在列表中的所有对象中使用索引、散列或仅使用唯一值。另一种方法是在您的 terraform 配置中放置一张地图。就个人而言,我认为在您的配置中使用对象列表而不是地图看起来更简洁。除了标识地图中的不同项目外,密钥通常没有其他用途,因此可以动态构建。
字符串列表:
locals {
ip_addresses = ["10.0.0.1", "10.0.0.2"]
}
resource "example" "example" {
for_each = toset(local.ip_addresses)
ip_address = each.key
}
Run Code Online (Sandbox Code Playgroud)
对象列表:
locals {
virtual_machines = [
{
ip_address = "10.0.0.1"
name = "vm-1"
},
{
ip_address = "10.0.0.1"
name = "vm-1"
}
]
}
resource "example" "example" {
for_each = {
for index, vm in local.virtual_machines:
index => vm
# OR: vm.name => vm (not always unique if names are the same)
# OR: sha1(vm.name) vm => (not always unique if names are the same)
# NOT: uuid() => vm (gets recreated everytime)
}
name = each.value.name
ip_address = each.value.ip_address
}
Run Code Online (Sandbox Code Playgroud)
您可以执行以下操作:
for_each = toset(keys({for i, r in var.vms: i => r}))
cpu = var.vms[each.value]["cpu"]
Run Code Online (Sandbox Code Playgroud)
假设您有以下情况:
variable "vms" {
type = list(object({
hostname = string
cpu = number
ram = number
hdd = number
log_drive = number
template = string
service_types = list(string)
}))
default = [
{
cpu: 1
...
}
]
}
Run Code Online (Sandbox Code Playgroud)
使用这个for_each块是很新的,而且没有太多的文档。一些最好的信息来自他们的公告博客文章:https : //www.hashicorp.com/blog/hashicorp-terraform-0-12-preview-for-and-for-each/
还要确保查看其文档的动态块部分:https : //www.terraform.io/docs/configuration/expressions.html#dynamic-blocks
从您的示例看起来,您需要为每个创建的实例设置一组值,以便您拥有一张地图:
下面是我使用 Terraform 0.12.12 创建的示例:
variable "hostnames" {
default = {
"one" = {
"name" = "one",
"machine" = "n1-standard-1",
"os" = "projects/coreos-cloud/global/images/coreos-stable-2247-5-0-v20191016",
"zone" = "us-central1-a"
},
"two" = {
"name" = "two",
"machine" = "n1-standard-2",
"os" = "projects/centos-cloud/global/images/centos-8-v20191018",
"zone" = "us-central1-b"
}
}
}
resource "google_compute_instance" "default" {
for_each = var.hostnames
name = each.value.name
machine_type = each.value.machine
zone = each.value.zone
boot_disk {
initialize_params {
image = each.value.os
}
}
scratch_disk {
}
network_interface {
network = "default"
}
}
Run Code Online (Sandbox Code Playgroud)
地形计划输出:
Terraform will perform the following actions:
# google_compute_instance.default["one"] will be created
+ resource "google_compute_instance" "default" {
+ can_ip_forward = false
+ cpu_platform = (known after apply)
+ deletion_protection = false
+ guest_accelerator = (known after apply)
+ id = (known after apply)
+ instance_id = (known after apply)
+ label_fingerprint = (known after apply)
+ machine_type = "n1-standard-1"
+ metadata_fingerprint = (known after apply)
+ name = "one"
+ project = (known after apply)
+ self_link = (known after apply)
+ tags_fingerprint = (known after apply)
+ zone = "us-central1-a"
+ boot_disk {
+ auto_delete = true
+ device_name = (known after apply)
+ disk_encryption_key_sha256 = (known after apply)
+ kms_key_self_link = (known after apply)
+ mode = "READ_WRITE"
+ source = (known after apply)
+ initialize_params {
+ image = "projects/coreos-cloud/global/images/coreos-stable-2247-5-0-v20191016"
+ labels = (known after apply)
+ size = (known after apply)
+ type = (known after apply)
}
}
+ network_interface {
+ address = (known after apply)
+ name = (known after apply)
+ network = "default"
+ network_ip = (known after apply)
+ subnetwork = (known after apply)
+ subnetwork_project = (known after apply)
}
+ scheduling {
+ automatic_restart = (known after apply)
+ on_host_maintenance = (known after apply)
+ preemptible = (known after apply)
+ node_affinities {
+ key = (known after apply)
+ operator = (known after apply)
+ values = (known after apply)
}
}
+ scratch_disk {
+ interface = "SCSI"
}
}
# google_compute_instance.default["two"] will be created
+ resource "google_compute_instance" "default" {
+ can_ip_forward = false
+ cpu_platform = (known after apply)
+ deletion_protection = false
+ guest_accelerator = (known after apply)
+ id = (known after apply)
+ instance_id = (known after apply)
+ label_fingerprint = (known after apply)
+ machine_type = "n1-standard-2"
+ metadata_fingerprint = (known after apply)
+ name = "two"
+ project = (known after apply)
+ self_link = (known after apply)
+ tags_fingerprint = (known after apply)
+ zone = "us-central1-b"
+ boot_disk {
+ auto_delete = true
+ device_name = (known after apply)
+ disk_encryption_key_sha256 = (known after apply)
+ kms_key_self_link = (known after apply)
+ mode = "READ_WRITE"
+ source = (known after apply)
+ initialize_params {
+ image = "projects/centos-cloud/global/images/centos-8-v20191018"
+ labels = (known after apply)
+ size = (known after apply)
+ type = (known after apply)
}
}
+ network_interface {
+ address = (known after apply)
+ name = (known after apply)
+ network = "default"
+ network_ip = (known after apply)
+ subnetwork = (known after apply)
+ subnetwork_project = (known after apply)
}
+ scheduling {
+ automatic_restart = (known after apply)
+ on_host_maintenance = (known after apply)
+ preemptible = (known after apply)
+ node_affinities {
+ key = (known after apply)
+ operator = (known after apply)
+ values = (known after apply)
}
}
+ scratch_disk {
+ interface = "SCSI"
}
}
Plan: 2 to add, 0 to change, 0 to destroy.
Run Code Online (Sandbox Code Playgroud)