Как ссылаться на источник данных из модуля в другой модуль и передавать его как переменную в корневой модуль?

У меня есть структура каталогов terraform, как показано ниже:

terraform/
main.tf  modules  outputs.tf  provider.tf  variables.tf

./modules:
compute  network  resourcegroup

./modules/compute:
main.tf  outputs.tf  variables.tf

./modules/network:
main.tf  outputs.tf  variables.tf

./modules/resourcegroup:
main.tf  outputs.tf  variables.tf

Файлы конфигурации модуля resourcegroup, как показано ниже:

Цель: в этом модуле я ссылаюсь на существующую группу ресурсов, которую я хотел бы использовать для создания виртуальной машины и связанных с ней объектов.

main.tf

data "azurerm_resource_group" "tf-rg-external" {
  name = var.rg_name
}

variables.tf

variable "rg_name" {
  type = string

}

сетевой модуль

Цель: я хотел бы использовать группу ресурсов из модуля группы ресурсов для ссылки в этом модуле. Таким образом, я определяю в одном месте и использую его в корневом и других модулях, например, в вычислениях, службе приложений, аках и т. Д.

main.tf

# Reference existing Virtual Network
data "azurerm_virtual_network" "tf-vn" {
  name                = var.vnet_name
  resource_group_name = module.resource_groups.external_rg_name
}

# Reference existing subnet
data "azurerm_subnet" "tf-sn" {
  name                 = var.subnet_name
  virtual_network_name = data.azurerm_virtual_network.tf-vn.name
  resource_group_name  = module.resource_groups.external_rg_name
}

variables.tf

# Declare env variable
variable "vnet_name" {
  type = string
}

variable "subnet_name" {
  type = string
}

вычислить модуль.

Цель: определить все атрибуты для вычислений (ВМ). Идея в том, что корневой модуль будет использовать этот модуль для раскрутки различных ролей виртуальных машин.

main.tf

module "vm_iis" {
  source                        = "Azure/compute/azurerm"
  location                      = data.resourcegroup.tf-rg-external.location
  vnet_subnet_id                = data.network.tf-sn.id
  admin_password                = var.admin_password
  data_sa_type                  = var.data_sa_type
  delete_os_disk_on_termination = var.delete_os_disk_on_termination
  nb_instances                 = var.nb_instances
  nb_public_ip                 = var.nb_public_ip
  public_ip_address_allocation = var.public_ip_address_allocation
  resource_group_name          = data.resourcegroup.tf-rg-external.name
  .
  .
  .
}

variables.tf

variable "admin_password" {
  type = string
}
variable "admin_username" {
  type = string
}
variable "boot_diagnostics" {
  type = bool
}
variable "boot_diagnostics_sa_type" {
  type = string
}...

Корневой модуль terraform.

Цель: здесь должны использоваться модули, определенные для создания различных виртуальных машин разных размеров и имен хостов.

main.tf:

module "sql_vm" {
  source                        = "./modules/compute/"
  #location                      = data.resourcegroup.tf-rg-external.location
  #vnet_subnet_id                = data.network.tf-sn.id
  public_ip_address_allocation  = var.public_ip_address_allocation
  #resource_group_name          = data.resourcegroup.tf-rg-external.name
  storage_account_type          = var.storage_account_type
  vm_hostname                   = var.vm_hostname
}

variables.tf: объявляет все переменные в файле main.tf.

Примечание. Я намеренно жестко закодировал переменные в основном файле / файле переменных корневого модуля. Это просто правильная связь между модулями. Правильный подход к пониманию и использованию модулей.

Однако, когда я запускаю terraform plan в корневом модуле. Я получаю сообщение об ошибке ниже:

Error: Reference to undeclared resource

  on modules/compute/main.tf line 3, in module "vm_iis":
   3:   location                      = data.resourcegroup.tf-rg-external.location

A data resource "resourcegroup" "tf-rg-external" has not been declared in
sql_vm.


Error: Reference to undeclared resource

  on modules/compute/main.tf line 4, in module "vm_iis":
   4:   vnet_subnet_id                = data.network.tf-sn.id

A data resource "network" "tf-sn" has not been declared in sql_vm.


Error: Reference to undeclared resource

  on modules/compute/main.tf line 22, in module "vm_iis":
  22:   resource_group_name          = data.resourcegroup.tf-rg-external.name

