Skip to content

shap0011/terraform-azure

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Terraform Azure Resource Group Setup

This project demonstrates how to create an Azure Resource Group and a Virtual Network using Terraform and the AzureRM provider.


Prerequisites

Make sure you have the following installed:

  • Terraform
  • Azure CLI

Step 1: Login to Azure

Open PowerShell and run:

az login

Verify your account and subscription:

az account show

Step 2: Set Environment Variable

Terraform requires a subscription ID.

Set it using:

$env:ARM_SUBSCRIPTION_ID="your-subscription-id"

Example:

$env:ARM_SUBSCRIPTION_ID="c928cbac-ea4a-4c7b-8970-3773f4175f80"

Step 3: Create variables.tf

Create a file named variables.tf and add:

variable "resource_group_name" {
  description = "Name of the Azure Resource Group"
  type        = string
  default     = "mtc-resources"
}

variable "location" {
  description = "Azure region where resources will be created"
  type        = string
  default     = "Canada Central"
}

variable "environment" {
  description = "Environment tag (e.g., dev, prod)"
  type        = string
  default     = "dev"
}

variable "virtual_network_name" {
  description = "Name of the Virtual Network"
  type        = string
  default     = "mtc-network"
}

variable "address_space" {
  description = "Address space for the Virtual Network"
  type        = list(string)
  default     = ["10.123.0.0/16"]
}

Step 4: Create main.tf

Create a file named main.tf and add:

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "=4.1.0"
    }
  }
}

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "mtc-rg" {
  name     = var.resource_group_name
  location = var.location

  tags = {
    environment = var.environment
  }
}

resource "azurerm_virtual_network" "mtc-vn" {
  name                = var.virtual_network_name
  address_space       = var.address_space
  location            = var.location
  resource_group_name = var.resource_group_name

  tags = {
    environment = var.environment
  }
}

Step 5: Initialize Terraform

terraform init

Step 6: Plan Deployment

terraform plan

You should see:

Plan: 2 to add, 0 to change, 0 to destroy.

Step 7: Apply Deployment

terraform apply

Type:

yes

Step 8: Destroy Resources (Optional)

terraform destroy

Notes

  • The Virtual Network defines a private network inside Azure.
  • The address space specifies the IP range used within that network.
  • Additional components such as subnets and virtual machines can be added later.

terraform state list

Project Structure

.
├── main.tf
├── variables.tf
├── README.md
└── .gitignore


Inspecting Terraform State

After applying your configuration, you can inspect the current state of your infrastructure using the following commands.

List Resources in State

terraform state list

Example output:

azurerm_resource_group.mtc-rg
azurerm_virtual_network.mtc-vn

This shows all resources currently tracked by Terraform.


Show Resource Details

terraform state show azurerm_resource_group.mtc-rg

Example output:

# azurerm_resource_group.mtc-rg:
resource "azurerm_resource_group" "mtc-rg" {
    id         = "/subscriptions/.../resourceGroups/mtc-resources"
    location   = "canadacentral"
    managed_by = null
    name       = "mtc-resources"
    tags       = {
        "environment" = "dev"
    }
}

This displays detailed information about a specific resource stored in the Terraform state.


Notes

  • Terraform state represents the current infrastructure managed by Terraform.
  • The state list command shows all tracked resources.
  • The state show command provides detailed attributes for a specific resource.
  • Some values (like id) are generated by Azure after deployment.


Destroy Plan and Apply

Terraform allows you to preview and remove all managed resources.

Preview Destroy

terraform plan --destroy

This command shows what resources will be deleted without actually removing them.

Example output:

Plan: 0 to add, 0 to change, 2 to destroy.

Apply Destroy

terraform apply --destroy

Type:

yes

This command deletes all resources managed by Terraform in the current configuration.


Notes

  • terraform plan --destroy is used to review changes before deletion.
  • terraform apply --destroy permanently removes all managed resources.
  • This is equivalent to running terraform destroy.


Terraform State Backup

Terraform automatically creates a backup of the state file named:

terraform.tfstate.backup

This file contains the previous state before the last change.


Restore State from Backup

If a mistake is made and the current state becomes incorrect, you can restore it from the backup:

copy terraform.tfstate.backup terraform.tfstate

Notes

  • The backup file is created automatically by Terraform.
  • It stores the last known good state before changes were applied.
  • Restoring the backup can help recover from accidental modifications.
  • Always ensure Terraform is not running when replacing the state file.
  • State files may contain sensitive information and should not be committed to version control.


Subnet Configuration

A subnet is a smaller network inside a Virtual Network. It allows you to organize and control resources within your network.


Add Subnet Resource

Update your main.tf file by adding:

resource "azurerm_subnet" "mtc-subnet" {
  name                 = "mtc-subnet"
  resource_group_name  = azurerm_resource_group.mtc-rg.name
  virtual_network_name = azurerm_virtual_network.mtc-vn.name
  address_prefixes     = ["10.123.1.0/24"]
}

Plan Output

After running:

terraform plan

You should see:

