Ошибка — отсутствует ключ экземпляра ресурса: поскольку в google_compute_instance установлено значение «count», его атрибуты должны быть доступны в определенных экземплярах

#google-cloud-platform #terraform #google-compute-engine #terraform-provider-gcp

# #google-cloud-platform #terraform #google-compute-engine #terraform-provider-gcp

Вопрос:

Я пытаюсь передать mat_ip экземпляров Google compute, созданных в модуле «microservice-instance», в другой модуль «database». Поскольку я создаю более одного экземпляра, я получаю следующую ошибку для выходной переменной в модуле «microservice-instance».

 Error: Missing resource instance key

  on modules/microservice-instance/ms-outputs.tf line 3, in output "nat_ip":    3:   value = google_compute_instance.apps.network_interface[*].access_config[0].nat_ip

Because google_compute_instance.apps has "count" set, its attributes must be accessed on specific instances.

For example, to correlate with indices of a referring resource, use:
    google_compute_instance.apps[count.index]
 

Я рассмотрел следующий и использовал тот же способ доступа к атрибуту, но он не работает. Вот код —
main.tf

 provider "google" {
  credentials = "${file("../../service-account.json")}"
  project = var.project
  region =var.region

  
}

# Include modules
module "microservice-instance" {
  count = var.appserver_count
  source = "./modules/microservice-instance"
  appserver_count = var.appserver_count
}
module "database" {
  count  = var.no_of_db_instances
  source = "./modules/database"
  nat_ip = module.microservice-instance.nat_ip
  no_of_db_instances = var.no_of_db_instances
}
 

./modules/microservice-instance/microservice-instance.tf

 resource "google_compute_instance" "apps" {
  count        = var.appserver_count
  name         = "apps-${count.index   1}"
  # name         = "apps-${random_id.app_name_suffix.hex}"
  machine_type = "f1-micro"

  boot_disk {
    initialize_params {
      image = "ubuntu-os-cloud/ubuntu-1804-lts"
    }
  }

  network_interface {
    network = "default"

    access_config {
      // Ephemeral IP
    }
  }
}
 

./modules/microservice-instance/ms-outputs.tf

 output "nat_ip" {
  value = google_compute_instance.apps.network_interface[*].access_config[0].nat_ip
}
 

./modules/database/database.tf

 resource "random_id" "db_name_suffix" {
  byte_length = 4
}

resource "google_sql_database_instance" "postgres" {
  name             = "postgres-instance-${random_id.db_name_suffix.hex}"
  database_version = "POSTGRES_11"
  settings {
    tier = "db-f1-micro"

    ip_configuration {

      dynamic "authorized_networks" {
        for_each = var.nat_ip
        # iterator = ip

        content {
          # value = ni.0.access_config.0.nat_ip
          value = each.key
        }
      }

    }
  }
}
 

Ответ №1:

Вы создаете var.appserver_count количество google_compute_instance.apps ресурсов. Таким образом, у вас будет:

 google_compute_instance.apps[0]
google_compute_instance.apps[1]
...
google_compute_instance.apps[var.appserver_count - 1]
 

Поэтому в вашем output , вместо:

 output "nat_ip" {
  value = google_compute_instance.apps.network_interface[*].access_config[0].nat_ip
}
 

вы должны ссылаться на отдельные apps ресурсы или на все из них, используя [*] , например:

 output "nat_ip" {
  value = google_compute_instance.apps[*].network_interface[*].access_config[0].nat_ip
}
 

Комментарии:

1. Я тоже пробовал это, но получал другую ошибку, как показано ниже… Ошибка: неподдерживаемый атрибут на main.tf строка 17, в модуле «база данных»: 17: nat_ip = module.microservice-instance.nat_ip Это значение не имеет никаких атрибутов.

2. @Amit Я не уверен, чего вы хотите достичь. Вы output "nat_ip" всегда будете возвращать несколько nat_ip s. Но module "database" кажется, что он ожидает только один nat_ip ?

3. Мне нужно вернуть этот множественный список nat_ip в модуль базы данных и выполнить цикл (см. for_each в database.tf ) их, чтобы установить authorized_networks для экземпляра БД.