A data resource "resourcegroup" "tf-rg-external" has not been declared in
sql_vm.

В чем проблема и как ее решить?

Кроме того, можно ли создавать разные (роли) виртуальные машины каким-либо циклом? пример sql-vm, iis-vm, testvm, abcvm? Что изменится, так это их имена хостов и размеры виртуальных машин.

==========

Опубликовать изменения ответа

==========

Я обновил значения для подсети, группы ресурсов и местоположения в compute / main.tf и terraform / main.tf, как показано ниже:

location                      = module.resourcegroup.tf-rg-external-location
vnet_subnet_id                = module.network.subnet-id
resource_group_name           = module.resourcegroup.tf-rg-external-name

Мой файл outputs.tf в модулях resourcegroup и network выглядит следующим образом:

outputs.tf модуля network

output "subnet-id" {
  value = "data.network.tf-sn.id"
}

outputs.tf модуля resourcegroup

output "tf-rg-external-location" {
  value = data.resourcegroup.tf-rg-external.location
}
output "tf-rg-external-name" {
  value = data.resourcegroup.tf-rg-external.name
}

К сожалению, я все еще получаю такие ошибки, как показано ниже

Error: Unsupported argument

  on main.tf line 3, in module "sql_vm":
   3:   location                      = module.resourcegroup.tf-rg-external-location

An argument named "location" is not expected here.


Error: Unsupported argument

  on main.tf line 4, in module "sql_vm":
   4:   vnet_subnet_id                = module.network.subnet-id

An argument named "vnet_subnet_id" is not expected here.


Error: Unsupported argument

  on main.tf line 5, in module "sql_vm":
   5:   resource_group_name           = module.resourcegroup.tf-rg-external-name

An argument named "resource_group_name" is not expected here.

Итак, похоже, мы не должны ссылаться на них в корневом модуле?

Кроме того, где их переменные должны быть определены, как в файле root modules variables.tf, поскольку я считаю, что вы можете переопределить значения для переменной модулей в корневом модуле?

Простите меня, если я веду себя глупо. Я пытаюсь понять, как это работает в реальной жизни.

После последнего коммита и публичного репо ошибки указаны ниже

Error: Reference to undeclared module

  on main.tf line 3, in module "sql_vm":
   3:   location                      = module.resourcegroup.tf-rg-external-location

No module call named "resourcegroup" is declared in the root module.


Error: Reference to undeclared module

  on main.tf line 4, in module "sql_vm":
   4:   vnet_subnet_id                = module.network.subnet-id

No module call named "network" is declared in the root module.


Error: Reference to undeclared module

  on main.tf line 5, in module "sql_vm":
   5:   resource_group_name           = module.resourcegroup.tf-rg-external-name

No module call named "resourcegroup" is declared in the root module.


Error: Reference to undeclared module

  on modules/compute/main.tf line 3, in module "vm_iis":
   3:   location                      = module.resourcegroup.tf-rg-external-location

No module call named "resourcegroup" is declared in sql_vm.


Error: Reference to undeclared module

  on modules/compute/main.tf line 4, in module "vm_iis":
   4:   vnet_subnet_id                = module.network.subnet-id

No module call named "network" is declared in sql_vm.


Error: Reference to undeclared module

  on modules/compute/main.tf line 5, in module "vm_iis":
   5:   resource_group_name           = module.resourcegroup.tf-rg-external-name

No module call named "resourcegroup" is declared in sql_vm.


Error: Reference to undeclared module

  on modules/network/main.tf line 5, in data "azurerm_virtual_network" "tf-vn":
   5:   resource_group_name = module.resource_groups.external_rg_name

No module call named "resource_groups" is declared in test2.


Error: Reference to undeclared resource

  on modules/resourcegroup/outputs.tf line 2, in output "tf-rg-external-location":
   2:   value = data.resourcegroup.tf-rg-external.location

A data resource "resourcegroup" "tf-rg-external" has not been declared in
test1.


Error: Reference to undeclared resource

  on modules/resourcegroup/outputs.tf line 5, in output "tf-rg-external-name":
   5:   value = data.resourcegroup.tf-rg-external.name

A data resource "resourcegroup" "tf-rg-external" has not been declared in
test1.

