Retrieve location of VNET through Terraform - azure

I want to pull the VNET location using just the azurerm_virtual_network data resource. Terraform's documentation says teh location attribute is available, but it is not working for me.
Here is my code:
data "azurerm_virtual_network" "vnet" {
name = "my-vnet"
resource_group_name = "my-vnet-resource-group"
}
output "LOCATION" {
value = "${data.azurerm_virtual_network.vnet.location}"
}
This is the error message I am receiving..
output.LOCATION: Resource 'data.azurerm_virtual_network.vnet'
does not have attribute 'location' for variable
'data.azurerm_virtual_network.vnet.location'
Any help getting around this is sincerely appreciated!

So doesn't seem there is a way to do it through the azurerm_virtual_network data resource. However, I was able to get it working by using the azurerm_resource_group data resource in conjunction with azurerm_virtual_network.
data "azurerm_virtual_network" "vnet" {
name = "my-vnet"
resource_group_name = "my-vnet-resource-group"
}
data "azurerm_resource_group" "rg" {
name = "${data.azurerm_virtual_network.vnet.resource_group_name}"
}
output "LOCATION" {
value = "${data.azurerm_resource_group.rg.location}"
}

according to this it is not possible. honestly, terraform is just bad ;)

Related

Terraform returning the path of Azure Resource Group instead of ID

I'm using Terraform to manage my Infrastructure and Terratest for Testing.
In terraform, I have a module called ResourceGroup (located in the Modules folder)
resource "azurerm_resource_group" "azResourceGroup" {
name = var.resource_group_name
location = var.resource_region
tags = var.tags
}
output "resource_group_name" {
value = azurerm_resource_group.azResourceGroup.id
}
And I'm using this module in the main.tf to create an Azure Resource Group.
module "azResourceGroup" {
source = "./Modules/ResourceGroup"
resource_group_name = var.resource_group_name
tags = var.tags
}
output "resource_group_name" {
value = "${module.azResourceGroup.resource_group_name}"
}
When I execute terraform apply the output of main.tf is returning the full path of the newly created Resource Group instead of its ID.
Here's the Output
Changes to Outputs:
- resource_group_name = "/subscriptions/xxxxxxx-xxxx-xxxx-xxxx-x/resourceGroups/rg-svf-nprd-test" -> null
Preferably, it should return only rg-svf-nprd-test (Id from output variable).
Am I missing anything here? Please help me with this.

Terraform can't create resource in group already exist

I would create a sample azure web app using Terraform.
I use this code to create the resoucre.
This is my main.tf file :
resource "azurerm_resource_group" "rg" {
name = var.rgname
location = var.rglocation
}
resource "azurerm_app_service_plan" "plan" {
name = var.webapp_plan_name
location = var.rglocation
resource_group_name = var.rgname
sku {
tier = var.plan_settings["tier"]
size = var.plan_settings["size"]
capacity = var.plan_settings["capacity"]
}
}
resource "azurerm_app_service" "webapp" {
name = var.webapp_name
location = var.rglocation
resource_group_name = var.rgname
app_service_plan_id = azurerm_app_service_plan.plan.id
}
and this is the variable.tf
# variables for Resource Group
variable "rgname" {
description = "(Required)Name of the Resource Group"
type = string
default = "example-rg"
}
variable "rglocation" {
description = "Resource Group location like West Europe etc."
type = string
default = "eastus2"
}
# variables for web app plan
variable "webapp_plan_name" {
description = "Name of webapp"
type = string
default = "XXXXXXXXXx"
}
variable "plan_settings" {
type = map(string)
description = "Definition of the dedicated plan to use"
default = {
kind = "Linux"
size = "S1"
capacity = 1
tier = "Standard"
}
}
variable "webapp_name" {
description = "Name of webapp"
type = string
default = "XXXXXXXX"
}
The terraform apply --auto-approve show a error :
Error: creating/updating App Service Plan "XXXXXXXXXXX" (Resource Group "example-rg"): web.AppServicePlansClient#CreateOrUpdate: Failure sending request: StatusCode=0 -- Original Error: Code="ResourceGroupNotFound" Message="Resource group 'example-rg' could not be found."
but in Azure Portal , the ressource group is created
what's wrong in my code ?
Can i hold on Terraform to check if resource is created or not before pass to next resource ?
You need to reference the resources to indicate the dependency between them to terraform, so that it can guarantee, that the resource group is created first, and then the other resources. The error indicates, that the resource group does not exist, yet. Your code tries to create the ASP first and then the RG.
resource "azurerm_resource_group" "rg" {
name = var.rgname
location = var.rglocation
}
resource "azurerm_app_service_plan" "plan" {
...
resource_group_name = azurerm_resource_group.rg.name
...
}
... but I can't use variable?
To answer that question and give more detail about the current issue, what's happening in your original code is that you're not referencing terraform resources in a way that terraform can use to create its dependency graph.
if var.rgname equals <my-rg-name> and azurerm_resource_group.rg.name also equals <my-rg-name> then technically, that's the same, right?
Well, no, not necessarily. They indeed have the same value. The difference is that the first one just echos the value. The second one contains the same value but it's also instruction to terraform saying, "Hey, wait a minute. We need the name value from azurerm_resource_group.rg so let me make sure I set that up first, and then I'll provision this resource"
The difference is subtle but important. Using values in this way lets Terraform understand what it has to provision first and lets it create its dependency graph. Using variables alone does not. Especially in large projects, alway try to use the resource variable value instead of just input variables which will help avoid unnecessary issues.
It's quite common to use an input variable to define certain initial data, like the name of the resource group as you did above. After that, however, every time resource_group_name is referenced in the manifests you should always use terraform generated value, so resource_group_name = azurerm_resource_group.rg.name

