Deploy development virtual machines on Azure

This page details the Terraform configuration for deploying development virtual machines (VMs) on Microsoft Azure with multiple operating system options and automated Netprobe deployment. This environment creates development VMs on Azure with:

Template files Copied

The environment contains the following Terraform configuration files:

Prerequisites Copied

  1. Terraform version 1.0 or higher installed

  2. Azure CLI version 2.0 or higher installed

  3. Azure authentication configured:

    # Method 1: Interactive login
    az login
    
    # Method 2: Service principal
    az login --service-principal \
      --username <app-id> \
      --password <password> \
      --tenant <tenant-id>
    
    # Method 3: Environment variables
    export ARM_CLIENT_ID="your-client-id"
    export ARM_CLIENT_SECRET="your-client-secret"
    export ARM_SUBSCRIPTION_ID="your-subscription-id"
    export ARM_TENANT_ID="your-tenant-id"
    
  4. Azure subscription with appropriate permissions:

    • Contributor role or equivalent permissions on the target Resource Group
    • Access to create virtual machines, networks, and associated resources
  5. SSH key pair for VM access

    # Generate SSH key pair if not already available
    ssh-keygen -t rsa -b 4096 -f ../../../../../resources/id_rsa
    
  6. Existing Azure resources (Prerequisites):

    • Resource Group - Must exist before deployment
    • Virtual Network with subnet - VMs will be deployed to existing subnet
    • Network Security Group - Will be associated with VM network interfaces

Deployment setup Copied

  1. Copy the example configuration.

    # For Ubuntu 22.04 (default)
    cp terraform.tfvars.example terraform.tfvars
    
    # For Ubuntu 24.04
    cp terraform.tfvars.ubuntu24.example terraform.tfvars
    
    # For RHEL 8
    cp terraform.tfvars.rhel8.example terraform.tfvars
    
    # For RHEL 9
    cp terraform.tfvars.rhel9.example terraform.tfvars
    
  2. Update the terraform.tfvars configuration file with your Azure resource IDs and preferences.

    nano terraform.tfvars
    
  3. Deploy the infrastructure.

    terraform init
    terraform plan
    terraform apply
    

Authentication overview Copied

This deployment requires two types of authentication:

  1. Terraform authentication (infrastructure creation) to allow Terraform to create virtual machines, networks, and cloud resources. For Azure, you need to configure the Azure CLI or service principal. Select only one method:

    • Interactive login — makes use of the Azure CLI interactive login.

      az login
      
    • Service principal — makes use of a service principal for automated deployments.

      az login --service-principal \
        --username <app-id> \
        --password <password> \
        --tenant <tenant-id>
      
    • Environment variables — makes use of environment variables for authentication.

      export ARM_CLIENT_ID="your-client-id"
      export ARM_CLIENT_SECRET="your-client-secret"
      export ARM_SUBSCRIPTION_ID="your-subscription-id"
      export ARM_TENANT_ID="your-tenant-id"
      
  2. Application authentication (cloud storage access) to allow applications running on virtual machines to download the deployment resources from the respective cloud storage. This is configured in the netprobe.yml file for each environment. Refer to Azure authentication for detailed authentication configuration.

Identity configuration Copied

User assigned identity for Azure storage access Copied

VMs can be configured with user assigned identities for secure access to the Azure Blob Storage without storing credentials.

# In terraform.tfvars
identity_ids = [
  "/subscriptions/your-subscription-id/resourceGroups/your-resource-group/providers/Microsoft.ManagedIdentity/userAssignedIdentities/your-identity"
]

The user assigned identity must have the Storage Blob Data Reader role assigned on the storage account or container used for deployment resources.

Run the following Azure CLI commands to create the identity:

# Create User Assigned Identity
az identity create \
  --name "geneos-cloud-managed-identity" \
  --resource-group "your-resource-group"

# Get identity resource ID
az identity show \
  --name "geneos-cloud-managed-identity" \
  --resource-group "your-resource-group" \
  --query "id" -o tsv

