Creating subnet per availability zones in Azure using terraform - azure

I am trying to create subnets per availability zones in Azure using terraform. I am using the code below to create a subnet.
resource "azurerm_subnet" "public_subnet" {
name = "public_subnet"
virtual_network_name = azurerm_virtual_network.vnet.name
resource_group_name = azurerm_resource_group.terraform_rg.name
address_prefix = "10.20.10.0/24"
}
My requirement is possible in AWS. Since I am new to Azure I am not sure whether it is possible to do the same in Azure. It would be great if some one render their hands to help me.
Thanks in advance!

The azure subnet is not a Zonal service(where a resource is pinned to a specific zone), refer to Azure services and regions that support Availability Zones. So you need to create the specific support services per availability zone.
For example, you can create an Azure VM or Azure public IP per availability zone.
resource "azurerm_resource_group" "example" {
name = "example-resources"
location = "east us"
}
resource "azurerm_public_ip" "example" {
name = "acceptanceTestPublicIp1"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
allocation_method = "Static"
sku = "Standard"
zones = ["1"]
}
resource "azurerm_virtual_network" "example" {
name = "example-network"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
}
resource "azurerm_subnet" "example" {
name = "internal"
resource_group_name = azurerm_resource_group.example.name
virtual_network_name = azurerm_virtual_network.example.name
address_prefix = "10.0.2.0/24"
}
resource "azurerm_network_interface" "example" {
name = "example-nic"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
ip_configuration {
name = "internal"
subnet_id = azurerm_subnet.example.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.example.id
}
}
resource "azurerm_linux_virtual_machine" "example" {
name = "example-machine"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
size = "Standard_F2"
zone = "1"
admin_username = "adminuser"
network_interface_ids = [
azurerm_network_interface.example.id,
]
admin_ssh_key {
username = "adminuser"
public_key = file("~/.ssh/id_rsa.pub")
}
os_disk {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}
source_image_reference {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "16.04-LTS"
version = "latest"
}
}
If you're interested in the zone option, you can look at this open issue.

Related

get ip addresses of azurerm_linux_virtual_machine_scale_set as output

Can I somehow get the internal IP addresses of the created VMs of an azurerm_linux_virtual_machine_scale_set with a fixed amount of instances as output variable?
I went through the documentation but didn't find any export related to the virtual machines created.
I tried to create the Internal IP address of the created vm in my environment and got the below results
The below script I have taken from this terraform URL and modified as per the requirement
locals {
first_public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+wWK73dCr+jgQOAxNsHAnNNNMEMWOHYEccp6wJm2gotpr9katuF/ZAdou5AaW1C61slRkHRkpRRX9FA9CYBiitZgvCCz+3nWNN7l/Up54Zps/pHWGZLHNJZRYyAB6j5yVLMVHIHriY49d/GZTZVNB8GoJv9Gakwc/fuEZYYl4YDFiGMBP///TzlI4jhiJzjKnEvqPFki5p2ZRJqcbCiF4pJrxUQR/RXqVFQdbRLZgYfJ8xGB878RENq3yQ39d8dVOkq4edbkzwcUmwwwkYVPIoDGsYLaRHnG+To7FvMeyO7xDVQkMKzopTQV8AuKpyvpqu0a9pWOMaiCyDytO7GGN you#me.com"
}
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "example" {
name = "example-resourcesabc"
location = "West Europe"
}
resource "azurerm_virtual_network" "example" {
name = "example-networkabc"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
address_space = ["10.0.0.0/16"]
}
resource "azurerm_subnet" "internal" {
name = "internal"
resource_group_name = azurerm_resource_group.example.name
virtual_network_name = azurerm_virtual_network.example.name
address_prefixes = ["10.0.2.0/24"]
}
resource "azurerm_linux_virtual_machine_scale_set" "example" {
name = "vmssabc"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
sku = "Standard_F2"
instances = 3
admin_username = "adminuser"
admin_ssh_key {
username = "adminuser"
public_key = local.first_public_key
}
source_image_reference {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "16.04-LTS"
version = "latest"
}
os_disk {
storage_account_type = "Standard_LRS"
caching = "ReadWrite"
}
network_interface {
name = "example"
primary = true
ip_configuration {
name = "internal"
primary = true
subnet_id = azurerm_subnet.internal.id
}
}
}
Run the following script
terraform init
terraform plan
terraform apply
When I open and check the virtual machine scale set i am able to see the 3 instances created
I opened the Vm instance, I am able to see the terraform created Private IP address

