Note: Scroll down this article to download the terrafom files in zip format. |
Azure Jump Host with Terraform
This Terraform project deploys a secure Ubuntu 24.04 LTS jump host (Bastion Host) into an existing Azure virtual network.
It is designed to provide a secure entry point to your private Azure environment. It creates the VM and its necessary components (like a Public IP and NSG) in a resource group.
Features
- Creates VM Resource Group (or use existing): Creates a new resource group for the jump host. Includes a
prevent_destroylifecycle hook to prevent accidental deletion. - Deploys Ubuntu 24.04 VM: Deploys a
Standard_B2ats_v2Ubuntu 24.04 VM. - Secure by Default: Creates a Network Security Group (NSG) that only allows inbound SSH (port 22) from the
admin_public_ipyou specify. - Public IP: Provisions a static public IP address for the VM.
- Adds Explicit Route: Adds a single route to your existing route table. This route forces traffic destined for your
admin_public_ipto go directly to theInternet, ensuring your SSH connection isn't hijacked by a forced-tunneling (e.g., to a firewall).
Prerequisites
Before you begin, you must have the following:
- Terraform (v1.0.0+) installed.
- Azure CLI installed.
- An active Azure Subscription.
- An existing Virtual Network (VNet) and Subnet.
- An existing Route Table (UDR) associated with your Subnet.
Configuration
Authenticate with Azure:
az loginConfigure Variables: Edit
terraform.auto.tfvarsand fill in your environment's specific values.
terraform.auto.tfvars Example
# -----------------------------------------------------------------
# --- Fill in these values before running 'terraform apply' ---
# -----------------------------------------------------------------
# 1. Location
# The Azure region for your resources.
location = "uksouth"
# 2. Resource Groups
# The RG where your VNet, Subnet, and Route Table are.
network_resource_group_name = "rg-my-existing-network"
# The name of the RG for the new Jump Host.
# It will be CREATED if it does not exist.
vm_resource_group_name = "rg-my-new-jumphosts"
# 3. Existing Network Details
vnet_name = "vnet-my-production-vnet"
subnet_name = "snet-jumphosts"
# 4. Existing Route Table
# The name of the route table (UDR) already associated with your subnet.
existing_route_table_name = "rt-my-subnet-routes"
# 5. Security Details
# Find your IP by searching "what is my IP" in Google.
admin_public_ip = "YOUR_HOME_OR_OFFICE_IP_HERE"
# Path to your public SSH key.
# Example: "C:/Users/YourUser/.ssh/id_rsa.pub" or "/home/youruser/.ssh/id_rsa.pub"
admin_ssh_key_path = "~/.ssh/id_rsa.pub"
Usage
Initialize Terraform: This downloads the Azure provider.
terraform initPlan Deployment: This shows you what resources will be created, modified, or destroyed.
terraform planApply Configuration: This will build the resources in Azure.
terraform applyType
yeswhen prompted to approve the plan.
Outputs
After a successful deployment, Terraform will output the following values:
| Name | Description |
|---|---|
jump_host_public_ip | The public IP address of the newly created jump host. |
ssh_command | The full SSH command to connect to your new VM. |
jump_host_vm_id | The full Azure Resource ID of the created VM. |
You can connect to your VM using the ssh_command output:
ssh -k 'ssh-key' azureuser@YOUR_NEW_PUBLIC_IP
Destroying Resources
To remove all resources except the protected resource group, run:
terraform destroy
Note on Resource Group Destruction
The VM resource group (vm_resource_group_name) is protected by a prevent_destroy = true lifecycle block. If you run terraform destroy, all resources (VM, NIC, PIP, NSG, Route) will be deleted, but Terraform will stop with an error, refusing to delete the resource group.
This is a safety feature. To delete the resource group, you must either:
- Manually delete it from the Azure Portal.
- Comment out or remove the
lifecycleblock inmain.tfand runterraform apply(to update the state) and thenterraform destroyagain.