# Assign Storage Blob Data Reader role to identity
az role assignment create \
  --role "Storage Blob Data Reader" \
  --assignee-object-id $(az identity show --name "geneos-cloud-managed-identity" --resource-group "your-resource-group" --query "principalId" -o tsv) \
  --assignee-principal-type "ServicePrincipal" \
  --scope "/subscriptions/your-subscription-id/resourceGroups/your-resource-group/providers/Microsoft.Storage/storageAccounts/your-storage-account"

Configuration files Copied

Select the appropriate configuration file for your operating system:

Operating system Configuration file
Ubuntu 22.04 LTS (default) terraform.tfvars.example
Ubuntu 24.04 LTS terraform.tfvars.ubuntu24.example
RHEL 8 terraform.tfvars.rhel8.example
RHEL 9 terraform.tfvars.rhel9.example

In the selected configuration file, configure the parameters outlined below.

Azure account configuration Copied

Parameter Description Default Required
subscription_id Azure subscription ID where resources will be deployed Yes

Deployment configuration Copied

Parameter Description Default Required
resource_group_name Name of the existing Azure resource group for resource deployment Yes
deployment_count Number of identical VM deployments to create 1 Yes
tags Resource tags to assign to all created resources {} No

Network configuration Copied

Parameter Description Default Required
vnet_subnet_id ID of the existing VNet subnet where VMs will be deployed Yes
nsg_id ID of the existing Network Security Group to associate with NICs Yes

Public IP configuration Copied

Parameter Description Default Required
public_ip_name Base name for Public IP Address resources Yes
public_ip_sku SKU of the Public IP Address (Standard, Basic) “Standard” Yes
public_ip_type Allocation method for Public IP Address (Static, Dynamic) “Static” Yes
public_ip_zones Availability zones for the Public IP Address [“1”] Yes

Network interface configuration Copied

Parameter Description Default Required
nic_name Base name for Network Interface resources Yes

Virtual machine configuration Copied

Virtual machine configurations are based on the Netprobe system requirements. The default VM size and OS disk type follow the ITRS Azure virtual machine image specifications.

Parameter Description Default Required
vm_name Base name for Virtual Machine resources Yes
vm_size Size/type of the Virtual Machine “Standard_D2s_v3” Yes
vm_zones Availability zones for the Virtual Machine [“1”] Yes
vm_os_disk_type OS disk type “Premium_LRS” Yes

Virtual machine image configuration Copied

Parameter Description Default Required
vm_image_publisher Publisher of the VM image Yes
vm_image_offer Image offer for the Virtual Machine Yes
vm_image_sku Image SKU for the Virtual Machine Yes
vm_image_version Image version for the Virtual Machine “latest” Yes

SSH access configuration Copied

Parameter Description Default Required
ssh_user SSH username for VM access Yes
ssh_public_key_path Path to SSH public key file Yes
disable_password_auth Disable password authentication (SSH keys only) true Yes
vm_admin_password Admin password for the Virtual Machine (used as fallback) "" No

Ansible deployment configuration Copied

Parameter Description Default Required
ansible_playbook_path Path to Ansible playbook for deployment “../../../../ansible/netprobe.yml” Yes
ansible_operation Deployment operation “install” Yes
ansible_ssh_common_args SSH common arguments for Ansible connections “-o ControlMaster=no -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null” Yes
additional_args Additional Ansible playbook arguments "" No

Resources created Copied

The following Azure infrastructure resources will be created:

Resource Description
Public IP Address Static IP for external access
Network Interface Connected to existing VNet subnet and NSG
Virtual Machine Linux VM with SSH access and selected OS
Ansible Deployment Automated Netprobe service installation

Outputs Copied

The following outputs will be available after deployment:

Output Description
external_ip Public IP address of the virtual machine
internal_ip Private IP address of the virtual machine
vm_name Name of the virtual machine
resource_group_name Resource group containing the resources
operating_system Operating system version selected
ssh_user SSH username for the operating system
deployment_summary Summary of all deployed resources