How to use selective zone(s) while deploying azure vm through terraform

I am using the below while deploying a virtual machine to specific zone in region eastus
resource "azurerm_linux_virtual_machine" "vm" {
.........
.........
zones = [1]
}
but terraform validate says
An argument named "zones" is not expected here. Did you mean "zone"?
You should prefer for_each and set to count and index. you can use this transformer code to create a virtual Machine in 3 Availability Zone. You can set the number of Zones according to your needs
provider "azurerm" {
features {}
}
data "azurerm_resource_group" "example" {
name = "XXXXXXXXX"
}
resource "azurerm_virtual_network" "example" {
name = "example-network"
address_space = ["10.0.0.0/16"]
location = data.azurerm_resource_group.example.location
resource_group_name = data.azurerm_resource_group.example.name
}
resource "azurerm_subnet" "example" {
name = "internal"
resource_group_name = data.azurerm_resource_group.example.name
virtual_network_name = azurerm_virtual_network.example.name
address_prefixes = ["10.0.2.0/24"]
}
resource "azurerm_network_interface" "example" {
#count=3
name = "example-nic"
location = data.azurerm_resource_group.example.location
resource_group_name = data.azurerm_resource_group.example.name
ip_configuration {
name = "internal"
subnet_id = azurerm_subnet.example.id
private_ip_address_allocation = "Dynamic"
}
}
resource "azurerm_linux_virtual_machine" "example" {
#count=3
name = "example-machine"
resource_group_name = data.azurerm_resource_group.example.name
location = data.azurerm_resource_group.example.location
size = "Standard_F2"
for_each = local.zones
zone = each.value
admin_username = "adminuser"
network_interface_ids = [
azurerm_network_interface.example.id,
]
admin_ssh_key {
username = "adminuser"
public_key = file("~/.ssh/id_rsa.pub")
}
os_disk {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}
source_image_reference {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "16.04-LTS"
version = "latest"
}
}
locals {
zones = toset(["1","2","3"])
}

Azure VM Creation using For_Each loop via Terraform

