get ip addresses of azurerm_linux_virtual_machine_scale_set as output - azure

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

Related

How to use in Terraform an image from Azure Marketplace

I'm trying to create a VM in Azure using Terraform. I can create the VM directly in Azure Marketplace. However, I'm interested in using Terraform for that.
It's a Linux VM machine, and I'm aware of the block source_image_reference belonging to the resource azurerm_linux_virtual_machine.
This block looks like this:
source_image_reference {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "16.04-LTS"
version = "latest"
}
How am I supposed to fulfill such block using an image from Azure Marketplace?
Cheers
EDIT 1
The source_image_reference shown above is just an example. Actually, the very example available on Terraform's site. The image I want to use is SQL Server 2019 on Ubuntu Server 20.04 LTS
However, I'd say that the question is more general. I mean, once I find an image in Azure Marketplace, how could I use it in Terraform plans?
I tried in my environment and successfully created Linux virtual machine with image SQL Server 2019 on Ubuntu Server 20.04 LTS
Terraform code:
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "rg" {
name = "example-resources"
location = "eastus"
}
resource "azurerm_virtual_network" "my_terraform_network" {
name = "myVnet"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
}
# Create subnet
resource "azurerm_subnet" "my_terraform_subnet" {
name = "mySubnet"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.my_terraform_network.name
address_prefixes = ["10.0.1.0/24"]
}
# Create public IPs
resource "azurerm_public_ip" "my_terraform_public_ip" {
name = "myPublicIP"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
allocation_method = "Dynamic"
}
# Create Network Security Group and rule
resource "azurerm_network_security_group" "my_terraform_nsg" {
name = "myNetworkSecurityGroup"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
security_rule {
name = "SSH"
priority = 1001
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "22"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}
# Create network interface
resource "azurerm_network_interface" "my_terraform_nic" {
name = "myNIC"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
ip_configuration {
name = "my_nic_configuration"
subnet_id = azurerm_subnet.my_terraform_subnet.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.my_terraform_public_ip.id
}
}
# Connect the security group to the network interface
resource "azurerm_network_interface_security_group_association" "example" {
network_interface_id = azurerm_network_interface.my_terraform_nic.id
network_security_group_id = azurerm_network_security_group.my_terraform_nsg.id
}
# Generate random text for a unique storage account name
resource "random_id" "random_id" {
keepers = {
# Generate a new ID only when a new resource group is defined
resource_group = azurerm_resource_group.rg.name
}
byte_length = 8
}
# Create storage account for boot diagnostics
resource "azurerm_storage_account" "my_storage_account" {
name = "diag${random_id.random_id.hex}"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
account_tier = "Standard"
account_replication_type = "LRS"
}
# Create (and display) an SSH key
resource "tls_private_key" "example_ssh" {
algorithm = "RSA"
rsa_bits = 4096
}
# Create virtual machine
resource "azurerm_linux_virtual_machine" "my_terraform_vm" {
name = "myVM"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
network_interface_ids = [azurerm_network_interface.my_terraform_nic.id]
size = "Standard_DS1_v2"
os_disk {
name = "myOsDisk"
caching = "ReadWrite"
storage_account_type = "Premium_LRS"
}
source_image_reference {
publisher = "MicrosoftSQLServer"
offer = "sql2019-ubuntu2004"
sku = "web"
version = "15.0.221108"
}
computer_name = "myvm"
admin_username = "azureuser"
disable_password_authentication = true
admin_ssh_key {
username = "azureuser"
public_key = tls_private_key.example_ssh.public_key_openssh
}
boot_diagnostics {
storage_account_uri = azurerm_storage_account.my_storage_account.primary_blob_endpoint
}
}
The source image reference for SQL Server 2019 on Ubuntu Server 20.04 LTS
source_image_reference {
publisher = "MicrosoftSQLServer"
offer = "sql2019-ubuntu2004"
sku = "web"
version = "15.0.221108"
}
Console:
Portal:
You can get the version and sku by executing below azure cli commands:
az vm image list --all --publisher="MicrosoftSQLServer" --offer="sql2019-ubuntu2004"
Reference:
Creating an Azure Linux VM with Ubuntu 20.04 with Terraform - Stack Overflow by Teodorico Maziviala

Terraform error: Error: creating Subnet: Original Error: Code="NetcfgInvalidSubnet" Message="Subnet 'internal' is not valid in virtual network

I am trying to create resources in azure using terraform, a SQL server database and also a virtual machine.I get the error.
│ Error: creating Subnet: (Name "db_subnetn" / Virtual Network Name "tf_dev-network" / Resource Group "terraform_youtube"): network.SubnetsClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="NetcfgInvalidSubnet" Message="Subnet 'db_subnetn' is not valid in virtual network 'tf_dev-network'." Details=[]
What have I done ?
followed the link here Error while provisioning Terraform subnet using azurerm
I deleted other network resources using thesame IP range.
My network understanding is pretty basic, however from my research it appears that 10.0.0.0/16 is quite a large IP range and can lead to overlaps. So what did I do, I changed the virtual network IP range from 10.0.0.0/16 to 10.0.1.0/24 to restrict the range, what simply happened is that the error changed to
│ Error: creating Subnet: (Name "internal" / Virtual Network Name "tf_dev-network" / Resource Group "terraform_youtube"): network.SubnetsClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="NetcfgInvalidSubnet" Message="Subnet 'internal' is not valid in virtual network 'tf_dev-network'." Details=[]
At this stage, I would be grateful if someone can explain what is going wrong here and what needs to be done. Thanks in advance
My files are as follows.
dbcode.tf
resource "azurerm_sql_server" "sqlserver" {
name = "tom556sqlserver"
resource_group_name = azurerm_resource_group.resource_gp.name
location = azurerm_resource_group.resource_gp.location
version = "12.0"
administrator_login = "khdfd9898rerer"
administrator_login_password = "4-v3ry-jlhdfdf89-p455w0rd"
tags = {
environment = "production"
}
}
resource "azurerm_sql_virtual_network_rule" "sqlvnetrule" {
name = "sql_vnet_rule"
resource_group_name = azurerm_resource_group.resource_gp.name
server_name = azurerm_sql_server.sqlserver.name
subnet_id = azurerm_subnet.db_subnet.id
}
resource "azurerm_subnet" "db_subnet" {
name = "db_subnetn"
resource_group_name = azurerm_resource_group.resource_gp.name
virtual_network_name = azurerm_virtual_network.main.name
address_prefixes = ["10.0.2.0/24"]
service_endpoints = ["Microsoft.Sql"]
}
main.tf
resource "azurerm_resource_group" "resource_gp" {
name="terraform_youtube"
location = "UK South"
tags = {
"owner" = "Rahman"
"purpose" = "Practice terraform"
}
}
variable "prefix" {
default = "tf_dev"
}
resource "azurerm_virtual_network" "main" {
name = "${var.prefix}-network"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.resource_gp.location
resource_group_name = azurerm_resource_group.resource_gp.name
}
resource "azurerm_subnet" "internal" {
name = "internal"
resource_group_name = azurerm_resource_group.resource_gp.name
virtual_network_name = azurerm_virtual_network.main.name
address_prefixes = ["10.0.2.0/24"]
}
resource "azurerm_network_interface" "main" {
name = "${var.prefix}-nic"
location = azurerm_resource_group.resource_gp.location
resource_group_name = azurerm_resource_group.resource_gp.name
ip_configuration {
name = "testconfiguration1"
subnet_id = azurerm_subnet.internal.id
private_ip_address_allocation = "Dynamic"
}
}
resource "azurerm_virtual_machine" "main" {
name = "${var.prefix}-vm"
location = azurerm_resource_group.resource_gp.location
resource_group_name = azurerm_resource_group.resource_gp.name
network_interface_ids = [azurerm_network_interface.main.id]
vm_size = "Standard_B1ls"
# Uncomment this line to delete the OS disk automatically when deleting the VM
delete_os_disk_on_termination = true
# Uncomment this line to delete the data disks automatically when deleting the VM
delete_data_disks_on_termination = true
storage_image_reference {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "16.04-LTS"
version = "latest"
}
storage_os_disk {
name = "myosdisk1"
caching = "ReadWrite"
create_option = "FromImage"
managed_disk_type = "Standard_LRS"
}
os_profile {
computer_name = "hostname"
admin_username = "testadmin"
admin_password = "Password1234!"
}
os_profile_linux_config {
disable_password_authentication = false
}
tags = {
environment = "staging"
}
}
Tested with your code in my environment was getting the same error.
To fix the issue you need to change address_prefixes for db_subnet to ["10.0.3.0/24"] as ["10.0.2.0/24"] address range is already using by internal subnet in your main.tf and also check update for sqlvnetrule and do the changes in your dbcode.tf file.
resource "azurerm_mssql_server" "sqlserver" {
name = "tom556sqlserver"
resource_group_name = azurerm_resource_group.resource_gp.name
location = azurerm_resource_group.resource_gp.location
version = "12.0"
administrator_login = "khdfd9898rerer"
administrator_login_password = "4-v3ry-jlhdfdf89-p455w0rd"
tags = {
environment = "production"
}
}
resource "azurerm_subnet" "db_subnet" {
name = "db_subnetn"
resource_group_name = azurerm_resource_group.resource_gp.name
virtual_network_name = azurerm_virtual_network.main.name
address_prefixes = ["10.0.3.0/24"]
service_endpoints = ["Microsoft.Sql"]
}
resource "azurerm_mssql_virtual_network_rule" "sqlvnetrule" {
name = "sql_vnet_rule"
#resource_group_name = azurerm_resource_group.resource_gp.name
#server_name = azurerm_sql_server.sqlserver.name
server_id = azurerm_mssql_server.sqlserver.id
subnet_id = azurerm_subnet.db_subnet.id
}

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"])
}

