繁体   English   中英

如何通过 Terraform 从同一模板创建两个具有不同 static 外部 IP 的 GCP VM 实例?

[英]How to create two GCP VM instances with deferent static external IP from same template via Terraform?

试图找到如何从同一模板创建两个带有 static 外部 IP 的 GCP 实例的方法。 我有一个代码在两个非托管实例组中创建两个具有临时外部 IP 的实例。 我需要改进用于创建实例的代码 static 外部 IP。现有代码:

resource "google_compute_instance_template" "default" {
  # name         = format("%s-template", var.hostname)
  name_prefix  = var.hostname
  project      = var.project
  machine_type = var.machine_type

  region = var.region

  tags = var.target_tags

  labels = var.instance_labels

  can_ip_forward = var.can_ip_forward

  service_account {
    email  = var.service_account_email
    scopes = var.service_account_scopes
  }

  disk {
    auto_delete  = lookup(var.main_disk, "auto_delete", true)
    boot         = true
    source_image = lookup(var.main_disk, "source_image", "projects/debian-cloud/global/images/family/debian-9")
    device_name  = lookup(var.main_disk, "device_name", null)
    mode         = lookup(var.main_disk, "device_name", "READ_WRITE")
    type         = lookup(var.main_disk, "type", "PERSISTENT")
    disk_name    = lookup(var.main_disk, "disk_name", null)
    disk_type    = lookup(var.main_disk, "disk_type", "pd-ssd")
    disk_size_gb = lookup(var.main_disk, "disk_size_gb", null)
  }

  dynamic "disk" {
    for_each = [for d in var.additional_disks : {
      # auto_delete - (Optional) Whether or not the disk should be auto-deleted. This defaults to true.
      auto_delete = lookup(d, "auto_delete", true)
      # device_name - (Optional) A unique device name that is reflected into the /dev/ tree of a Linux operating system running within the instance. If not specified, the server chooses a default device name to apply to this disk.
      device_name = lookup(d, "device_name", null)
      # disk_name - (Optional) Name of the disk. When not provided, this defaults to the name of the instance.
      disk_name = lookup(d, "disk_name", null)
      # mode - (Optional) The mode in which to attach this disk, either READ_WRITE or READ_ONLY. If you are attaching or creating a boot disk, this must read-write mode.
      mode = lookup(d, "mode", "READ_WRITE")
      # source - (Required if source_image not set) The name (not self_link) of the disk (such as those managed by google_compute_disk) to attach.
      source = d.source
      # disk_type - (Optional) The GCE disk type. Can be either "pd-ssd", "local-ssd", or "pd-standard".
      disk_type = lookup(d, "disk_type", "pd-ssd")
      # disk_size_gb - (Optional) The size of the image in gigabytes. If not specified, it will inherit the size of its base image.
      disk_size_gb = lookup(d, "disk_size_gb", null)
      #type - (Optional) The type of GCE disk, can be either "SCRATCH" or "PERSISTENT".
      type = lookup(d, "type", "PERSISTENT")
    }]

    content {
      auto_delete  = disk.value.auto_delete
      boot         = disk.value.boot
      device_name  = disk.value.device_name
      disk_name    = disk.value.disk_name
      mode         = disk.value.mode
      source       = disk.value.source
      disk_type    = disk.value.disk_type
      disk_size_gb = disk.value.disk_size_gb
      type         = disk.value.type
    }
  }

  dynamic "network_interface" {
    for_each = [for n in var.interfaces : {
      network      = lookup(n, "network", null)
      subnetwork   = lookup(n, "subnetwork", null)
      network_ip   = lookup(n, "network_ip", null)
      nat_ip       = lookup(n, "nat_ip", null)
      network_tier = lookup(n, "network_tier", "PREMIUM")
      public_ip    = lookup(n, "public_ip", false)
    }]

    content {
      network    = network_interface.value.network
      subnetwork = network_interface.value.subnetwork
      network_ip = network_interface.value.network_ip

      dynamic "access_config" {
        for_each = network_interface.value.public_ip == "true" ? list(0) : []

        content {
          nat_ip       = network_interface.value.public_ip
          network_tier = network_interface.value.network_tier
        }
      }
    }
  }

  metadata = var.metadata

  metadata_startup_script = var.startup_script

  scheduling {
    preemptible         = var.scheduling["preemptible"]
    automatic_restart   = var.scheduling["automatic_restart"]
    on_host_maintenance = var.scheduling["on_host_maintenance"]
  }

  lifecycle {
    create_before_destroy = true
  }
}

resource "google_compute_instance_from_template" "compute_instance" {
  count                    = var.num_instances
  project                  = var.project
  name                     = format("%s%d", var.hostname, count.index + 1)
  zone                     = var.zone[count.index]
  source_instance_template = google_compute_instance_template.default.self_link
}

resource "google_compute_instance_group" "instance_group" {
  count   = var.num_instances
  project = var.project
  name    = format("%s-ig-%d", var.hostname, count.index)
  zone    = var.zone[count.index]

  instances = [google_compute_instance_from_template.compute_instance[count.index].self_link]

  dynamic "named_port" {
    for_each = var.named_ports
    content {
      name = named_port.value.name
      port = named_port.value.port
    }
  }
}

我找到了用于创建 static 外部 IP 的模块

module "address" {
  source  = "terraform-google-modules/address/google"
  version = "2.1.0"
  project_id = var.project
  region = var.region
  address_type = "EXTERNAL"
  enable_cloud_dns = false
  names = [
    "ip",
    "ip2",
  ]
 }

该模块给出 output module.address.addresses 格式

[ 
  xxx.xxx.xxx.xxx,
  yyy.yyy.yyy.yyy
]

但是我仍然找不到一种棘手的方法来通过模板从模块中获取这个 IP 的实例。

可能有人给我建议我如何实现它?

我对 TF 和 GCP 也很陌生,但是......从脑海中浮现出两个想法(记住我是新手,可能是一个更好的解决方案)

  • 为每个具有该值的 IP 定义一个变量,然后在您想要的资源中调用该 IP。
  • 为 IP 声明和 output,然后在您想要的资源中调用这些 IP 的 output,例如 IP

我通过覆盖模板设置解决了问题

resource "google_compute_address" "static" {
  count = var.num_instances
  project      = var.project
  name  = var.ext_ip_name[count.index] # ["ip", "ip2"]
  address_type = "EXTERNAL"
}

<...>

resource "google_compute_instance_from_template" "compute_instance" {
  count                    = var.num_instances
  project                  = var.project
  name                     = format("%s%d", var.hostname, count.index + 1)
  zone                     = var.zone[count.index]
  source_instance_template = google_compute_instance_template.default.self_link
  dynamic "network_interface" {
    for_each = [for n in var.interfaces : {
      network      = lookup(n, "network", null)
      subnetwork   = lookup(n, "subnetwork", null)
      network_ip   = lookup(n, "network_ip", null)
      nat_ip       = lookup(n, "nat_ip", null)
      network_tier = lookup(n, "network_tier", "PREMIUM")
      public_ip    = lookup(n, "public_ip", false)
    }]

    content {
      network    = network_interface.value.network
      subnetwork = network_interface.value.subnetwork
      network_ip = network_interface.value.network_ip

      dynamic "access_config" {
        for_each = network_interface.value.public_ip == "true" ? list(0) : []

        content {
          nat_ip       = google_compute_address.static[count.index].address
          network_tier = network_interface.value.network_tier
        }
      }
    }
  }
}

<...>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM