0

I have created resource, network and compute module in terraform, now want to pass output of vm_id to site recovery module here are the files I am using currently.

Continue to subject: in resource "azurerm_site_recovery_replicated_vm" "vm-replication": source_vm_id= module.compute.vm_id

This is directory structure that I am following currently,

.
├── main.tf
└── modules
    ├── compute
    │   ├── main.tf
    │   ├── outputs.tf_bk
    │   ├── variable.tf
    │   └── variable.tfvars
    ├── network
    │   ├── main.tf
    │   ├── variable.tf
    │   └── variable.tfvars
    ├── resource
    │   ├── main.tf
    │   ├── variable.tf
    │   └── variable.tfvars
    └── site_recovery
        ├── main.tf
        ├── variable.tf
        └── variable.tfvars

root module main.cf file:

#Select provider
provider "azurerm" {
  subscription_id = "xxxxxxxxxxxxxxxxxxxxxxxx"
  version = "~> 2.4"
  features {}
}

module "resource" {
  source = "./modules/resource"
  resource_group_name = "devops_primary"
  location = "southeastasia"
}

module "network" {
  source = "./modules/network"
  virtual_network = "primaryvnet"
  subnet = "primarysubnet"
  address_space = "192.168.0.0/16"
  address_prefix = "192.168.1.0/24"
  public_ip = "backendvmpip"
  location = "southeastasia"
  primary_nic = "backendvmnic"
  primary_ip_conf = "backendvm"
  resource_group_name = "module.resource.primary_group_name"
}

module "compute" {
  source = "./modules/compute"
  #resource_group_name = "devops_primary"
  #location = "southeastasia"
  vm_name = "backendvm-primary"
  vm_size = "standard_d2s_v3"
  vm_storage_od_disk_name = "backend-vm-os-disk-primary"
  computer_name = "backendserver"
  username = "terraform"
  ssh_key_path = "/home/terraform/.ssh/authorized_keys"
  keys_data = "~/.ssh/id_rsa.pub"
  sa_name = "primarysa"
  disk_name = "backenddisk_primary"
}

module "site_recovery" {
  source = "./modules/site_recovery"
  #resource_group_name = "devops_primary"
  #location = "southeastasia"
  sec_resource_group = "devops_secondary"
  recovery_vault_name = "recovery-vault"
  primary_fabric = "devops_primary-fabric"
  seconday_fabric = "devops_secondary-fabric"
  primary_container = "primary-protection-container"
  secondary_container = "secondary-protection-container"
  policy_name = "policy"
  container_mapping = "container-mapping"
  replicated_vm = "backendvm-replication"
}

compute main.cf :