I am trying to create multiple Azure VM using for_each via terrform , I am able to create 2 NIC card but while defining NIC id in zurerm_windows_virtual_machine block , both VM are picking same NIC card (last one , index 1) and result is only VM is getting created and other got failed .
what would be logic for (network_interface_ids = azurerm_network_interface.az_nic[*].id) put that 1st vm will pick 1st NIC and second do so .
#---------------creating Network Interface for Windows VM's---------------
resource "azurerm_network_interface" "az_nic" {
count = length(var.vm_names)
name = "${var.vm_names[count.index]}_nic"
location = var.location
resource_group_name = data.azurerm_resource_group.Resource_group.name
ip_configuration {
name = var.vm_names[count.index]
subnet_id = data.azurerm_subnet.subnet.id
private_ip_address_allocation = "Dynamic"
}
}
resource "azurerm_windows_virtual_machine" "myvm" {
for_each = toset(var.vm_names)
name = each.value
resource_group_name = data.azurerm_resource_group.Resource_group.name
location = var.location
size = "Standard_D2s_v3"
admin_username = "abc"
admin_password = "uejehrikch123"
network_interface_ids = azurerm_network_interface.az_nic[*].id
source_image_reference {
publisher = "MicrosoftWindowsServer"
offer = "WindowsServer"
sku = "2016-Datacenter"
version = "latest"
}
os_disk {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}
You can add the count parameter in the resource "azurerm_windows_virtual_machine" instead of mixing the count and for_each.
Suppose you have
variable "vm_names" {
default = ["vm1", "vm2"]
}
then you can change the resource .tf file like this:
resource "azurerm_windows_virtual_machine" "myvm" {
count = length(var.vm_names)
name = element(var.vm_names,count.index)
resource_group_name = data.azurerm_resource_group.Resource_group.name
location = var.location
size = "Standard_D2s_v3"
admin_username = "abc"
admin_password = "uejehrikch123"
network_interface_ids = [element(azurerm_network_interface.az_nic.*.id, count.index)]
source_image_reference {
publisher = "MicrosoftWindowsServer"
offer = "WindowsServer"
sku = "2016-Datacenter"
version = "latest"
}
os_disk {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}

Create multiple VM's in Azure with different configuration

I want to create two vm's with terraform in Azure. I have configured two "azurerm_network_interface" but when I try to apply the changes, I receive an error. Do you have any idea? Is there any issue if I try to create them on different regions?
The error is something like: vm2-nic was not found azurerm_network_interface
# Configure the Azure Provider
provider "azurerm" {
subscription_id = var.subscription_id
tenant_id = var.tenant_id
version = "=2.10.0"
features {}
}
resource "azurerm_virtual_network" "main" {
name = "north-network"
address_space = ["10.0.0.0/16"]
location = "North Europe"
resource_group_name = var.azurerm_resource_group_name
}
resource "azurerm_subnet" "internal" {
name = "internal"
resource_group_name = var.azurerm_resource_group_name
virtual_network_name = azurerm_virtual_network.main.name
address_prefix = "10.0.2.0/24"
}
resource "azurerm_public_ip" "example" {
name = "test-pip"
location = "North Europe"
resource_group_name = var.azurerm_resource_group_name
allocation_method = "Static"
idle_timeout_in_minutes = 30
tags = {
environment = "dev01"
}
}
resource "azurerm_network_interface" "main" {
for_each = var.locations
name = "${each.key}-nic"
location = "${each.value}"
resource_group_name = var.azurerm_resource_group_name
ip_configuration {
name = "testconfiguration1"
subnet_id = azurerm_subnet.internal.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.example.id
}
}
resource "azurerm_virtual_machine" "main" {
for_each = var.locations
name = "${each.key}t-vm"
location = "${each.value}"
resource_group_name = var.azurerm_resource_group_name
network_interface_ids = [azurerm_network_interface.main[each.key].id]
vm_size = "Standard_D2s_v3"
...
Error:
Error: Error creating Network Interface "vm2-nic" (Resource Group "candidate-d7f5a2-rg"): network.InterfacesClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="InvalidResourceReference" Message="Resource /subscriptions/xxxxxxx/resourceGroups/xxxx/providers/Microsoft.Network/virtualNetworks/north-network/subnets/internal referenced by resource /subscriptions/xxxxx/resourceGroups/xxxxx/providers/Microsoft.Network/networkInterfaces/vm2-nic was not found. Please make sure that the referenced resource exists, and that both resources are in the same region." Details=[]
on environment.tf line 47, in resource "azurerm_network_interface" "main":
47: resource "azurerm_network_interface" "main" {
According to the documentation each NIC attached to a VM must exist in the same location (Region) and subscription as the VM. https://learn.microsoft.com/en-us/azure/virtual-machines/windows/network-overview.
If you can re-create the NIC in the same location as the VM or create the VM in the same location as the NIC that will likely solve your problem.
Since you have for_each and in the resource "azurerm_network_interface", it will create two NICs in the location = "${each.value}" while the subnet or VNet has a fixed region "North Europe". You need to create the NICs or other Azure VM related resources like subnets in the same region, you could change the codes like this,
resource "azurerm_resource_group" "test" {
name = "myrg"
location = "West US"
}
variable "locations" {
type = map(string)
default = {
vm1 = "North Europe"
vm2 = "West Europe"
}
}
resource "azurerm_virtual_network" "main" {
for_each = var.locations
name = "${each.key}-network"
address_space = ["10.0.0.0/16"]
location = "${each.value}"
resource_group_name = azurerm_resource_group.test.name
}
resource "azurerm_subnet" "internal" {
for_each = var.locations
name = "${each.key}-subnet"
resource_group_name = azurerm_resource_group.test.name
virtual_network_name = azurerm_virtual_network.main[each.key].name
address_prefix = "10.0.2.0/24"
}
resource "azurerm_public_ip" "example" {
for_each = var.locations
name = "${each.key}-pip"
location = "${each.value}"
resource_group_name = azurerm_resource_group.test.name
allocation_method = "Static"
idle_timeout_in_minutes = 30
}
resource "azurerm_network_interface" "main" {
for_each = var.locations
name = "${each.key}-nic"
location = "${each.value}"
resource_group_name = azurerm_resource_group.test.name
ip_configuration {
name = "testconfiguration1"
subnet_id = azurerm_subnet.internal[each.key].id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.example[each.key].id
}
}

Terraform Vm Provision attached 2 NIC

I am working on provisioning the new azure VM using terraform and attached 2 nic to that VM.
I am getting below error.
azurerm_virtual_machine.vm: compute.VirtualMachinesClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="VirtualMachineMustHaveOneNetworkInterfaceAsPrimary" Message="Virtual machine AZLXSPTOPTFWTEST must have one network interface set as the primary." Details=[]
I have referred https://www.terraform.io/docs/providers/azurerm/r/network_interface.html this URL for creating NIC
This is my Terraform code.
resource "azurerm_resource_group" "main" {
name = "RG-EASTUS-FW-TEST"
location = "eastus"
}
#create a virtual Network
resource "azurerm_virtual_network" "privatenetwork" {
name = "VNET-EASTUS-FWTEST"
address_space = ["10.100.0.0/16"]
location = "${azurerm_resource_group.main.location}"
resource_group_name = "${azurerm_resource_group.main.name}"
}
#create a subnet with externel virtual network
resource "azurerm_subnet" "external"{
name = "SNET-FWTEST-OUT"
virtual_network_name = "${azurerm_virtual_network.privatenetwork.name}"
resource_group_name = "${azurerm_resource_group.main.name}"
address_prefix = "10.100.10.0/24"
}
#Create a public IP address
resource "azurerm_public_ip" "public" {
name = "PFTEST-PUBLIC"
location = "${azurerm_resource_group.main.location}"
resource_group_name = "${azurerm_resource_group.main.name}"
allocation_method = "Static"
}
# Create a Subnet within the Virtual Network
resource "azurerm_subnet" "internal" {
name = "SNET-FWTEST-IN"
virtual_network_name = "${azurerm_virtual_network.privatenetwork.name}"
resource_group_name = "${azurerm_resource_group.main.name}"
address_prefix = "10.100.11.0/24"
}
resource "azurerm_network_interface" "OUT" {
name = "NIC-FWTEST-OUT"
location = "${azurerm_resource_group.main.location}"
resource_group_name = "${azurerm_resource_group.main.name}"
# network_security_group_id = "${azurerm_network_interface.main.id}"
primary = "true"
ip_configuration {
name = "OUT"
subnet_id = "${azurerm_subnet.external.id}"
private_ip_address_allocation = "static"
private_ip_address = "10.100.10.5"
public_ip_address_id = "${azurerm_public_ip.public.id}"
}
}
# Create a network interface for VMs and attach the PIP and the NSG
resource "azurerm_network_interface" "main" {
name = "NIC-FWTEST-IN"
location = "${azurerm_resource_group.main.location}"
resource_group_name = "${azurerm_resource_group.main.name}"
# network_security_group_id = "${azurerm_network_security_group.main.id}"
ip_configuration {
name = "IN"
subnet_id = "${azurerm_subnet.internal.id}"
private_ip_address_allocation = "static"
private_ip_address = "10.100.11.5"
}
}
# Create a new Virtual Machine based on the Golden Image
resource "azurerm_virtual_machine" "vm" {
name = "AZLXSPTOPTFWTEST"
location = "${azurerm_resource_group.main.location}"
resource_group_name = "${azurerm_resource_group.main.name}"
network_interface_ids = ["${azurerm_network_interface.OUT.id}","${azurerm_network_interface.main.id}"]
vm_size = "Standard_DS12_v2"
delete_os_disk_on_termination = true
delete_data_disks_on_termination = true
I am expecting result as provision azure VM with 2 nic.
Thanks In Advance
I got the solution as we need to specify the primary network interface id and add this to the network interface id. As well as we need to add in ipconfiguration while creating network interface.
Please refer below code.
ip_configuration {
name = "OUT"
subnet_id = "${azurerm_subnet.external.id}"
primary = true
private_ip_address_allocation = "static"
private_ip_address = "10.100.10.5"
public_ip_address_id = "${azurerm_public_ip.public.id}"
}
resource "azurerm_virtual_machine" "vm" {
name = "AZLXSPTOPTFWTEST"
location = "${azurerm_resource_group.main.location}"
resource_group_name = "${azurerm_resource_group.main.name}"
network_interface_ids = ["${azurerm_network_interface.main.id}","${azurerm_network_interface.OUT.id}"]
primary_network_interface_id = "${azurerm_network_interface.OUT.id}"
vm_size = "Standard_DS12_v2"
delete_os_disk_on_termination = true
delete_data_disks_on_termination = true

Resources