comment
Я думаю, вам нужно внимательно прочитать ответ, в нем говорится, что вам нужно определить вывод, чтобы вы могли обращаться к нужным вам ресурсам.   -  person Charles Xu    schedule 28.11.2019
comment
На самом деле я это сделал, а затем только запустил план терраформирования, я не вставлял output.tf в свой вопрос. Я исправлю свой вопрос, чтобы вы могли видеть outputs.tf. Если бы файл outputs.tf не был определен, он сам сообщил бы о другой ошибке.   -  person learner    schedule 28.11.2019
comment
Возможно, теперь это будет иметь смысл? Мне нужна помощь, так как я не могу заставить его работать на основе решения, предложенного BMW Sir.   -  person learner    schedule 28.11.2019


Ответы (1)


Просмотрите репозиторий, над которым вы работаете (https://github.com/ameyaagashe/help_me_cross/tree/d7485d2a3db339723e9c791e592b2f1dbc1f0788). Теперь это имеет для меня смысл.

Проблема в том, что вы смешиваете идею использования общедоступных модулей с собственными созданными модулями.

Фактически, вам не нужно устанавливать какие-либо модули для ссылки на другие общедоступные модули реестра terraform.

Переместите все коды в подмодулях (модуль / вычисление, модуль / сеть, модуль / группа ресурсов) в верхнюю папку (<repo_root>/main.tf).

например (коды не проверяются, просто для справки)

data "azurerm_resource_group" "tf-rg-external" {
  name = var.rg_name
}

data "azurerm_virtual_network" "tf-vn" {
  name                = var.vnet_name
  resource_group_name = var.rg_name
}

# Reference existing subnet
data "azurerm_subnet" "tf-sn" {
  name                 = var.subnet_name
  virtual_network_name = data.azurerm_virtual_network.tf-vn.name
  resource_group_name  = var.rg_name
}

module "sql_vm" {
  source                        = "Azure/compute/azurerm"
  location                      = data.azurerm_resource_group.tf-rg-external.location
  vnet_subnet_id                = data.azurerm_virtual_network.tf-vn.subnets
  resource_group_name           = data.azurerm_resource_group.tf-rg-external.name
  admin_password                = var.admin_password
  admin_username                = var.admin_username
  boot_diagnostics              = var.boot_diagnostics
  boot_diagnostics_sa_type      = var.boot_diagnostics_sa_type
  data_disk                     = var.data_disk
  data_disk_size_gb             = var.data_disk_size_gb
  data_sa_type                  = var.data_sa_type
  delete_os_disk_on_termination = var.delete_os_disk_on_termination
  enable_accelerated_networking = var.enable_accelerated_networking
  # flag is_windows_image is required only when you use a custom image to spin up a VM
  # is_windows_image
  # flag vm_os_id is required only when you are using custom image
  # you need to provide id of your custom image
  # vm_os_id
  nb_instances                 = var.nb_instances
  nb_public_ip                 = var.nb_public_ip
  public_ip_address_allocation = var.public_ip_address_allocation
  storage_account_type         = var.storage_account_type
  vm_hostname                  = var.vm_hostname
  vm_os_offer                  = var.vm_os_offer
  vm_os_publisher              = var.vm_os_publisher
  # vm_os_simple is to be used is you do not wish to specify offer, publisher and sku
  # vm_os_simple                  = UbuntuServer, WindowsServer, RHEL, openSUSE-Leap, CentOS, Debian, CoreOS and SLES
  vm_os_sku     = var.vm_os_sku
  vm_os_version = var.vm_os_version
  vm_size       = var.vm_size
}
person BMW    schedule 28.11.2019
comment
Сэр, теперь я обновил свой вопрос новыми ошибками, любезный совет. - person learner; 28.11.2019
comment
Я добавил ответ, дайте мне знать, может ли он решить вашу проблему или нет. - person BMW; 29.11.2019
comment
Сэр. Пожалуйста, помогите. Теперь все мое репо публично. github.com/ameyaagashe/help_me_cross - person learner; 29.11.2019
comment
теперь это имеет смысл. Вам вообще не нужно создавать подмодули. все должно быть наверху. потому что вы пытаетесь ссылаться на общедоступные модули реестра terraform. Даю вам несколько кодов, смотрите мои обновления. - person BMW; 29.11.2019
comment
Большое спасибо! Теперь я понимаю, какой микс делал. Еще есть чему поучиться! - person learner; 29.11.2019
comment
Теперь это работает. Выдает ошибку, специфичную для модуля, но я бы создал другой поток. - person learner; 29.11.2019