Skip to content

Instantly share code, notes, and snippets.

@jinnosux
Created March 13, 2025 22:28
Show Gist options
  • Save jinnosux/74cb065144259aaa751b4eeea9ae06c2 to your computer and use it in GitHub Desktop.
Save jinnosux/74cb065144259aaa751b4eeea9ae06c2 to your computer and use it in GitHub Desktop.
# Assignment 2 - Vahid Konicanin
#
# Terraform code to deploy an Azure infrastructure with a virtual network, subnet, network security group,
# and two virtual machines (Windows and Linux), each with its own public IP address.
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "=3.0.0"
}
}
}
provider "azurerm" {
features {}
}
variable "prefix" {
description = "Resource prefix"
default = "demo"
}
variable "location" {
description = "Azure region"
default = "East US"
}
variable "admin_username" {
description = "VM admin username"
default = "adminuser"
}
variable "admin_password" {
description = "VM admin password"
sensitive = true
}
# VM configurations
locals {
vms = {
"win" = {
os_type = "windows"
size = "Standard_D2s_v3"
image = {
publisher = "MicrosoftWindowsServer"
offer = "WindowsServer"
sku = "2022-Datacenter"
version = "latest"
}
},
"linux" = {
os_type = "linux"
size = "Standard_B1s"
image = {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "18.04-LTS"
version = "latest"
}
}
}
# Common tags
tags = {
environment = "development"
project = "azure-demo"
}
}
# Resource Group
resource "azurerm_resource_group" "main" {
name = "${var.prefix}-rg"
location = var.location
tags = local.tags
}
# Network resources
resource "azurerm_virtual_network" "main" {
name = "${var.prefix}-vnet"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
tags = local.tags
}
resource "azurerm_subnet" "main" {
name = "${var.prefix}-subnet"
resource_group_name = azurerm_resource_group.main.name
virtual_network_name = azurerm_virtual_network.main.name
address_prefixes = ["10.0.1.0/24"]
}
# Network Security Group with common rules
resource "azurerm_network_security_group" "main" {
name = "${var.prefix}-nsg"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
tags = local.tags
# SSH access
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 = "*"
}
# RDP access
security_rule {
name = "RDP"
priority = 1002
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "3389"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}
# Virtual machines and their dependencies
resource "azurerm_public_ip" "vm" {
for_each = local.vms
name = "${var.prefix}-${each.key}-ip"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
allocation_method = "Dynamic"
tags = local.tags
}
resource "azurerm_network_interface" "vm" {
for_each = local.vms
name = "${var.prefix}-${each.key}-nic"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
tags = local.tags
ip_configuration {
name = "internal"
subnet_id = azurerm_subnet.main.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.vm[each.key].id
}
}
# Associate NSG with NICs
resource "azurerm_network_interface_security_group_association" "vm" {
for_each = local.vms
network_interface_id = azurerm_network_interface.vm[each.key].id
network_security_group_id = azurerm_network_security_group.main.id
}
# Create VMs using for_each
resource "azurerm_virtual_machine" "vm" {
for_each = local.vms
name = "${var.prefix}-${each.key}"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
network_interface_ids = [azurerm_network_interface.vm[each.key].id]
vm_size = each.value.size
tags = local.tags
delete_os_disk_on_termination = true
delete_data_disks_on_termination = true
storage_image_reference {
publisher = each.value.image.publisher
offer = each.value.image.offer
sku = each.value.image.sku
version = each.value.image.version
}
storage_os_disk {
name = "${var.prefix}-${each.key}-osdisk"
caching = "ReadWrite"
create_option = "FromImage"
managed_disk_type = "Standard_LRS"
}
os_profile {
computer_name = "${each.key}vm"
admin_username = var.admin_username
admin_password = var.admin_password
}
dynamic "os_profile_linux_config" {
for_each = each.value.os_type == "linux" ? [1] : []
content {
disable_password_authentication = false
}
}
dynamic "os_profile_windows_config" {
for_each = each.value.os_type == "windows" ? [1] : []
content {
provision_vm_agent = true
}
}
}
# Essential outputs
output "vm_public_ips" {
value = {
for name, ip in azurerm_public_ip.vm : name => ip.ip_address
}
description = "Public IP addresses of the VMs"
}
output "resource_group_name" {
value = azurerm_resource_group.main.name
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment