Seamless Azure VM Access: Automate SSH Key Management with Terraform
When working with Azure Virtual Machines, secure and efficient access is critical, especially for development and administration tasks — or adhoc labs where you are just kicking the tires. Using SSH keys simplifies this process by offering a password-less method of authentication that enhances security. In this guide, we’ll walk through generating an SSH key locally using Terraform’s tls provider, saving it securely on your system, and referencing it to provision and connect to an Azure Virtual Machine.
The first step is to generate an SSH key pair using Terraform’s tls provider. This provider allows you to create secure, cryptographically strong private keys. In our example, we use the RSA algorithm with 4096 bits for enhanced security. The configuration below creates the key pair:
resource "tls_private_key" "vm1" {
algorithm = "RSA"
rsa_bits = 4096
}
Once the key pair is generated, the next step is to store it locally in the .ssh directory under your home directory. Terraform’s local_file resource makes this straightforward by writing the private and public keys to separate files. The private key is saved with strict permissions (0600) to ensure it remains secure, while the public key is saved in a format compatible with OpenSSH. Here’s how this is achieved:
resource "local_file" "private_key" {
content = tls_private_key.vm1.private_key_pem
filename = pathexpand("~/.ssh/vm1") # Save private key as ~/.ssh/vm1
file_permission = "0600"
}
resource "local_file" "public_key" {
content = tls_private_key.vm1.public_key_openssh
filename = pathexpand("~/.ssh/vm1.pub") # Save public key as ~/.ssh/vm1.pub
}
With the SSH keys securely stored, we can now reference the public key while provisioning an Azure Virtual Machine. In the configuration below, the admin_ssh_key block is used to inject the public key into the VM during creation. This ensures that the VM is pre-configured to allow secure access using the SSH private key stored locally.
resource "azurerm_linux_virtual_machine" "vm1" {
name = "vm1${var.application_name}${var.environment_name}"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
size = "Standard_D2_v2_Promo"
admin_username = "adminuser"
network_interface_ids = [
azurerm_network_interface.vm1.id,
]
admin_ssh_key {
username = "adminuser"
public_key = tls_private_key.vm1.public_key_openssh
}
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"
}
}
Finally, connecting to the Virtual Machine becomes a seamless task. With the private key securely stored in the .sshdirectory, you can use the ssh command to establish a secure session. Make sure to replace FOO with the public IP address of your Azure Virtual Machine:
ssh -i ~/.ssh/vm1 adminuser@FOO
This method eliminates the need for manual key generation or complex configuration and ensures your connection process remains both secure and efficient. By integrating SSH key management into your Terraform workflow, you not only streamline your infrastructure provisioning but also improve security practices for adhoc labs.
It’s important to remember that this is not intended for production scenarios but it can help you reduce the propogation of your primary “day-to-day” driver SSH key from being circulated widely. In conclusion, saving an SSH key locally and integrating it into your labs that use Azure Virtual Machines can be streamlined with Terraform in a simple yet powerful technique. It automates key management, enhancing security by reducing long lived SSH keys, and makes connecting to your VM hassle-free. Whether you’re managing a single VM or scaling to multiple instances, this approach lays a strong foundation for secure and efficient operations. All you have to do is run terraform destroy and your lab — and its SSH Keys are all cleaned up!