有一个问题,我需要部署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"
]
}
]
}
答案 0 :(得分:4)
我经常使用 Terraform 中的字符串列表和对象列表。这总是让我头疼。因此,我确定了两种最常见的模式,即字符串列表和对象列表。对于字符串列表,您始终可以使用 toset()
并使用 for_each
对其进行循环。处理对象列表时,您需要将其转换为键为唯一值的映射。对于唯一值,您可以使用索引、散列或列表中所有对象的唯一值。
字符串列表:
locals {
ip_addresses = ["10.0.0.1", "10.0.0.2"]
}
resource "example" "example" {
for_each = toset(local.ip_addresses)
ip_address = each.key
}
对象列表:
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
}
答案 1 :(得分:1)
使用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"
}
}
Terraform计划输出:
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.
答案 2 :(得分:1)
好像我找到了要做什么。如果您不传递地图,而是传递地图列表,则可以使用此类代码
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)}"
}
}
它将创建实例的实际数量,例如,当您删除三个中间的一个(如果创建三个:)时,terraform将删除我们要求的内容。
答案 3 :(得分:1)
您可以执行以下操作:
let response = await fetch(baseUrl + '/aaa/nom-de-levenement/add', {
method: 'POST',
headers: {
'X-CSRF-TOKEN': token,
"Content-type": "application/json",
},
body: {
"page": "pageName"
}
})
return response.json()
假设您具有以下条件:
/**
* @Route("/add", methods={"POST"})
*/
public function createPage($slug, EntityManagerInterface $entityManager, EventRepository $eventRepository, Request $request){
$event = $eventRepository->findOneBy(['slug' => $slug]);
$data = $request->request->get('page');
dd($data);
}
答案 4 :(得分:0)
从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)
}))
}
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
}
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"]
},
}
}
当然,您可以根据需要添加任意多个变量,然后在模块中使用它们。