I am creating a virtual network using Terraform and the subnets are created within the virtual network resource block (instead of using its own resource block).
I am trying to associate some route tables to the subnets, however I'm not sure how to obtain the subnet resource ID when the subnets are created within virtual network, could someone help?
main.tf
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "3.24.0"
}
}
}
provider "azurerm" {
skip_provider_registration = true
features {}
}
###########################
# RESOURCE GROUP CREATION #
###########################
resource "azurerm_resource_group" "rg" {
name = var.rg.name
location = var.rg.location
}
############################
# VIRTUAL NETWORK CREATION #
############################
resource "azurerm_virtual_network" "vnet" {
name = var.vnet.name
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
address_space = var.vnet.address_space
dns_servers = var.vnet.dns_servers
subnet {
name = var.vnet.subnet1_name
address_prefix = var.vnet.subnet1_address_prefix
}
subnet {
name = var.vnet.subnet2_name
address_prefix = var.vnet.subnet2_address_prefix
}
subnet {
name = var.vnet.subnet3_name
address_prefix = var.vnet.subnet3_address_prefix
}
subnet {
name = var.vnet.subnet4_name
address_prefix = var.vnet.subnet4_address_prefix
}
subnet {
name = var.vnet.subnet5_name
address_prefix = var.vnet.subnet5_address_prefix
}
}
########################
# ROUTE TABLE CREATION #
########################
resource "azurerm_route_table" "fslogix_rt" {
name = var.rt.fslogix.name
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
disable_bgp_route_propagation = false
}
resource "azurerm_route_table" "back_office_rt" {
name = var.rt.back_office.name
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
disable_bgp_route_propagation = false
}
resource "azurerm_route_table" "dev_dev_rt" {
name = var.rt.dev_dev.name
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
disable_bgp_route_propagation = false
}
resource "azurerm_route_table" "dev_prod_rt" {
name = var.rt.dev_prod.name
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
disable_bgp_route_propagation = false
}
resource "azurerm_route_table" "front_office_rt" {
name = var.rt.front_office.name
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
disable_bgp_route_propagation = false
}
##################
# ROUTE CREATION #
##################
resource "azurerm_route" "fslogix_routes" {
for_each = var.fslogix_routes
name = each.value.name
resource_group_name = azurerm_resource_group.rg.name
route_table_name = azurerm_route_table.fslogix_rt.name
address_prefix = each.value.address_prefix
next_hop_type = each.value.next_hop_type
next_hop_in_ip_address = each.value.next_hop_in_ip_address
}
resource "azurerm_route" "back_office_routes" {
for_each = var.back_office_routes
name = each.value.name
resource_group_name = azurerm_resource_group.rg.name
route_table_name = azurerm_route_table.back_office_rt.name
address_prefix = each.value.address_prefix
next_hop_type = each.value.next_hop_type
next_hop_in_ip_address = each.value.next_hop_in_ip_address
}
resource "azurerm_route" "dev_dev_routes" {
for_each = var.developer_dev_routes
name = each.value.name
resource_group_name = azurerm_resource_group.rg.name
route_table_name = azurerm_route_table.dev_dev_rt.name
address_prefix = each.value.address_prefix
next_hop_type = each.value.next_hop_type
next_hop_in_ip_address = each.value.next_hop_in_ip_address
}
resource "azurerm_route" "dev_prod_routes" {
for_each = var.developer_prod_routes
name = each.value.name
resource_group_name = azurerm_resource_group.rg.name
route_table_name = azurerm_route_table.dev_prod_rt.name
address_prefix = each.value.address_prefix
next_hop_type = each.value.next_hop_type
next_hop_in_ip_address = each.value.next_hop_in_ip_address
}
resource "azurerm_route" "front_office_routes" {
for_each = var.front_office_routes
name = each.value.name
resource_group_name = azurerm_resource_group.rg.name
route_table_name = azurerm_route_table.front_office_rt.name
address_prefix = each.value.address_prefix
next_hop_type = each.value.next_hop_type
next_hop_in_ip_address = each.value.next_hop_in_ip_address
}
###########################
# ROUTE TABLE ASSOICATION #
###########################
resource "azurerm_subnet_route_table_association" "fslogix_rta" {
subnet_id = ???????????????????????????????????????
route_table_id = azurerm_route_table.fslogix_rt.id
}
You can get all the subnet_id with:
azurerm_virtual_network.vnet.subnet.*.id
You can get the first subnet_id with:
azurerm_virtual_network.vnet.subnet.*.id[0]
And the second subnet_id with:
azurerm_virtual_network.vnet.subnet.*.id[1]
And go on...
Hope this helps!
Related
I want to create a cluster inside a VNET, so that later I can create a connection to the on-premise resources.
I have following problem:
│ Error: Unsupported argument │ │ on main.tf line 130, in resource "azurerm_kubernetes_cluster" "aks": │ 130: user_assigned_identity_id = azurerm_user_assigned_identity.identity.id │ │ An argument named "user_assigned_identity_id" is not expected here.
My main.tf:
`
data "azurerm_resource_group" "aks-rg" {
name = var.resource_group_name
}
resource "azurerm_role_assignment" "role_acrpull" {
scope = azurerm_container_registry.acr.id
role_definition_name = "AcrPull"
principal_id = azurerm_kubernetes_cluster.aks.kubelet_identity.0.object_id
#skip_service_principal_aad_check = true
}
resource "azurerm_container_registry" "acr" {
name = var.acr_name
resource_group_name = data.azurerm_resource_group.aks-rg.name
location = var.location
sku = "Standard"
admin_enabled = false
}
resource "azurerm_network_security_group" "pusg" {
name = "Public_Security_Group"
location = var.location
resource_group_name = data.azurerm_resource_group.aks-rg.name
}
resource "azurerm_virtual_network" "puvnet" {
name = "Public_VNET"
location = var.location
resource_group_name = data.azurerm_resource_group.aks-rg.name
address_space = ["10.19.0.0/16"]
dns_servers = ["10.19.0.4", "10.19.0.5"]
}
resource "azurerm_subnet" "osubnet" {
name = "Outer_Subnet"
resource_group_name = data.azurerm_resource_group.aks-rg.name
address_prefixes = ["10.19.1.0/24"]
virtual_network_name = azurerm_virtual_network.puvnet.name
}
resource "azurerm_subnet" "isubnet" {
name = "Inner_Subnet"
resource_group_name = data.azurerm_resource_group.aks-rg.name
address_prefixes = ["10.19.2.0/24"]
virtual_network_name = azurerm_virtual_network.puvnet.name
}
resource "azurerm_subnet" "firewall_subnet" {
name = "AzureFirewallSubnet"
resource_group_name = data.azurerm_resource_group.aks-rg.name
virtual_network_name = azurerm_virtual_network.puvnet.name
address_prefixes = ["10.19.3.0/24"]
}
resource "azurerm_user_assigned_identity" "identity" {
resource_group_name = data.azurerm_resource_group.aks-rg.name
location = var.location
name = "identityh"
}
resource "azurerm_role_assignment" "networkRole" {
scope = data.azurerm_resource_group.aks-rg.id
role_definition_name = "Network Contributor"
principal_id = azurerm_user_assigned_identity.identity.principal_id
}
resource "azurerm_route_table" "routeTable" {
name = "rt-FWall"
location = var.location
resource_group_name = data.azurerm_resource_group.aks-rg.name
}
resource "azurerm_route" "route1" {
name = "dg-route1"
resource_group_name = data.azurerm_resource_group.aks-rg.name
route_table_name = azurerm_route_table.routeTable.name
address_prefix = "0.0.0.0/0"
next_hop_type = "VirtualAppliance"
next_hop_in_ip_address = azurerm_firewall.firewall.ip_configuration.0.private_ip_address
}
resource "azurerm_subnet_route_table_association" "base" {
subnet_id = azurerm_subnet.osubnet.id
route_table_id = azurerm_route_table.routeTable.id
}
resource "azurerm_public_ip" "firewall_public_ip" {
name = "pip-firewall"
location = var.location
resource_group_name = data.azurerm_resource_group.aks-rg.name
allocation_method = "Static"
sku = "Standard"
}
resource "azurerm_firewall" "firewall" {
name = "public_firewall"
location = var.location
resource_group_name = data.azurerm_resource_group.aks-rg.name
sku_name = "AZFW_VNet"
sku_tier = "Standard"
ip_configuration {
name = "ipconfig"
subnet_id = azurerm_subnet.firewall_subnet.id
public_ip_address_id = azurerm_public_ip.firewall_public_ip.id
}
}
resource "azurerm_kubernetes_cluster" "aks" {
name = var.cluster_name
kubernetes_version = var.kubernetes_version
location = var.location
resource_group_name = data.azurerm_resource_group.aks-rg.name
dns_prefix = var.cluster_name
network_profile {
network_plugin = "azure"
outbound_type = "userDefinedRouting"
}
default_node_pool {
name = "system"
node_count = var.system_node_count
vm_size = "Standard_DS2_v2"
vnet_subnet_id = azurerm_subnet.osubnet.id
}
identity {
type = "UserAssigned"
user_assigned_identity_id = azurerm_user_assigned_identity.identity.id
}
}
`
Region is Germany West Central. Kubernetes version 1.24.3, Azurerm 3.33, Terraform 1.3
I have tried different approaches I found over internet, but none seemed to work. Best case scenario is when creation takes too long and terraform stops without creating cluster.
That argument does not seem to be a part of the identity block. The argument that can be used inside of the identity block is identity_ids [1]:
resource "azurerm_kubernetes_cluster" "aks" {
name = var.cluster_name
kubernetes_version = var.kubernetes_version
location = var.location
resource_group_name = data.azurerm_resource_group.aks-rg.name
dns_prefix = var.cluster_name
network_profile {
network_plugin = "azure"
outbound_type = "userDefinedRouting"
}
default_node_pool {
name = "system"
node_count = var.system_node_count
vm_size = "Standard_DS2_v2"
vnet_subnet_id = azurerm_subnet.osubnet.id
}
identity {
type = "UserAssigned"
identity_ids = [azurerm_user_assigned_identity.identity.id]
}
}
Note that the identity_ids argument is a list, hence the square brackets around the identity.
[1] https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/kubernetes_cluster#identity_ids
I need to test my azure private-endpoint using the following scenario.
We have a virtual netwroks with two sub-nets (vm_subnet and storage_account_subnet)
The virtual-machine (vm) should be able to connect to the storage-account using a private-link.
So, the below image explains the scenario:
and then i need to test my endpoint using the below manual test-case:
Connect to the azure virtual-machine using ssh and putty username: adminuser and password: P#$$w0rd1234!
In the terminal ping formuleinsstorage.blob.core.windows.net (Expect to see the ip of storage account in the range of storage_account_subnet (10.0.2.0/24))
I deploy all the infrastructure using the below Terraform code:
provider "azurerm" {
features {
resource_group {
prevent_deletion_if_contains_resources = false
}
}
}
resource "azurerm_resource_group" "main_resource_group" {
name = "RG-Terraform-on-Azure"
location = "West Europe"
}
# Create Virtual-Network
resource "azurerm_virtual_network" "virtual_network" {
name = "Vnet"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.main_resource_group.location
resource_group_name = azurerm_resource_group.main_resource_group.name
}
# Create subnet for virtual-machine
resource "azurerm_subnet" "virtual_network_subnet" {
name = "vm_subnet"
resource_group_name = azurerm_resource_group.main_resource_group.name
virtual_network_name = azurerm_virtual_network.virtual_network.name
address_prefixes = ["10.0.1.0/24"]
}
# Create subnet for storage account
resource "azurerm_subnet" "storage_account_subnet" {
name = "storage_account_subnet"
resource_group_name = azurerm_resource_group.main_resource_group.name
virtual_network_name = azurerm_virtual_network.virtual_network.name
address_prefixes = ["10.0.2.0/24"]
}
# Create Linux Virtual machine
resource "azurerm_linux_virtual_machine" "example" {
name = "example-machine"
location = azurerm_resource_group.main_resource_group.location
resource_group_name = azurerm_resource_group.main_resource_group.name
size = "Standard_F2"
admin_username = "adminuser"
admin_password = "14394Las?"
disable_password_authentication = false
network_interface_ids = [
azurerm_network_interface.virtual_machine_network_interface.id,
]
os_disk {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}
source_image_reference {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "16.04-LTS"
version = "latest"
}
}
resource "azurerm_network_interface" "virtual_machine_network_interface" {
name = "vm-nic"
location = azurerm_resource_group.main_resource_group.location
resource_group_name = azurerm_resource_group.main_resource_group.name
ip_configuration {
name = "internal"
subnet_id = azurerm_subnet.virtual_network_subnet.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.vm_public_ip.id
}
}
# Create Network-interface and public-ip for virtual-machien
resource "azurerm_public_ip" "vm_public_ip" {
name = "vm-public-ip-for-rdp"
location = azurerm_resource_group.main_resource_group.location
resource_group_name = azurerm_resource_group.main_resource_group.name
allocation_method = "Static"
sku = "Standard"
}
resource "azurerm_network_interface" "virtual_network_nic" {
name = "vm_nic"
location = azurerm_resource_group.main_resource_group.location
resource_group_name = azurerm_resource_group.main_resource_group.name
ip_configuration {
name = "testconfiguration1"
subnet_id = azurerm_subnet.virtual_network_subnet.id
private_ip_address_allocation = "Dynamic"
}
}
# Setup an Inbound rule because we need to connect to the virtual-machine using RDP (remote-desktop-protocol)
resource "azurerm_network_security_group" "traffic_rules" {
name = "vm_traffic_rules"
location = azurerm_resource_group.main_resource_group.location
resource_group_name = azurerm_resource_group.main_resource_group.name
security_rule {
name = "virtual_network_permission"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "*"
source_port_range = "*"
destination_port_range = "22"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}
resource "azurerm_subnet_network_security_group_association" "private_nsg_asso" {
subnet_id = azurerm_subnet.virtual_network_subnet.id
network_security_group_id = azurerm_network_security_group.traffic_rules.id
}
# Setup storage_account and its container
resource "azurerm_storage_account" "storage_account" {
name = "storagaccountfortest"
location = azurerm_resource_group.main_resource_group.location
resource_group_name = azurerm_resource_group.main_resource_group.name
account_tier = "Standard"
account_replication_type = "LRS"
account_kind = "StorageV2"
is_hns_enabled = "true"
}
resource "azurerm_storage_data_lake_gen2_filesystem" "data_lake_storage" {
name = "rawdata"
storage_account_id = azurerm_storage_account.storage_account.id
lifecycle {
prevent_destroy = false
}
}
# Setup DNS zone
resource "azurerm_private_dns_zone" "dns_zone" {
name = "privatelink.blob.core.windows.net"
resource_group_name = azurerm_resource_group.main_resource_group.name
}
resource "azurerm_private_dns_zone_virtual_network_link" "network_link" {
name = "vnet_link"
resource_group_name = azurerm_resource_group.main_resource_group.name
private_dns_zone_name = azurerm_private_dns_zone.dns_zone.name
virtual_network_id = azurerm_virtual_network.virtual_network.id
}
# Setup private-link
resource "azurerm_private_endpoint" "endpoint" {
name = "storage-private-endpoint"
location = azurerm_resource_group.main_resource_group.location
resource_group_name = azurerm_resource_group.main_resource_group.name
subnet_id = azurerm_subnet.storage_account_subnet.id
private_service_connection {
name = "private-service-connection"
private_connection_resource_id = azurerm_storage_account.storage_account.id
is_manual_connection = false
subresource_names = ["blob"]
}
}
resource "azurerm_private_dns_a_record" "dns_a" {
name = "dns-record"
zone_name = azurerm_private_dns_zone.dns_zone.name
resource_group_name = azurerm_resource_group.main_resource_group.name
ttl = 10
records = [azurerm_private_endpoint.endpoint.private_service_connection.0.private_ip_address]
}
The problem is, my endpoint does not work ! But, if i try to add the service-endpoint manually then everything works well like a charm. So,i think, my DNS Zone is correct, also apparently the link to the storage-account is also working well. So, I think there should be something wrong with my private-link ! Any idea ?
Update:
Here are versions:
Terraform v1.2.5
on windows_386
+ provider registry.terraform.io/hashicorp/azurerm v3.30.0
I believe the issue lies in the name of the dns_a_record. This should be the name of the storage account you want to reach via the private link.
The following Terraform code is working for me:
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "=3.30.0"
}
}
}
provider "azurerm" {
features {
resource_group {
prevent_deletion_if_contains_resources = false
}
}
}
resource "azurerm_resource_group" "main_resource_group" {
name = "RG-Terraform-on-Azure"
location = "West Europe"
}
# Create Virtual-Network
resource "azurerm_virtual_network" "virtual_network" {
name = "Vnet"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.main_resource_group.location
resource_group_name = azurerm_resource_group.main_resource_group.name
}
# Create subnet for virtual-machine
resource "azurerm_subnet" "virtual_network_subnet" {
name = "vm_subnet"
resource_group_name = azurerm_resource_group.main_resource_group.name
virtual_network_name = azurerm_virtual_network.virtual_network.name
address_prefixes = ["10.0.1.0/24"]
}
# Create subnet for storage account
resource "azurerm_subnet" "storage_account_subnet" {
name = "storage_account_subnet"
resource_group_name = azurerm_resource_group.main_resource_group.name
virtual_network_name = azurerm_virtual_network.virtual_network.name
address_prefixes = ["10.0.2.0/24"]
}
# Create Linux Virtual machine
resource "azurerm_linux_virtual_machine" "example" {
name = "example-machine"
location = azurerm_resource_group.main_resource_group.location
resource_group_name = azurerm_resource_group.main_resource_group.name
size = "Standard_F2"
admin_username = "adminuser"
admin_password = "14394Las?"
disable_password_authentication = false
network_interface_ids = [
azurerm_network_interface.virtual_machine_network_interface.id,
]
os_disk {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}
source_image_reference {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "16.04-LTS"
version = "latest"
}
}
resource "azurerm_network_interface" "virtual_machine_network_interface" {
name = "vm-nic"
location = azurerm_resource_group.main_resource_group.location
resource_group_name = azurerm_resource_group.main_resource_group.name
ip_configuration {
name = "internal"
subnet_id = azurerm_subnet.virtual_network_subnet.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.vm_public_ip.id
}
}
# Create Network-interface and public-ip for virtual-machien
resource "azurerm_public_ip" "vm_public_ip" {
name = "vm-public-ip-for-rdp"
location = azurerm_resource_group.main_resource_group.location
resource_group_name = azurerm_resource_group.main_resource_group.name
allocation_method = "Static"
sku = "Standard"
}
resource "azurerm_network_interface" "virtual_network_nic" {
name = "storage-private-endpoint-nic"
location = azurerm_resource_group.main_resource_group.location
resource_group_name = azurerm_resource_group.main_resource_group.name
ip_configuration {
name = "storage-private-endpoint-ip-config"
subnet_id = azurerm_subnet.virtual_network_subnet.id
private_ip_address_allocation = "Dynamic"
}
}
# Setup an Inbound rule because we need to connect to the virtual-machine using RDP (remote-desktop-protocol)
resource "azurerm_network_security_group" "traffic_rules" {
name = "vm_traffic_rules"
location = azurerm_resource_group.main_resource_group.location
resource_group_name = azurerm_resource_group.main_resource_group.name
security_rule {
name = "virtual_network_permission"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "*"
source_port_range = "*"
destination_port_range = "22"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}
resource "azurerm_subnet_network_security_group_association" "private_nsg_asso" {
subnet_id = azurerm_subnet.virtual_network_subnet.id
network_security_group_id = azurerm_network_security_group.traffic_rules.id
}
# Setup storage_account and its container
resource "azurerm_storage_account" "storage_account" {
name = <STORAGE_ACCOUNT_NAME>
location = azurerm_resource_group.main_resource_group.location
resource_group_name = azurerm_resource_group.main_resource_group.name
account_tier = "Standard"
account_replication_type = "LRS"
account_kind = "StorageV2"
is_hns_enabled = "true"
}
resource "azurerm_storage_data_lake_gen2_filesystem" "data_lake_storage" {
name = "rawdata"
storage_account_id = azurerm_storage_account.storage_account.id
lifecycle {
prevent_destroy = false
}
}
# Setup DNS zone
resource "azurerm_private_dns_zone" "dns_zone" {
name = "privatelink.blob.core.windows.net"
resource_group_name = azurerm_resource_group.main_resource_group.name
}
resource "azurerm_private_dns_zone_virtual_network_link" "network_link" {
name = "vnet-link"
resource_group_name = azurerm_resource_group.main_resource_group.name
private_dns_zone_name = azurerm_private_dns_zone.dns_zone.name
virtual_network_id = azurerm_virtual_network.virtual_network.id
}
# Setup private-link
resource "azurerm_private_endpoint" "endpoint" {
name = "storage-private-endpoint"
location = azurerm_resource_group.main_resource_group.location
resource_group_name = azurerm_resource_group.main_resource_group.name
subnet_id = azurerm_subnet.storage_account_subnet.id
private_service_connection {
name = "storage-private-service-connection"
private_connection_resource_id = azurerm_storage_account.storage_account.id
is_manual_connection = false
subresource_names = ["blob"]
}
}
resource "azurerm_private_dns_a_record" "dns_a" {
name = azurerm_storage_account.storage_account.name
zone_name = azurerm_private_dns_zone.dns_zone.name
resource_group_name = azurerm_resource_group.main_resource_group.name
ttl = 10
records = [azurerm_private_endpoint.endpoint.private_service_connection.0.private_ip_address]
}
Additionally, I'm not sure whether it is possible to ping storage accounts. To test I ran nslookup <STORAGE_ACCOUNT_NAME>.blob.core.windows.net both from my local machine and from the Azure VM. In the former case, I got a public IP while in the latter I got a private IP in the range defined in the Terraform config, which seems to be the behaviour you are looking for.
I am trying to setup a databricks into subet and protect it by firewalls using the following code in Terraform:
Setup resource group:
provider "azurerm" {
features {
resource_group {
prevent_deletion_if_contains_resources = false
}
}
}
resource "azurerm_resource_group" "main_resource_group" {
name = var.resource_group_name
location = var.resource_group_location
}
Setup virtual network:
resource "azurerm_virtual_network" "test_vnet" {
name = var.vnet_name
address_space = ["10.0.0.0/16"]
location = var.resource_group_location
resource_group_name = var.resource_group_name
}
Setup subnets:
resource "azurerm_subnet" "private_snet" {
name = "subnet-private"
resource_group_name = var.resource_group_name
virtual_network_name = var.vnet_name
address_prefixes = ["10.0.1.0/24"]
delegation {
name = "databricksprivatermdelegation"
service_delegation {
name = "Microsoft.Databricks/workspaces"
}
}
}
resource "azurerm_subnet" "public_snet" {
name = "subnet-public"
resource_group_name = var.resource_group_name
virtual_network_name = var.vnet_name
address_prefixes = ["10.0.2.0/24"]
delegation {
name = "databrickspublicdelegation"
service_delegation {
name = "Microsoft.Databricks/workspaces"
}
}
}
Setup firewals:
resource "azurerm_network_security_group" "private_empty_nsg" {
name = "firewall-private"
location = var.resource_group_location
resource_group_name = var.resource_group_name
}
resource "azurerm_subnet_network_security_group_association" "private_nsg_asso" {
subnet_id = azurerm_subnet.private_snet.id
network_security_group_id = azurerm_network_security_group.private_empty_nsg.id
}
resource "azurerm_network_security_group" "public_empty_nsg" {
name = "firewall-public"
location = var.resource_group_location
resource_group_name = var.resource_group_name
}
resource "azurerm_subnet_network_security_group_association" "public_nsg_asso" {
subnet_id = azurerm_subnet.public_snet.id
network_security_group_id = azurerm_network_security_group.public_empty_nsg.id
}
And finally setup the databricks:
resource "azurerm_databricks_workspace" "forex_price_databricks" {
name = "databricks-test"
location = var.resource_group_location
resource_group_name = var.resource_group_name
sku = "standard"
custom_parameters {
virtual_network_id = azurerm_virtual_network.test_vnet.id
public_subnet_name = azurerm_subnet.public_snet.name
public_subnet_network_security_group_association_id = azurerm_network_security_group.public_empty_nsg.id
private_subnet_name = azurerm_subnet.private_snet.name
private_subnet_network_security_group_association_id = azurerm_network_security_group.private_empty_nsg.id
}
}
However, when i run the code in the first try i got the below error:
Error: Code="ResourceNotFound" Message="The Resource 'Microsoft.Network/virtualNetworks/my-vnet' under resource group 'My-Resource-Group' was not found.
So, the question is:
Why the Virtual Network is not created ? or cannot be found ?
Update:
When i remove the
resource_group {
prevent_deletion_if_contains_resources = false
}
I used to have this line, becuse i usually run the terraform destroy and i don't want t remove my resource group. However, even if i remove it ,I got the below error:
Message="Operation was canceled." Details=[{"code":"
CanceledAndSupersededDueToAnotherOperation","message":"Operation PutVirtualNetworkOperation was canceled and superseded by operation PutSubnetOpe
ration
Are you able to reproduce the same error ?
Im quite new to Terraform so maybe i make a very basic mistake but after multiple hours maybe here someone can help me out.
So i tried to peer to vlans together. I viewed multiple tutorials about it and the only difference between my configuration i can see is that i want to make a peering between 2 vlans that are in 2 different resource groups. I also noticed that if i put the peering in one of the 2 vlan ressource groups i have fever errors.
error
#Creating Resource Groups
resource "azurerm_resource_group" "network" {
name = "network"
location = "West Europe"
}
resource "azurerm_resource_group" "front" {
name = "front"
location = "West Europe"
}
resource "azurerm_resource_group" "middle" {
name = "middle"
location = "West Europe"
}
resource "azurerm_resource_group" "back" {
name = "back"
location = "West Europe"
}
resource "azurerm_resource_group" "peerings" {
name = "peerings"
location = "West Europe"
}
#Creating Virtual Networks
resource "azurerm_virtual_network" "network" {
name = "network"
location = azurerm_resource_group.network.location
resource_group_name = azurerm_resource_group.network.name
address_space = ["10.1.0.0/16"]
subnet {
name = "default"
address_prefix = "10.1.0.0/24"
}
subnet {
name = "gatewaysubnet"
address_prefix = "10.1.1.0/24"
}
subnet {
name = "azurefirewallsubnet"
address_prefix = "10.1.3.0/24"
}
subnet {
name = "azurebastionsubnet"
address_prefix = "10.1.2.0/24"
}
}
resource "azurerm_virtual_network" "front" {
name = "network"
location = azurerm_resource_group.front.location
resource_group_name = azurerm_resource_group.front.name
address_space = ["10.2.0.0/16"]
}
resource "azurerm_virtual_network" "middle" {
name = "network"
location = azurerm_resource_group.middle.location
resource_group_name = azurerm_resource_group.middle.name
address_space = ["10.3.0.0/16"]
}
resource "azurerm_virtual_network" "back" {
name = "network"
location = azurerm_resource_group.back.location
resource_group_name = azurerm_resource_group.back.name
address_space = ["10.4.0.0/16"]
}
#Create peerings
#network <--> front
resource "azurerm_virtual_network_peering" "networktofront" {
name = "networktofront"
resource_group_name = azurerm_resource_group.peerings.name
virtual_network_name = azurerm_virtual_network.network.name
remote_virtual_network_id = azurerm_virtual_network.front.id
}
resource "azurerm_virtual_network_peering" "fronttonetwork" {
name = "fronttonetwork"
resource_group_name = azurerm_resource_group.peerings.name
virtual_network_name = azurerm_virtual_network.front.name
remote_virtual_network_id = azurerm_virtual_network.network.id
}
#network <--> middle
resource "azurerm_virtual_network_peering" "networktomiddle" {
name = "networktomiddle"
resource_group_name = azurerm_resource_group.peerings.name
virtual_network_name = azurerm_virtual_network.network.name
remote_virtual_network_id = azurerm_virtual_network.middle.id
}
resource "azurerm_virtual_network_peering" "middletonetwork" {
name = "middletonetwork"
resource_group_name = azurerm_resource_group.peerings.name
virtual_network_name = azurerm_virtual_network.middle.name
remote_virtual_network_id = azurerm_virtual_network.network.id
}
#network <--> back
resource "azurerm_virtual_network_peering" "networktoback" {
name = "networktoback"
resource_group_name = azurerm_resource_group.peerings.name
virtual_network_name = azurerm_virtual_network.network.name
remote_virtual_network_id = azurerm_virtual_network.back.id
}
resource "azurerm_virtual_network_peering" "backtonetwork" {
name = "backtonetwork"
resource_group_name = azurerm_resource_group.peerings.name
virtual_network_name = azurerm_virtual_network.back.name
remote_virtual_network_id = azurerm_virtual_network.network.id
}
Virtual Network Peerings are a subset of the Virtual Network Resource (Microsoft.Network/virtualNetworks/network/virtualNetworkPeerings) and it is therefore not possible to carve these out into different resource groups.
Besides that, your code is accurate and should work as soon as you create the peerings in the corresponding virtual network resource groups:
#Creating Resource Groups
resource "azurerm_resource_group" "network" {
name = "network"
location = "West Europe"
}
resource "azurerm_resource_group" "front" {
name = "front"
location = "West Europe"
}
resource "azurerm_resource_group" "middle" {
name = "middle"
location = "West Europe"
}
resource "azurerm_resource_group" "back" {
name = "back"
location = "West Europe"
}
#Creating Virtual Networks
resource "azurerm_virtual_network" "network" {
name = "network"
location = azurerm_resource_group.network.location
resource_group_name = azurerm_resource_group.network.name
address_space = ["10.1.0.0/16"]
subnet {
name = "default"
address_prefix = "10.1.0.0/24"
}
subnet {
name = "gatewaysubnet"
address_prefix = "10.1.1.0/24"
}
subnet {
name = "azurefirewallsubnet"
address_prefix = "10.1.3.0/24"
}
subnet {
name = "azurebastionsubnet"
address_prefix = "10.1.2.0/24"
}
}
resource "azurerm_virtual_network" "front" {
name = "network"
location = azurerm_resource_group.front.location
resource_group_name = azurerm_resource_group.front.name
address_space = ["10.2.0.0/16"]
}
resource "azurerm_virtual_network" "middle" {
name = "network"
location = azurerm_resource_group.middle.location
resource_group_name = azurerm_resource_group.middle.name
address_space = ["10.3.0.0/16"]
}
resource "azurerm_virtual_network" "back" {
name = "network"
location = azurerm_resource_group.back.location
resource_group_name = azurerm_resource_group.back.name
address_space = ["10.4.0.0/16"]
}
#Create peerings
#network <--> front
resource "azurerm_virtual_network_peering" "networktofront" {
name = "networktofront"
resource_group_name = azurerm_resource_group.network.name
virtual_network_name = azurerm_virtual_network.network.name
remote_virtual_network_id = azurerm_virtual_network.front.id
}
resource "azurerm_virtual_network_peering" "fronttonetwork" {
name = "fronttonetwork"
resource_group_name = azurerm_resource_group.front.name
virtual_network_name = azurerm_virtual_network.front.name
remote_virtual_network_id = azurerm_virtual_network.network.id
}
#network <--> middle
resource "azurerm_virtual_network_peering" "networktomiddle" {
name = "networktomiddle"
resource_group_name = azurerm_resource_group.network.name
virtual_network_name = azurerm_virtual_network.network.name
remote_virtual_network_id = azurerm_virtual_network.middle.id
}
resource "azurerm_virtual_network_peering" "middletonetwork" {
name = "middletonetwork"
resource_group_name = azurerm_resource_group.middle.name
virtual_network_name = azurerm_virtual_network.middle.name
remote_virtual_network_id = azurerm_virtual_network.network.id
}
#network <--> back
resource "azurerm_virtual_network_peering" "networktoback" {
name = "networktoback"
resource_group_name = azurerm_resource_group.network.name
virtual_network_name = azurerm_virtual_network.network.name
remote_virtual_network_id = azurerm_virtual_network.back.id
}
resource "azurerm_virtual_network_peering" "backtonetwork" {
name = "backtonetwork"
resource_group_name = azurerm_resource_group.back.name
virtual_network_name = azurerm_virtual_network.back.name
remote_virtual_network_id = azurerm_virtual_network.network.id
}
Error Message
I get the following error message when executing terraform apply:
Error: Error Creating/Updating Virtual Network "CTI-NETWORK" (Resource Group "CTI-RESOURCES"): network.VirtualNetworksClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="InUseSubnetCannotBeDeleted" Message="Subnet CTI-PRD is in use by /subscriptions/d92e8f07-e127-4015-b67a-a547af76fdfc/resourceGroups/CTI-RESOURCES/providers/Microsoft.Network/networkInterfaces/CTI-NIC-PRD1/ipConfigurations/CTI-IP-PRD1 and cannot be deleted. In order to delete the subnet, delete all the resources within the subnet. See aka.ms/deletesubnet." Details=[]
I assume I've got a dependency mixed up but cant seem to figure it out.
Code Snippet
Content of main.tf
provider "azurerm" {
version = "=1.38.0"
subscription_id = "d92e8f07-e127-4015-b67a-a547af76fdfc"
}
resource "azurerm_resource_group" "resourcegroup" {
name = "${var.prefix}RESOURCES"
location = var.location
}
resource "azurerm_virtual_network" "network" {
name = "${var.prefix}NETWORK"
resource_group_name = azurerm_resource_group.resourcegroup.name
address_space = ["10.0.0.0/16"]
location = var.location
}
resource "azurerm_subnet" "prd-subnet" {
name = "${var.prefix}PRD"
resource_group_name = azurerm_resource_group.resourcegroup.name
virtual_network_name = azurerm_virtual_network.network.name
address_prefix = "10.0.0.0/24"
}
resource "azurerm_subnet" "tst-subnet" {
name = "${var.prefix}TST"
resource_group_name = azurerm_resource_group.resourcegroup.name
virtual_network_name = azurerm_virtual_network.network.name
address_prefix = "10.0.1.0/24"
}
resource "azurerm_public_ip" "ip-prd-1" {
name = "${var.prefix}PIP-PRD1"
resource_group_name = azurerm_resource_group.resourcegroup.name
location = var.location
allocation_method = "Dynamic"
domain_name_label = "vm-prd-1"
}
resource "azurerm_network_interface" "nic-prd-1" {
name = "${var.prefix}NIC-PRD1"
resource_group_name = azurerm_resource_group.resourcegroup.name
location = var.location
ip_configuration {
name = "${var.prefix}IP-PRD1"
subnet_id = azurerm_subnet.prd-subnet.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.ip-prd-1.id
}
}
resource "azurerm_virtual_machine" "vm-prd-1" {
name = "${var.prefix}VM-PRD-1"
location = var.location
resource_group_name = azurerm_resource_group.resourcegroup.name
network_interface_ids = [azurerm_network_interface.nic-prd-1.id]
vm_size = var.size
delete_os_disk_on_termination = true
delete_data_disks_on_termination = true
storage_image_reference {
publisher = "credativ"
offer = "Debian"
sku = "9-backports"
version = "latest"
}
storage_os_disk {
name = "lin-disk-1"
caching = "ReadWrite"
create_option = "FromImage"
managed_disk_type = "Standard_LRS"
}
os_profile {
computer_name = "${var.prefix}IP-PRD1"
admin_username = "ADM-ADV"
admin_password = "!!W0rksh0p"
}
os_profile_linux_config {
disable_password_authentication = false
}
tags = {
environment = "Production"
application = "CTI Core"
}
}
resource "azurerm_public_ip" "ip-prd-2" {
name = "${var.prefix}PIP-PRD-2"
resource_group_name = azurerm_resource_group.resourcegroup.name
location = var.location
allocation_method = "Dynamic"
domain_name_label = "vm-prd-2"
}
resource "azurerm_network_interface" "nic-prd-2" {
name = "${var.prefix}NIC-PRD-2"
resource_group_name = azurerm_resource_group.resourcegroup.name
location = var.location
ip_configuration {
name = "${var.prefix}IP-PRD-2"
subnet_id = azurerm_subnet.prd-subnet.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.ip-prd-2.id
}
}
resource "azurerm_virtual_machine" "vm-prd-chef" {
name = "${var.prefix}VM-PRD-CHEF"
location = var.location
resource_group_name = azurerm_resource_group.resourcegroup.name
network_interface_ids = [azurerm_network_interface.nic-prd-2.id]
vm_size = var.size
delete_os_disk_on_termination = true
delete_data_disks_on_termination = true
storage_image_reference {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "18.04-LTS"
version = "latest"
}
storage_os_disk {
name = "lin-disk-2"
caching = "ReadWrite"
create_option = "FromImage"
managed_disk_type = "Standard_LRS"
}
os_profile {
computer_name = "${var.prefix}IP-PRD-CHEF"
admin_username = "XXX"
admin_password = "XXX"
}
os_profile_linux_config {
disable_password_authentication = false
}
tags = {
environment = "Production"
application = "CTI Service"
}
provisioner "remote-exec" {
inline = [
"touch /root/test.txt"
]
}
}
Content of variables.tf
variable "prefix" {
type = string
default = "CTI-"
description = "Prefix of the resources"
}
variable "location" {
type = string
default = "westeurope"
description = "Location of the resources"
}
variable "size" {
type = string
default = "Standard_A1_v2"
description = "Size of the virtual machines"
}
Thanks for you help!
With the message you provided, you want to create another VM in the existing subnet of the Vnet. So you need to use the data resource instead of the resource format. Change your Terraform code like this:
Change:
resource "azurerm_virtual_network" "network" {
name = "${var.prefix}NETWORK"
resource_group_name = azurerm_resource_group.resourcegroup.name
address_space = ["10.0.0.0/16"]
location = var.location
}
resource "azurerm_subnet" "prd-subnet" {
name = "${var.prefix}PRD"
resource_group_name = azurerm_resource_group.resourcegroup.name
virtual_network_name = azurerm_virtual_network.network.name
address_prefix = "10.0.0.0/24"
}
Into:
data "azurerm_virtual_network" "network" {
name = "${var.prefix}NETWORK"
resource_group_name = azurerm_resource_group.resourcegroup.name
}
data "azurerm_subnet" "prd-subnet" {
name = "${var.prefix}PRD"
virtual_network_name = data.azurerm_virtual_network.network.name
resource_group_name = azurerm_resource_group.resourcegroup.name
}
resource "azurerm_network_interface" "nic-prd-1" {
name = "${var.prefix}NIC-PRD1"
resource_group_name = azurerm_resource_group.resourcegroup.name
location = var.location
ip_configuration {
name = "${var.prefix}IP-PRD1"
subnet_id = data.azurerm_subnet.prd-subnet.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.ip-prd-1.id
}
}
The Terraform data will quote the existing resource and do not change them. If the other subnet tst-subnet is also existing, you can change it like above yourself.