Ansible integration Copied

Ansible playbooks are automatically executed after the creation of the virtual machine. These are used to:

Troubleshooting Copied

You can run the given commands if you encounter the following issues:

Issue type Command
Authentication issues
# Check current Azure identity
az account show

# List available subscriptions
az account list

# Set subscription
az account set --subscription "your-subscription-id"

# Check permissions
az role assignment list --assignee $(az account show --query user.name -o tsv)
Resource group and network issues
# Check resource group exists
az group show --name "your-resource-group"

# List VNets in resource group
az network vnet list --resource-group "your-resource-group"

# List subnets in VNet
az network vnet subnet list --resource-group "your-resource-group" --vnet-name "your-vnet"

# Check NSG exists
az network nsg show --resource-group "your-resource-group" --name "your-nsg"
Instance issues
# Check VM status
az vm list --resource-group "your-resource-group"

# Get VM details
az vm show --resource-group "your-resource-group" --name "your-vm"

# Check via Terraform
terraform show
terraform state list
Image issues
# List available Ubuntu images
az vm image list --publisher Canonical --offer 0001-com-ubuntu-server-jammy --all

# List available RHEL images
az vm image list --publisher RedHat --offer RHEL --all
SSH connection issues
# Check public IP
az network public-ip show --resource-group "your-resource-group" --name "your-public-ip"

# Check NSG rules
az network nsg rule list --resource-group "your-resource-group" --nsg-name "your-nsg"

# Test SSH connection
ssh -i ../../../../../resources/id_rsa netprobe_user@<public-ip>
Ansible deployment issues
# Check Ansible logs in Terraform output
terraform apply -auto-approve

# Manual Ansible execution
ansible-playbook -i <public-ip>, ../../../../ansible/netprobe.yml \
  --private-key ../../../../../resources/id_rsa \
  --user netprobe_user \
  --extra-vars "operation=install"

Terraform commands Copied

Run the following Terraform commands to deploy the infrastructure.

Command Command
Initialize Terraform
terraform init
Plan the deployment
terraform plan -var-file="terraform.tfvars"
Apply the deployment
terraform apply -var-file="terraform.tfvars"
Show the deployment options
terraform output
Destroy the deployment
terraform destroy -var-file="terraform.tfvars"

Netprobe configuration Copied

The netprobe.yml file contains Ansible configuration for Netprobe deployment. For general configuration structure and available parameters, refer to Ansible configuration.

Update the following environment-specific settings in netprobe.yml file for your Azure development environment:

SSH configuration Copied

# SSH connection configuration (required)
ansible_ssh_private_key_file: "../../../../resources/id_rsa"
ansible_ssh_common_args: "-o ControlMaster=no -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"

Bootstrap configuration Copied

# Set to false for dev environments (minimal bootstrap)
perform_bootstrap: false

# Azure CLI installation command if perform_bootstrap is true
additional_bootstrap: "{{ python_path }} -m pip install --upgrade msrestazure && ansible-galaxy collection install azure.azcollection --force && {{ python_path }} -m pip install -r ~/.ansible/collections/ansible_collections/azure/azcollection/requirements.txt"

Cloud provider configuration Copied

resources:
  # Azure Blob Storage configuration (update with your credentials)
  source:
    azure:
      resource_group: resource_group
      storage_account_name: storage_account_name
      account_key: account_key
  # Cloud storage container
  container: geneos
  # Resource paths
  path: netprobe.tar.gz
  setupfile:
    path: netprobe.setup_template.xml

Gateway connection Copied

env_vars:
  # Gateway information (configure for your setup)
  GATEWAY_HOST: "0.0.0.0"
  GATEWAY_PORT: "7039"

Netprobe connection Copied

env_vars:
  # Netprobe information
  SERVICE_PARAM: "-port 7036 -setup {{ workspace_dir }}/{{ resources.setupfile.path | basename }}"
["Geneos"] ["Geneos > Netprobe"] ["User Guide"]

Was this topic helpful?