Plan: 1 to add, 0 to change, 0 to destroy.

Notes

  • A subnet must be created inside a Virtual Network.
  • virtual_network_name links the subnet to the VNet.
  • address_prefixes defines the IP range for the subnet.
  • The subnet range must be within the Virtual Network address space.

In this example:

  • Virtual Network: 10.123.0.0/16
  • Subnet: 10.123.1.0/24

The subnet is a smaller portion of the main network.



Network Security Group and Rule

A Network Security Group (NSG) is used to control inbound and outbound network traffic for Azure resources.


Add Network Security Group

Update your main.tf file by adding:

resource "azurerm_network_security_group" "mtc-sg" {
  name                = "mtc-sg"
  location            = azurerm_resource_group.mtc-rg.location
  resource_group_name = azurerm_resource_group.mtc-rg.name

  tags = {
    environment = "dev"
  }
}

Add Security Rule

Add a rule to define allowed traffic:

resource "azurerm_network_security_rule" "mtc-dev-rule" {
  name                        = "mtc-dev-rule"
  priority                    = 100
  direction                   = "Inbound"
  access                      = "Allow"
  protocol                    = "Tcp"
  source_port_range           = "*"
  destination_port_range      = "*"
  source_address_prefix       = "*"
  destination_address_prefix  = "*"
  resource_group_name         = azurerm_resource_group.mtc-rg.name
  network_security_group_name = azurerm_network_security_group.mtc-sg.name
}

Plan Output

After running:

terraform plan

You should see:

Plan: 2 to add, 0 to change, 0 to destroy.

Notes

  • A Network Security Group (NSG) acts as a firewall for your network.
  • Security rules define what traffic is allowed or denied.
  • direction = "Inbound" means incoming traffic is controlled.
  • access = "Allow" permits traffic matching the rule.
  • protocol = "Tcp" applies the rule to TCP traffic.
  • Using "*" allows all ports and all IP addresses.
  • priority determines rule order (lower number = higher priority).
  • The rule is associated with the NSG using network_security_group_name.

This example creates a basic rule that allows all inbound TCP traffic. In real scenarios, rules should be more restrictive.



Subnet and Network Security Group Association

After creating a Network Security Group (NSG), it must be associated with a subnet or network interface to take effect.


Add Association

Update your main.tf file by adding:

resource "azurerm_subnet_network_security_group_association" "mtc-sga" {
  subnet_id                 = azurerm_subnet.mtc-subnet.id
  network_security_group_id = azurerm_network_security_group.mtc-sg.id
}

Plan Output

After running:

terraform plan

You should see:

Plan: 1 to add, 0 to change, 0 to destroy.

Notes

  • An NSG does not apply to any resources until it is associated.
  • This resource links the NSG to a subnet.
  • subnet_id identifies the subnet where the rules will apply.
  • network_security_group_id identifies the NSG to attach.
  • Once associated, all resources inside the subnet are affected by the NSG rules.

This step ensures that the defined security rules are enforced on the network.



Public IP Address

A Public IP allows Azure resources to be accessible from the internet.


Add Public IP Resource

Update your main.tf file by adding:

resource "azurerm_public_ip" "mtc-ip" {
  name                = "mtc-ip"
  resource_group_name = azurerm_resource_group.mtc-rg.name
  location            = azurerm_resource_group.mtc-rg.location
  allocation_method   = "Static"
  sku                 = "Standard"

  tags = {
    environment = "dev"
  }
}

Plan Output

After running:

terraform plan

You should see:

Plan: 1 to add, 0 to change, 0 to destroy.

Notes

  • A Public IP enables communication between Azure resources and the internet.
  • sku = "Standard" is used by default in newer AzureRM provider versions.
  • Standard Public IPs require allocation_method = "Static".
  • The IP address is assigned at creation time and remains the same.
  • A Public IP is typically associated with a Network Interface or Load Balancer.
  • This resource alone does not expose anything until it is attached to another resource.

This step prepares your infrastructure for external access.



Network Interface (NIC)

A Network Interface connects a Virtual Machine to a Virtual Network and allows it to communicate with other resources.


Add Network Interface Resource

Update your main.tf file by adding:

resource "azurerm_network_interface" "mtc-nic" {
  name                = "mtc-nic"
  location            = azurerm_resource_group.mtc-rg.location
  resource_group_name = azurerm_resource_group.mtc-rg.name

  ip_configuration {
    name                          = "internal"
    subnet_id                     = azurerm_subnet.mtc-subnet.id
    private_ip_address_allocation = "Dynamic"
    public_ip_address_id          = azurerm_public_ip.mtc-ip.id
  }

  tags = {
    environment = "dev"
  }
}

Plan Output

After running:

terraform plan

You should see:

Plan: 1 to add, 0 to change, 0 to destroy.

Notes

  • A Network Interface (NIC) connects resources (such as virtual machines) to a network.
  • subnet_id links the NIC to a subnet inside the Virtual Network.
  • private_ip_address_allocation = "Dynamic" lets Azure assign a private IP automatically.
  • The private IP comes from the subnet range (e.g., 10.123.1.0/24).
  • public_ip_address_id attaches a Public IP for external access.
  • Without a NIC, a Virtual Machine cannot communicate with the network.

