1
votes

I'm creating VMs using the script below beginning with "# Script to create VM". The script is being called from a higher level directory so as to create the VMs using modules, the call looks something like in the code below starting with "#Template..". The problem is that we are missing the state for a few VMs that were created during a previous run. I've tried importing the VM itself but looking at the state file it does not appear anything similar to the ones already there created using the bottom script. Any help would be great.

#Template to call VM Script below
module <virtual_machine_name> {
    source = "./vm"
    virtual_machine_name = "<virtual_machine_name>"
    resource_group_name = "<resource_group_name>"
    availability_set_name = "<availability_set_name>"
    virtual_machine_size = "<virtual_machine_size>"
    subnet_name = "<subnet_name>"
    private_ip = "<private_ip>"

    optional:
    production = true (default is false)
    data_disk_name = ["<disk1>","<disk2>"]
    data_disk_size = ["50","100"] size is in GB
}

# Script to create VM
data azurerm_resource_group rgdata02 {
    name = "${var.resource_group_name}"
}
data azurerm_subnet sndata02 {
    name = "${var.subnet_name}"
  resource_group_name = "${var.core_resource_group_name}"
  virtual_network_name = "${var.virtual_network_name}"
}
data azurerm_availability_set availsetdata02 {
  name = "${var.availability_set_name}"
  resource_group_name = "${var.resource_group_name}"
}
data azurerm_backup_policy_vm bkpoldata02 {
  name                = "${var.backup_policy_name}"
  recovery_vault_name = "${var.recovery_services_vault_name}"
  resource_group_name = "${var.core_resource_group_name}"
}
data azurerm_log_analytics_workspace law02 { 
  name                = "${var.log_analytics_workspace_name}"
  resource_group_name = "${var.core_resource_group_name}"
}
#===================================================================
# Create NIC
#===================================================================
resource "azurerm_network_interface" "vmnic02" {
  name                = "nic${var.virtual_machine_name}"
  location            = "${data.azurerm_resource_group.rgdata02.location}"
  resource_group_name = "${var.resource_group_name}"

  ip_configuration {
    name                          = "ipcnfg${var.virtual_machine_name}"
    subnet_id                     = "${data.azurerm_subnet.sndata02.id}"
    private_ip_address_allocation = "Static"
    private_ip_address            = "${var.private_ip}"
  }
}
#===================================================================
# Create VM with Availability Set
#===================================================================
resource "azurerm_virtual_machine" "vm02" {
  count = var.avail_set != "" ? 1 : 0
  depends_on            = [azurerm_network_interface.vmnic02]
  name                  = "${var.virtual_machine_name}"
  location              = "${data.azurerm_resource_group.rgdata02.location}"
  resource_group_name   = "${var.resource_group_name}"
  network_interface_ids = [azurerm_network_interface.vmnic02.id]
  vm_size               = "${var.virtual_machine_size}"
  availability_set_id   = "${data.azurerm_availability_set.availsetdata02.id}"
  tags                  = var.tags

  # This means the OS Disk will be deleted when Terraform destroys the Virtual Machine
  # NOTE: This may not be optimal in all cases.
  delete_os_disk_on_termination = true

  os_profile {
    computer_name  = "${var.virtual_machine_name}"
    admin_username = "__VMUSER__"
    admin_password = "__VMPWD__"
  }

  os_profile_linux_config {
    disable_password_authentication = false
  }

  storage_image_reference {
    id = "${var.image_id}"
  }

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

  boot_diagnostics {
    enabled = true
    storage_uri = "${var.boot_diagnostics_uri}"
  } 
}
#===================================================================
# Create VM without Availability Set
#===================================================================
resource "azurerm_virtual_machine" "vm03" {
  count = var.avail_set == "" ? 1 : 0
  depends_on            = [azurerm_network_interface.vmnic02]
  name                  = "${var.virtual_machine_name}"
  location              = "${data.azurerm_resource_group.rgdata02.location}"
  resource_group_name   = "${var.resource_group_name}"
  network_interface_ids = [azurerm_network_interface.vmnic02.id]
  vm_size               = "${var.virtual_machine_size}"
  # availability_set_id   = "${data.azurerm_availability_set.availsetdata02.id}"
  tags                  = var.tags

  # This means the OS Disk will be deleted when Terraform destroys the Virtual Machine
  # NOTE: This may not be optimal in all cases.
  delete_os_disk_on_termination = true

  os_profile {
    computer_name  = "${var.virtual_machine_name}"
    admin_username = "__VMUSER__"
    admin_password = "__VMPWD__"
  }

  os_profile_linux_config {
    disable_password_authentication = false
  }

  storage_image_reference {
    id = "${var.image_id}"
  }

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

  boot_diagnostics {
    enabled = true
    storage_uri = "${var.boot_diagnostics_uri}"
  } 
}
#===================================================================
# Set Monitoring and Log Analytics Workspace
#===================================================================
resource "azurerm_virtual_machine_extension" "oms_mma02" {
  count = var.bootstrap ? 1 : 0
  name                       = "${var.virtual_machine_name}-OMSExtension"
  virtual_machine_id         = "${azurerm_virtual_machine.vm02.id}"
  publisher                  = "Microsoft.EnterpriseCloud.Monitoring"
  type                       = "OmsAgentForLinux"
  type_handler_version       = "1.8"
  auto_upgrade_minor_version = true

  settings = <<SETTINGS
    {
      "workspaceId" : "${data.azurerm_log_analytics_workspace.law02.workspace_id}"
    }
  SETTINGS

  protected_settings = <<PROTECTED_SETTINGS
    {
      "workspaceKey" : "${data.azurerm_log_analytics_workspace.law02.primary_shared_key}"
    }
  PROTECTED_SETTINGS
}
#===================================================================
# Associate VM to Backup Policy
#===================================================================
resource "azurerm_backup_protected_vm" "vm02" {
  count = var.bootstrap ? 1 : 0
  resource_group_name = "${var.core_resource_group_name}"
  recovery_vault_name = "${var.recovery_services_vault_name}"
  source_vm_id        = "${azurerm_virtual_machine.vm02.id}"
  backup_policy_id    = "${data.azurerm_backup_policy_vm.bkpoldata02.id}"}