How to use existing resources from another resource group to make deployments in new resource group using Terraform

I want to create resources in a new resource group but i want to use a virtual network for those resources which is in another resource group. How do i do this? For example, i want to create redis/postgresql in resourcegroupA but i want to make use of the virtual network which is in resourcegroupB. Is it possible?
This is the resource group from where i am retrieving the vnet-
resource "azurerm_resource_group" "azresourcegroup" {
name =
"resourcegroupA"
location = var.resource_group_location
}
#-----CREATING VIRTUAL NETWORK-----
resource "azurerm_virtual_network" "vnet2" {
name = "virtualnetworkA"
location = azurerm_resource_group.azresourcegroup.location
resource_group_name = azurerm_resource_group.azresourcegroup.name
address_space = [var.virtual_network_address_prefix_infra,var.virtual_network_address_prefix]
I retrieved it while using it for another resource group like this-
data "azurerm_resource_group" "azresourcegroup" {
name = "resoucegroupA"
}
data "azurerm_virtual_network" "vnet2" {
name = "virtualnetworkA"
resource_group_name = data.azurerm_resource_group.azresourcegroup.name
}
I want to use the above virtual network but want to create the other resources in the new resource group which is-
resource "azurerm_resource_group" "main" {
name = "resourcegroupB"
location = var.resource_group_location
}
I am making use of module to create redis cache that requires the vnet which is created in other RG-
module "rediscache" {
source = "../../modules/rediscache"
prefix = var.prefix
environmentType = var.environmentType
virtual_network_name = var.virtual_network_name
unique_identifier = var.unique_identifier_kube
resource_group_name = azurerm_resource_group.main.name
resource_group_location = var.resource_group_location
redis_subnet_address_prefix = var.redis_subnet_address_prefix
azurerm_virtual_network_name = data.azurerm_virtual_network.vnet2.name
azurerm_log_analytics_workspace_id = azurerm_log_analytics_workspace.workspace.id
}
To simplify this, vnet is created in other resource group and redis in another one.But i want to use that vnet. also if i change the resource group name argument used in module, from azurerm_resource_group.main.name to data.azurerm_resource_group.azresourcegroup.name then it creates the redis in the 1st resource group which i dont want.
Please help.
Of course, it's possible. The only condition is that the virtual network should be in the same location. Then you can quote it in the Terraform code via the Terraform Data Source azurerm_virtual_network like this:
data "azurerm_virtual_network" "example" {
name = "production"
resource_group_name = "networking"
}

Pull subnet ID from existing resource

In Terraform, I want to build a Azure route table and assign it to an existing subnet. To do this, I need the subnet_id. Is there an easy way to pull this information into Terraform?
Below is the route table association resource I am using.
resource "azurerm_subnet_route_table_association" "test" {
subnet_id = "${data.azurerm_subnet.spoke.subnet_id}"
route_table_id = "${module.routetable.routetable_id}"
}
Assuming you already set up data.azurerm_subnet.spoke, it looks like your mistake is using subnet_id instead of just id.
resource "azurerm_subnet_route_table_association" "test" {
subnet_id = "${data.azurerm_subnet.spoke.id}"
route_table_id = "${module.routetable.routetable_id}"
}
The documentation shows which values are available under Attributes Reference.
If you haven't set up the data source, it should look something like this:
data "azurerm_subnet" "spoke" {
name = "<NAME>"
virtual_network_name = "<VIRTUAL_NETWORK_NAME>"
resource_group_name = "<RESOURCE_GROUP_NAME>"
}

Creating a resource group with terraform in azure: Cannot find resource group directly after creating it

I'm about to create a small VM with terraform in azure and have come across a curious problem. Terraform creates my resource group but immediately fails when creating the next object (a VNet) that is part of the resource group:
resource "azurerm_resource_group" "simple_vm" {
name = "simple_vm"
location = "westeurope"
}
resource "azurerm_virtual_network" "main" {
name = "main"
address_space = ["10.0.0.0/16"]
location = "westeurope"
resource_group_name = "simple_vm"
}
Calling terraform apply results in:
* azurerm_virtual_network.main: 1 error(s) occurred:
* azurerm_virtual_network.main: Error Creating/Updating Virtual Network "main" (Resource Group "simple_vm"): network.VirtualNetworksClient#CreateOrUpdate: Failure sending request: StatusCode=0 -- Original Error: autorest/azure: Service returned an error. Status=404 Code="ResourceGroupNotFound" Message="Resource group 'simple_vm' could not be found."
Looking at the web interface shows, the resource group has been created. Calling terraform apply a second time correctly finds it and creates the VNet inside the resource group.
To me this looks like terraform tries to create objects in the resource group while it is not yet fully instantiated in azure. I've observed a similar behavior with public IPs: I've created a VM with a public IP and included an output ... to print the public ip of the VM. On the first run, the output is empty (no error message though). After terraform refresh the output is filled with the IP.
Am I doing something wrong? Is this a bug in terraform?
You need to create an implicit dependency like this:
resource "azurerm_virtual_network" "main" {
name = "main"
address_space = ["10.0.0.0/16"]
location = "westeurope"
resource_group_name = "${azurerm_resource_group.simple_vm.name}"
}
In this way, Terraform knows that it will need to create the Resource Group first before it can create the vNet.
From Terraform's perspective, your original code simply has 2 independent resources.
Terraform's documentation on this is useful. In general, you don't want to set up explicit (depends_on) dependencies unless you absolutely have to.
Make sure you have your "provider" values exported properly before running plan and apply. Sometimes terraform might not know which subscription/resource group it needs to associate and hence, resource not found(404 error) might occur.
You are trying to use the resource group created using the code at the top (azurerm_resource_group.simple_vm.name)
I can also see that you are using the same location so you can set in the vnet module the location like follow:
azurerm_resource_group.simple_location
So your code should look like this
resource "azurerm_resource_group" "simple_vm" {
name = "simple_vm"
location = "westeurope"
}
resource "azurerm_virtual_network" "main" {
name = "main"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.simple_vm.location
resource_group_name = azurerm_resource_group.simple_vm.name
}
I had the same problem with terraform 1.1.9 and a reference to the resource group (name = azurerm_resource_group.simple_vm.name).
With terraform 0.13 and up, you can specify explicit dependencies with the depends_on input:
resource "azurerm_resource_group" "simple_vm" {
name = "simple_vm"
location = "westeurope"
}
resource "azurerm_virtual_network" "main" {
name = "main"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.simple_vm.location
resource_group_name = azurerm_resource_group.simple_vm.name
depends_on = [azurerm_resource_group.simple_vm]
}
Thanks to the other answers and comments, I realized I forgot to specify the dependencies.

Resources