Creating Azure Spot Instances with Terraform

I'm trying to create an Azure spot instance with Terraform. I saw this discussion How do I request azure spot instances using terraform, in a virtual machine scale set?
I still couldn't figure out how provision Azure spot instances with terraform. Then I found this repo https://github.com/terraform-providers/terraform-provider-azurerm/tree/master/examples/vm-scale-set/linux
I used the examples from the repo to come up with my own terraform code. I pushed it to gitlab here's the link..https://gitlab.com/cloud-projectz/azure-spot-terraform.git
Basically what I'm trying to achieve is the creation of a spot instance or spot instances with public ip and ssh access while automating network security rules. When I run terraform apply everything seems to go okay. Then I notice that the public IP is not attached to the spot vm!!
I can't figure out how to access the spot vm!!
there's also a bash script in the repo that kind of outlines what I attend to accomplish with terraform.
Anybody help me with this? Azure spot vm via terraform with public ip and ssh access?
Thank You
Regarding the issue, please refer to the following script
provider "azurerm" {
version = "~>2.0"
features {}
}
resource "azurerm_resource_group" "example" {
name = "example-resources"
location = "East Asia"
}
resource "azurerm_virtual_network" "example" {
name = "example-network"
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_network_security_group" "example" {
name = "allow-ssh"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
security_rule {
name = "SSH"
priority = 1001
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "22"
source_address_prefix = "<IP address>"
destination_address_prefix = "*"
}
}
resource "azurerm_public_ip_prefix" "example" {
name = "example-pip"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
}
resource "azurerm_linux_virtual_machine_scale_set" "example" {
name = "example-vmss"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
sku = "Standard_F2"
instances = 1
admin_username = "azure"
eviction_policy = "Deallocate"
priority = "Spot"
max_bid_price = 0.5
admin_ssh_key {
username = "azure"
public_key = file("/root/.ssh/Azure.pub")
}
source_image_reference {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "18.04-LTS"
version = "latest"
}
network_interface {
name = "interface"
primary = true
network_security_group_id= azurerm_network_security_group.example.id
ip_configuration {
name = "internal"
primary = true
subnet_id = azurerm_subnet.internal.id
public_ip_address {
name = "first"
public_ip_prefix_id = azurerm_public_ip_prefix.example.id
}
}
}
os_disk {
storage_account_type = "Standard_LRS"
caching = "ReadWrite"
}
}
To summarise from the other answer: you need to use a VM scale set, and use the priority setting in azurerm_linux_virtual_machine_scale_set:
priority - (Optional) The Priority of this Virtual Machine Scale Set. Possible values are Regular and Spot. Defaults to Regular. Changing this value forces a new resource.
When priority is set to Spot an eviction_policy must be specified.
Azure reference: https://learn.microsoft.com/en-us/azure/virtual-machines/spot-vms

Creating subnet per availability zones in Azure using terraform

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.

Resources