Deploy Azure like a pro: your first Terraform main.tf made simple
A simple main.tf for an Azure Terraform solution. We will refer to this in later tutorials.
# Configure the Azure Provider
provider "azurerm" {
features {}
}
# Create a resource group
resource "azurerm_resource_group" "example" {
name = "example-resources"
location = "East US"
tags = {
environment = "development"
}
}
# Create a virtual network
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
}
# Create a subnet
resource "azurerm_subnet" "example" {
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"]
}
# Create a network security group
resource "azurerm_network_security_group" "example" {
name = "example-nsg"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
security_rule {
name = "allow-http"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "80"
source_address_prefix = "*"
destination_address_prefix = "*"
}
security_rule {
name = "allow-https"
priority = 110
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "443"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}
# Create a public IP
resource "azurerm_public_ip" "example" {
name = "example-pip"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
allocation_method = "Dynamic"
}
# Create a network interface
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
}
}
# Output resource group name
output "resource_group_name" {
value = azurerm_resource_group.example.name
}
# Output virtual network name
output "virtual_network_name" {
value = azurerm_virtual_network.example.name
}
Let’s walk through each element of the Azure Terraform configuration file in detail:
Provider block
provider "azurerm" {
features {}
}
This configures the Azure Resource Manager (AzureRM) provider which is required to interact with Azure . The features {} block is mandatory in newer versions of the AzureRM provider. This block could also include authentication settings if not using Azure CLI authentication.
Resource group
resource "azurerm_resource_group" "example" {
name = "example-resources"
location = "East US"
tags = {
environment = "development"
}
}
A resource group is a logical container for Azure resources.
- name: Specifies the name of the resource group (“example-resources”)
- location: Specifies the Azure region where the resource group will be created (“East US”)
- tags: Optional metadata applied to the resource for organization and billing purposes
Virtual network
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
}
This creates an isolated network environment in Azure
- name: The name of the virtual network
- address_space: The IP address space for the VNet in CIDR notation (allows 65,536 IP addresses)
- location: References the location of the previously created resource group
- resource_group_name: References the name of the previously created resource group
Subnet
resource "azurerm_subnet" "example" {
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"]
}
This subdivides the virtual network into a smaller network segment.
- name: The subnet name (“internal”)
- resource_group_name: References the resource group name
- virtual_network_name: References the virtual network this subnet belongs to
- address_prefixes: Defines the subnet’s IP range (allows 256 IP addresses)
Network security group
resource "azurerm_network_security_group" "example" {
name = "example-nsg"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
security_rule {
name = "allow-http"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "80"
source_address_prefix = "*"
destination_address_prefix = "*"
}
security_rule {
name = "allow-https"
priority = 110
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "443"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}
The security group acts as a virtual firewall to control inbound and outbound traffic. The group contains two security rules that allow HTTP (port 80) and HTTPS (port 443) traffic.
- priority: Lower numbers have higher priority (100 is processed before 110)
- direction: Specifies if the rule applies to inbound or outbound traffic
- access: Determines whether to allow or deny the traffic specified by the rule
- protocol: Specifies the protocol this rule applies to (TCP in this case)
- source_port_range: Source ports to match ("*" means any)
- destination_port_range: Destination ports to match (80 for HTTP, 443 for HTTPS)
- source_address_prefix: Source IP addresses or ranges ("*" means any)
- destination_address_prefix: Destination IP addresses or ranges ("*" means any)
Public IP
resource "azurerm_public_ip" "example" {
name = "example-pip"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
allocation_method = "Dynamic"
}
Creates a public IP address that can be associated with Azure resources.
- name: The name of the public IP resource
- allocation_method: “Dynamic” means the IP address may change when the associated resource is deallocated
Network interface
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
}
}
A network interface connects a virtual machine to the virtual network.
- ip_configuration: Defines how the interface should be configured.
- subnet_id: References the subnet where this NIC will be placed
- private_ip_address_allocation: “Dynamic” means Azure assigns an available private IP from the subnet
- public_ip_address_id: Associates the previously created public IP with this network interface
Outputs
output "resource_group_name" {
value = azurerm_resource_group.example.name
}
output "virtual_network_name" {
value = azurerm_virtual_network.example.name
}
This defines values that will be displayed after terraform applies the configuration. It is useful for referencing created resources in other configurations or for informational purposes. These specific outputs would show the resource group and virtual network names after deployment.
This configuration creates a basic network infrastructure in Azure that could support deploying virtual machines or other services that would need network connectivity.
comments powered by Disqus