This step prepares the network connection for future resources such as virtual machines.


Linux Virtual Machine

A Virtual Machine (VM) is a compute resource that runs an operating system and applications in Azure.


Add Virtual Machine Resource

Update your main.tf file by adding:

resource "azurerm_linux_virtual_machine" "mtc-vm" {
  name                = "mtc-vm"
  resource_group_name = azurerm_resource_group.mtc-rg.name
  location            = azurerm_resource_group.mtc-rg.location
  size                = "Standard_B1s"
  admin_username      = "adminuser"

  network_interface_ids = [
    azurerm_network_interface.mtc-nic.id,
  ]

  admin_ssh_key {
    username   = "adminuser"
    public_key = file("~/.ssh/mtcazurekey.pub")
  }

  os_disk {
    caching              = "ReadWrite"
    storage_account_type = "Standard_LRS"
  }

  source_image_reference {
    publisher = "Canonical"
    offer     = "0001-com-ubuntu-server-jammy"
    sku       = "22_04-lts"
    version   = "latest"
  }
}

Plan Output

After running:

terraform plan

You should see:

Plan: 1 to add, 0 to change, 0 to destroy.

Notes

  • A Virtual Machine provides compute resources in Azure.
  • size = "Standard_B1s" defines the VM size (CPU, memory).
  • admin_username is used to log into the VM.
  • network_interface_ids connects the VM to the network.
  • The VM uses the previously created Network Interface, which includes both private and public connectivity.
  • admin_ssh_key enables secure SSH access using a public key.
  • file("~/.ssh/mtcazurekey.pub") reads the SSH public key from your local machine.
  • os_disk defines storage settings for the VM.
  • source_image_reference specifies the operating system image (Ubuntu 22.04 in this case).

SSH Access

After deployment, you can connect to the VM using SSH:

ssh adminuser@<public-ip-address>

Replace <public-ip-address> with the Public IP created earlier.


Notes on SSH Key

  • The SSH key pair must exist on your machine.
  • The .pub file contains the public key used by Azure.
  • The private key remains on your local machine and is used for authentication.

This step creates a fully functional virtual machine connected to your network.


Connect to Virtual Machine

After the Virtual Machine is deployed, you can connect to it using SSH.


SSH Command

Run the following command in PowerShell:

ssh -i ~/.ssh/mtcazurekey adminuser@<public-ip-address>

Replace <public-ip-address> with the Public IP created earlier.

Example:

ssh -i ~/.ssh/mtcazurekey adminuser@20.48.255.134

Successful Connection

If the connection is successful, you will see a message similar to:

Welcome to Ubuntu 22.04.5 LTS (GNU/Linux ...)

Notes

  • The -i flag specifies the private SSH key used for authentication.
  • The username must match the one defined in the Terraform configuration (adminuser).
  • The Public IP is assigned by Azure and used for external access.
  • The private IP (e.g., 10.123.1.4) is used internally within the Virtual Network.
  • SSH uses port 22, which must be allowed in the Network Security Group.

Verify Connection

After login, you can run basic commands:

whoami
hostname
ip a

These commands help verify that you are connected to the correct virtual machine.


This confirms that the infrastructure is deployed correctly and accessible.



Verify Ubuntu Installation

After connecting to the Virtual Machine, you can verify the operating system version.


Check OS Version

Run the following command inside the VM:

lsb_release -a

Example Output

No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.5 LTS
Release:        22.04
Codename:       jammy

Notes

  • This confirms that the VM is running Ubuntu.
  • The version matches the image defined in Terraform:
source_image_reference {
  publisher = "Canonical"
  offer     = "0001-com-ubuntu-server-jammy"
  sku       = "22_04-lts"
  version   = "latest"
}
  • "jammy" is the codename for Ubuntu 22.04.
  • This step verifies that the correct OS image was deployed.

This confirms that the Virtual Machine was created successfully with the expected configuration.


Exit VM

adminuser@mtc-vm:~$ exit
logout
Connection to 20.48.255.134 closed.

Summary

In this project, the following infrastructure was created and tested using Terraform:

  • Resource Group
  • Virtual Network (VNet)
  • Subnet
  • Network Security Group (NSG) and security rule
  • Subnet and NSG association
  • Public IP Address
  • Network Interface (NIC)
  • Linux Virtual Machine (Ubuntu)

Validation

The deployment was verified by:

  • Running terraform plan and terraform apply
  • Connecting to the Virtual Machine using SSH
  • Confirming the Ubuntu version installed on the VM

Cleanup

All resources were successfully removed using:

terraform destroy

This ensures no cloud resources remain running after testing.


Conclusion

This project demonstrates a complete end-to-end infrastructure deployment in Azure using Terraform, including networking, security, and compute resources.

The Virtual Machine was successfully provisioned and accessed remotely, confirming that all components were configured correctly.


About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages