Vinod K
Vinod K

Reputation: 1

Terraform Data source is not picking subnet or resource group properly

I started writing terraform to automate the iac for provisioning VMs in Azure. However I wrote the entire code but am unable to use the existing subnet/vnet/resource group properly.

main.tf

    # Configure the Microsoft Azure Provider

provider "azurerm" {
    # The "feature" block is required for AzureRM provider 2.x. 
    # If you're using version 1.x, the "features" block is not allowed.
    #version = "~>2.20.0"
    features {}
    subscription_id = var.subscription_id
    tenant_id = var.tenant_id
    client_id = var.client_id
    client_secret = var.client_secret
}

#terraform {
 # backend "azurerm" {
  #  snapshot = true
  #}
#}

# Refer to resource group

data "azurerm_resource_group" "nwrk_group" {
  name = var.nwrk_resource_group
}

data "azurerm_resource_group" "resource_group" {
  name = var.resource_group
}

# Refer to a subnet
data "azurerm_subnet" "subnet" {
  name                 = var.nwrk_subnet_name
  virtual_network_name = var.nwrk_name
  resource_group_name  = data.azurerm_resource_group.nwrk_group.name
}

# Refer to Network Security Group and rule
data "azurerm_network_security_group" "nwrk_security_group" {
    name                = var.nwrk_security_grp
    resource_group_name = data.azurerm_resource_group.nwrk_group.name
}

module "vm" {
    source = "../modules/windows_vm"
    node = var.node
    node_username = var.node_username
    node_password = var.node_password
    tags = var.tags
    deployment_environment = var.deployment_environment
    nwrk_group_location = data.azurerm_resource_group.resource_group.location
    nwrk_group_name = data.azurerm_resource_group.resource_group.name
    subnet_id = data.azurerm_subnet.subnet.id
    nwrk_security_group_id = data.azurerm_network_security_group.nwrk_security_group.id
    resource_group_location = data.azurerm_resource_group.resource_group.location
    resource_group_name   = data.azurerm_resource_group.resource_group.name
}

terraform.tfvars

tags = {
        project = "SEPS_Terraform"
        environment = "test_tfm"
    }
deployment_environment = "DEV"

node_username = "saz76test"
node_password = "SA82nd2"

nwrk_subnet_name = "SUBNET_45_0"

node = {
    general_info = {
      name                = "gateway.test.com"
      private_ip          = "153.78.51.92"
      vm_template         = "Standard_B2s"
      disk_type           = "StandardSSD_LRS"
      nwrk_resource_group = "SWS_LAB_36_192"
      nwrk_name           = "SUB_VNET_36_192"
      nwrk_security_group = "N-Untrusted"
      nwrk_subnet_name    = "SUB_51_0"
    }
    os_image = {
      publisher = "MicrosoftWindowsServer"
      offer     = "WindowsServer"
      sku       = "2019-DataCenter"
      version   = "latest"
    }
    storage_disk = {
      type    = "StandardSSD_LRS"
      size    = 256
    }
  }

variables.tf

   variable "subscription_id" {
        type = string
        description = "Azure subscription id to provision infra."
    }
    
    variable "tenant_id" {
        type = string
        description = "Azure subscription tenant id"
    }
    
    variable "client_id" {
        type = string
        description = "App id to authenticate to azure."
    }
    
    variable "client_secret" {
        type = string
        description = "App password to authenticate to azure"
    }
    
    variable "resource_group" {
        type = string
        description = "Resource group in which resources will be added other than network resources"
    }
    
    variable "nwrk_resource_group" {
        type = string
        description = "Resource group for network resources"
    }
    
    variable "nwrk_name" {
        type = string
        description = "VPC network name where the network resources belong to"
    }
    
    variable "nwrk_subnet_name" {
        type = string
        description = "Subnet of the VPC network"
    }
    
    variable "nwrk_security_grp" {
        type = string
        description = "Security group to which the network belong to"
    }
    
    variable "tags" {
        type = map(string)
        description = "Tags to attach to resources"
    }
    
    variable "deployment_environment" {
        type = string
        description = "Environment these VMs belong to"
    }
    
    variable "node" {
        type = map(map(string))
        description = "web node with specifications."
    }
    
    variable "node_username" {
        type = string
        description = "Login username for node"
    }
    
    variable "node_password" {
        type = string
        description = "Login password for node"
    }

module_code:

     # Create network interface
resource "azurerm_network_interface" "nic" {
    name                      = "${var.node["general_info"]["name"]}_nic"
    location                  = var.nwrk_group_location
    resource_group_name       = var.nwrk_group_name

    ip_configuration {
        name                          = "${var.node["general_info"]["name"]}_nicConfiguration"
        subnet_id                     = var.subnet_id
        private_ip_address_allocation = "Static"
        private_ip_address            = var.node["general_info"]["private_ip"]
    }

    tags = var.tags
}