#Create VM in Primary resource
resource "azurerm_virtual_machine" "primary" {
  name                  = "var.vm_name"
  location              = "module.resource.azurerm_resource_group.primary.location"
  resource_group_name   = "module.resource.azurerm_resource_group.primary.name"
  vm_size               = "var.vm_size"
  network_interface_ids = ["module.resource.azurerm_network_interface.primary.id"]

  storage_os_disk {
    name              = "var.vm_storage_od_disk_name"
    os_type           = "Linux"
    caching           = "ReadWrite"
    create_option     = "FromImage"
    managed_disk_type = "Premium_LRS"
  }

storage_image_reference {
    publisher = "Canonical"
    offer     = "UbuntuServer"
    sku       = "18.04-LTS"
    version   = "latest"
  }
  os_profile {
    computer_name  = "var.computer_name"
    admin_username = "var.username"
  }
  os_profile_linux_config {
    disable_password_authentication = true

  ssh_keys {
      path     = "/home/terraform/.ssh/authorized_keys"
      key_data = file("~/.ssh/id_rsa.pub")
    }
  }
  tags = {
        environment = "Test"
    }
output "vm_ids" {
  description = "Virtual machine ids created."
  value       = azurerm_virtual_machine.primary.id
  #depends_on = [azurerm_virtual_machine.primary.primary]
}

site recovery main.cf

#Create Site Recovery Replicated VM
resource "azurerm_site_recovery_replicated_vm" "vm-replication" {
  name                                      = var.replicated_vm
  resource_group_name                       = azurerm_resource_group.secondary.name
  recovery_vault_name                       = azurerm_recovery_services_vault.vault.name
  source_recovery_fabric_name               = azurerm_site_recovery_fabric.primary.name
  #source_vm_id                              = site recovery main.cf

#Create Site Recovery Replicated VM
resource "azurerm_site_recovery_replicated_vm" "vm-replication" {
  name                                      = var.replicated_vm
  resource_group_name                       = azurerm_resource_group.secondary.name
  recovery_vault_name                       = azurerm_recovery_services_vault.vault.name
  source_recovery_fabric_name               = azurerm_site_recovery_fabric.primary.name
  #source_vm_id                              = "module.compute.azurerm_virtual_machine.primary.id"
  source_vm_id                              = module.compute.vm_ids
  recovery_replication_policy_id            = azurerm_site_recovery_replication_policy.policy.id
  source_recovery_protection_container_name = azurerm_site_recovery_protection_container.primary.name
  target_resource_group_id                  = azurerm_resource_group.secondary.id
  target_recovery_fabric_id                 = azurerm_site_recovery_fabric.secondary.id
  target_recovery_protection_container_id   = azurerm_site_recovery_protection_container.secondary.id


  managed_disk {
    disk_id                    = "[module.resource.azurerm_virtual_machine.primary.storage_os_disk[0].managed_disk_id]"
    staging_storage_account_id = "module.resource.azurerm_storage_account.primary.id"
    target_resource_group_id   = azurerm_resource_group.secondary.id
    target_disk_type           = "Premium_LRS"
    target_replica_disk_type   = "Premium_LRS"
  }

  managed_disk {
    disk_id                    = "[module.resource.azurerm_managed_disk.primary.id]"
    staging_storage_account_id = "[module.resource.azurerm_storage_account.primary.id]"
    target_resource_group_id   = azurerm_resource_group.secondary.id
    target_disk_type           = "Premium_LRS"
    target_replica_disk_type   = "Premium_LRS"
  }
depends_on = ["module.compute.vm_ids"]
}

Used depends_on for input to site_recovery module, again will you please suggest, how can I output managed disks ids and Os disks ids from compute module and use input in site recovery module.

Nancy
  • 26,865
  • 3
  • 18
  • 34
M Chavhan
  • 47
  • 2
  • 11
  • I have added output to compute for vm id as below `output "vm_ids" { description = "Virtual machine ids created." value = azurerm_virtual_machine.primary.*.id #depends_on = [azurerm_virtual_machine.primary.primary] }` – M Chavhan Apr 08 '20 at 13:31
  • I have added output to compute for vm id (main.tf ) as below: `output "vm_ids" {description = "Virtual machine ids created." value = azurerm_virtual_machine.primary.*.id }` and added vm_ids to site recovery module as : `module "site_recovery" { vm_ids = "module.compute.vm_ids" } ` added variable to site_recovery module as : `"azurerm_site_recovery_replicated_vm" "vm-replication" { source_vm_id = var.vm_ids }` – M Chavhan Apr 08 '20 at 13:52
  • With _terrform plan_ getting succes, but with _terraform plan getting below as same above `Error: Can not parse "source_vm_id" as a resource id: Cannot parse Azure ID: parse module.compute.vm_ids: invalid URI for request on modules/site_recovery/main.tf line 80, in resource "azurerm_site_recovery_replicated_vm" "vm-replication": 80: resource "azurerm_site_recovery_replicated_vm" "vm-replication" {` @Nancy Xiong – M Chavhan Apr 08 '20 at 13:58

1 Answers1

1

For the error

Error: Reference to undeclared module on modules/site_recovery/main.tf

It means the referenced module is not declared in the calling module.

To call a module means to include the contents of that module into the configuration with specific values for its input variables. Modules are called from within other modules using module blocks. You need to add the module block in the configuration .tf file where you want to call that module. See calling a child module.

It seems that there are no module blocks declared in your sub site recovery and compute main.tf, so you can not call the resource modules such as module.resource.azurerm_resource_group.primary.location, module.resource.azurerm_managed_disk.primary.id and so on.

As your directory structure, you can also use input variable to call the module from another module output. The correct expression is module.<MODULE NAME>.<OUTPUT NAME>.

To output the VM id and managed disks id from compute module like this:

output "azurerm_vm_id" {
  value = azurerm_virtual_machine.primary.id
}


output "primary_os_disk_id" {
  value = azurerm_virtual_machine.primary.storage_os_disk[0].managed_disk_id
}

The main.tf in the root directory

module "vm" {
  source = "./modules/vm"
  vm_name = "backendvm-primary"
  vm_size = "standard_d2s_v3"
  vm_storage_od_disk_name = "backend-vm-os-disk-primary"
  computer_name = "backendserver"
  username = "terraform"
  nic_ids = module.network.primary_nic_id
  resource_group_name = module.resource.rg_name
  location = module.resource.rg_location
  #ssh_key_path = "/home/terraform/.ssh/authorized_keys"
  #keys_data = "~/.ssh/id_rsa.pub"
}


module "site_recovery" {
  source = "./modules/site_recovery"
  resource_group_name = module.resource.rg_name
  location = module.resource.rg_location
  sec_resource_group = "nancy_secondary"
  sec_location = "eastus"
  recovery_vault_name = "recovery-vault"
  primary_fabric = "devops_primary-fabric"
  seconday_fabric = "devops_secondary-fabric"
  primary_container = "primary-protection-container"
  secondary_container = "secondary-protection-container"
  policy_name = "policy"
  container_mapping = "container-mapping"
  replicated_vm = "backendvm-replication"

  source_vm_id  = module.vm.azurerm_vm_id
  primary_os_disk_id = module.vm.primary_os_disk_id

}

The Site Recovery main.tf file

#Create Site Recovery Replicated VM
resource "azurerm_site_recovery_replicated_vm" "vm-replication" {
  depends_on                                = [var.vm_depends_on]
  name                                      = var.replicated_vm
  resource_group_name                       = azurerm_resource_group.secondary.name
  recovery_vault_name                       = azurerm_recovery_services_vault.vault.name
  source_recovery_fabric_name               = azurerm_site_recovery_fabric.primary.name

  source_vm_id                              = var.source_vm_id
  recovery_replication_policy_id            = azurerm_site_recovery_replication_policy.policy.id
  source_recovery_protection_container_name = azurerm_site_recovery_protection_container.primary.name
  target_resource_group_id                  = azurerm_resource_group.secondary.id
  target_recovery_fabric_id                 = azurerm_site_recovery_fabric.secondary.id
  target_recovery_protection_container_id   = azurerm_site_recovery_protection_container.secondary.id


  managed_disk {
    disk_id                    = var.primary_os_disk_id
    staging_storage_account_id = azurerm_storage_account.primary.id
    target_resource_group_id   = azurerm_resource_group.secondary.id
    target_disk_type           = "Premium_LRS"
    target_replica_disk_type   = "Premium_LRS"
  }

}

In fact, in the azurerm_site_recovery_replicated_vm block, there is an implicit dependencies source_vm_id, it replys on the source Azure VM. If you want to use terraform depends_on meta-argument accepts a list of resources with module. You can refer to this thread - Terraform depends_on with modules and this document.

Nancy
  • 26,865
  • 3
  • 18
  • 34