1
The key obstacle I see is what you mentioned: I've tried importing the VM itself but ... it does not appear anything similar ... so you know how to import, I'm afraid your options here are limited, can you just destroy them and let Terrafrom create them again?Helder Sepulveda
I'm not clear what do you mean the state and what do you really want. Can you give a real purpose?Charles Xu
Thanks for the replies. The real purpose is to be able to import the VM as a module, with all its parts, and not as a VM. If I look at the state file, the format of the resource is "module.win.module.name of VM" for each resource mentioned in the script but when I import the VM it's just the name of the VM without any of the info in the creation script. I know I can import the VM as a module but it doesn't seem like it will import all resources listed in the creation script. I think all started when the original state file was deleted and with it the info on these VMs.mac
I also do not understand what you want. The Data source only quotes one existing resource. And the Terraform import just import the existing resource in the state file, does not change the resource configuration already in the file.Charles Xu
Apologies for not being so clear. I'm following the instruction on this link document, section three deals with importing modules which is what I'm doing to create the VMs as shown in the code above. For more info, when I'm running Terraform plan I get something similar to what's below: 2020-06-19T06:59:43.4014967Z module.windows.module.testwinvm30.azurerm_network_interface.vmnic: Refreshing state... showing that all resources associated to the VM are part of the module.mac

1 Answers

2
votes

On my understanding that you do not understand the Terraform Import clearly. So I would show you what does it mean.

  1. When you want to import the pre-existing resources, you need to configure the resource in the Terraform files first that how the existing resources configured. And all the resources would be imported into the state files.

  2. Another caveat currently is that only a single resource can be imported into a state file at a time.

When you want to import the resources into a module, I assume the folder structure like this:

testingimportfolder
    └── main.tf
    └── terraform.tfstate
    └── terraform.tfstate.backup
    └───module
          └── main.tf

And the main.tf file in the folder testingimportfolder set the module block liek this:

module "importlab" {
    source = "./module"
    ...
}

And after you finish importing all the resources into the state file, and then you can see the output of the command terraform state list like this:

module.importlab.azurerm_network_security_group.nsg
module.importlab.azurerm_resource_group.rg
module.importlab.azurerm_virtual_network.vnet

All the resource name should like module.module_name.azurerm_xxxx.resource_name. If you use the module inside the module, I assume the folder structure like this:

importmodules
├── main.tf
├── modules
│   └── vm
│       ├── main.tf
│       └── module
│           └── main.tf

And the file importmodules/modules/vm/main.tf like this:

module "azurevm" {
        source = "./module"
        ...
}

Then after you finish importing all the resources into the state file, and then you can see the output of the command terraform state list like this:

module.vm.module.azurevm.azurerm_network_interface.example

Yes, it just likes what you have got. The state file will store your existing resources as you quote the modules one by one. So you need to plan your code and modules carefully and clearly. Or you will make yourself confused.