# Connect the security group to the network interface
resource "azurerm_network_interface_security_group_association" "example" {
    network_interface_id      = azurerm_network_interface.nic.id
    network_security_group_id = var.nwrk_security_group_id
}

resource "azurerm_windows_virtual_machine" "vm" {
    name                  = var.node["general_info"]["name"]
    location              = var.resource_group_location
    resource_group_name   = var.resource_group_name
    network_interface_ids = [azurerm_network_interface.nic.id]
    size                  = var.node["general_info"]["vm_template"]

    computer_name  = var.node["general_info"]["name"]
    admin_username = var.node_username
    admin_password = var.node_password

    os_disk {
      name              = "${var.node["general_info"]["name"]}-osDisk"
      caching           = "ReadWrite"
      storage_account_type = var.node["general_info"]["disk_type"]
    }

    source_image_reference {
      publisher = var.node["os_image"]["publisher"]
      offer     = var.node["os_image"]["offer"]
      sku       = var.node["os_image"]["sku"]
      version   = var.node["os_image"]["version"]
    }

    tags = var.tags
}

output "vm_id" {
  value = azurerm_windows_virtual_machine.vm.id
}

output "vm_name" {
  value = azurerm_windows_virtual_machine.vm.name
}

output "vm_ip_address" {
  value = azurerm_network_interface.nic.private_ip_address
}

My code is above one which am trying to execute init working but plan is failing to do. Can someone please help me on this what I am missing. ?? The error is getting like it.

Error :

 Warning: Value for undeclared variable
│
│ The root module does not declare a variable named "nwrk_security_group" but a value was found in file "subscription.tfvars". If you meant to use 
│ this value, add a "variable" block to the configuration.
│
│ To silence these warnings, use TF_VAR_... environment variables to provide certain "global" settings to all configurations in your organization. 
│ To reduce the verbosity of these warnings, use the -compact-warnings option.
╵
╷
│ Warning: Resource targeting is in effect
│
│ You are creating a plan with the -target option, which means that the result of this plan may not represent all of the changes requested by the  
│ current configuration.
│
│ The -target option is not for routine use, and is provided only for exceptional situations such as recovering from errors or mistakes, or when   
│ Terraform specifically suggests to use it as part of an error message.
╵
╷
│ Error: Error: Subnet "SUBNET_45_0" (Virtual Network "SUB_VNET_36_192" / Resource Group "SWS_LAB_36_192") was not found
│
│   with data.azurerm_subnet.subnet,
│   on main.tf line 31, in data "azurerm_subnet" "subnet":
│   31: data "azurerm_subnet" "subnet" {
│
╵
╷
│ Error: Error: Network Security Group "NSG" (Resource Group "SWS_LAB_36_192") was not found
│
│   with data.azurerm_network_security_group.nwrk_security_group,
│   on main.tf line 38, in data "azurerm_network_security_group" "nwrk_security_group":
│   38: data "azurerm_network_security_group" "nwrk_security_group" {

Subscription.tfvars

subscription_id = "fdssssssssssssss"
client_id = "sdsdsdsdsdsdsdsdsdsdsdsd"
client_secret = ".dssssssssssssssssss
tenant_id = "asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf"
resource_group = "SWS_LAB_36_192"
nwrk_resource_group = "SWS_LAB_36_192"
nwrk_name = "SUB_VNET_36_192"
nwrk_security_group = "N-Untrusted"

Upvotes: 0

Views: 1961

Answers (1)

Marko E
Marko E

Reputation: 18213

There could potentially be many different problems because I am not sure what the outlook of the root module and child modules are, but as per the error you are getting, it seems that the value defined for the variable in the subscription.tfvars is not being declared anywhere and the one that is supposed to be declared is missing, the data source does not return anything, hence there is the error from the child module as well. Currently it is defined as:

variable "nwrk_security_grp" {
  type = string
  description = "Security group to which the network belong to"
}

If you take a look at the values in subscription.tfvars, there is no nwrk_security_grp, but there is a nwrk_security_group. One option to fix this would probably be to change the name of the variable in the variables.tf:

variable "nwrk_security_group" {
  type = string
  description = "Security group to which the network belong to"
}

In that case, you would have to adapt the data source to use the new variable name:

data "azurerm_network_security_group" "nwrk_security_group" {
    name                = var.nwrk_security_group
    resource_group_name = data.azurerm_resource_group.nwrk_group.name
}

Alternatively (and probably easier), you can change the name of the variable you are assigning the value to in subscription.tfvars:

nwrk_security_grp = "N-Untrusted" # it was nwrk_security_group

What I would strongly suggest going forward is to keep the naming convention for the variables the same because this way you will get into a lot of issues.

Upvotes: 0

Related Questions