Cách for_each máng một danh sách (đối tượng) trong Terraform 0.12


10

Có một câu hỏi, tôi cần triển khai một danh sách các thể hiện tính toán GCP, làm thế nào để tôi lặp for_each thông qua "vms" trong danh sách các đối tượng như thế này

    "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"
        ]
      }
    ]    
}

Terraform sử dụng một ngôn ngữ khai báo, do đó không có if, forhoặc whilebáo cáo. Bạn có thể mô phỏng những điều này, tuy nhiên, ở một mức độ nào đó, trong một số trường hợp nhờ vào counttài sản. Đọc bài viết tuyệt vời này về cách tái tạo các điều kiện hoặc vòng lặp với Terraform : blog.gruntwork.io/iêu
arvymet

Bắt đầu trong tài nguyên Terraform 0.12.6 có thể sử dụng for_eachcác khối: 0.12.6 Changelog . Để biết giá trị của nó, nếu / các điều kiện khác đã có trong Terraform cho một vài phiên bản bây giờ: Tài liệu về định dạng: Biểu thức có điều kiện
Carlo Mencarelli

Câu trả lời:


4

Có vẻ như tôi đã tìm thấy phải làm gì. Nếu bạn vượt qua không phải bản đồ bản đồ mà là danh sách bản đồ bạn có thể sử dụng mã đó

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)}"
  }
}

Nó sẽ tạo ra số lượng thực tế và khi bạn xóa ví dụ ở giữa một trong ba (nếu bạn tạo ba :)), terraform sẽ xóa những gì chúng tôi yêu cầu.


Điều này hoạt động tốt. Danh sách (đối tượng)) được chuyển đổi thành bản đồ có thể được sử dụng làm giá trị for_each. Chỉ cần chọn một khóa (ví dụ: tên máy chủ) là duy nhất
svinther

4

Từ Terraform 0.12, bạn có thể sử dụng for_each với các mô-đun như sau:

mô-đun / google_compute_instance / biến.tf

variable "hosts" {
    type = map(object({
        hostname        = string
        cpu             = number
        ram             = number
        hdd             = number
        log_drive       = number
        template        = string 
        service_types   = list(string)
      }))
    }

mô-đun / google_compute_instance / main.tf

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
}

máy chủ.tf

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"]
        },
    }
}

Tất nhiên, bạn có thể thêm bao nhiêu biến nếu cần và sử dụng chúng trong mô-đun.


Nó tốt nhưng biến được cung cấp động mỗi lần.
TheShadow2707

Các biến phổ biến có thể được thêm vào một cách riêng biệt như các biến và được sử dụng lại dưới dạng var.variable. Những cái duy nhất phải được khai báo riêng biệt nào.
Tamás Juhász

1

Sử dụng for_eachkhối này là khá mới và không có quá nhiều tài liệu. Một số thông tin tốt nhất đến từ bài đăng trên blog thông báo của họ: https://www.hashicorp.com/blog/hashicorp-terraform-0-12-preview-for-and-for-each/

Ngoài ra, hãy đảm bảo kiểm tra phần Khối động trong tài liệu của họ: https://www.terraform.io/docs/configuration/expressions.html#dynamic-blocks

Từ ví dụ của bạn trông giống như bạn cần có một bộ giá trị cho mỗi phiên bản được tạo để bạn có bản đồ bản đồ:

Dưới đây là một ví dụ tôi đã tạo bằng cách sử dụng 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"
    }
}

Sản lượng kế hoạch 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.

Vì vậy, tôi cần chuyển đổi danh sách thành bản đồ, vì tôi nhấn mạnh nó thay đổi chỉ mục của danh sách thành chính và nó sẽ là bản đồ.
TheShadow2707
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.