This document outlines the process of automating the deployment of an Azure Virtual Machine (VM) using Terraform, configuring the VM for GitHub SSH access, cloning a GitHub repository, and deploying an application with PM2. Additionally, it explains how GitHub Actions is configured to trigger deployments via SSH. This integration streamlines the continuous deployment pipeline by automating environment provisioning and code deployment.
Before starting the process, ensure you have the following:
- Terraform installed on your local machine.
- An Azure subscription with appropriate permissions.
- A GitHub repository containing your application code.
- SSH client tools (for key generation and verification).
- GitHub Actions enabled in your repository.
- Basic knowledge of shell scripting and command line operations.
Terraform is used to generate an SSH key pair. This key pair will be used for:
- Securing access to the Azure VM.
- Enabling the VM to authenticate with GitHub over SSH.
resource "tls_private_key" "ssh_key" { algorithm = "RSA" rsa_bits = 4096 }
- Output: The public key is embedded in the VM configuration The private key is stored for GitHub Actions as well as provisioner connection
- Terraform provisions an Azure VM using the generated SSH key for secure login. The VM is deployed into a resource group, virtual network, and subnet which are created in the same terraform code.
resource "azurerm_linux_virtual_machine" "vm" { name = "var.vm_name" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name size = "var.vm_size" admin_username = "var.user_name" ... admin_ssh_key { username = "azureuser" public_key = tls_private_key.ssh_key.public_key_openssh } ... }
Shell provisioners (embedded in the custom_data field) perform the following tasks upon VM startup:
- Install Dependencies: Update package lists and install Git and PM2.
- Configure SSH Access: Set up the SSH private key in the ~/.ssh directory and add GitHub’s host key to prevent man-in-the-middle attacks.
- Clone Repository & Deploy: Clone the specified GitHub repository and use PM2 to deploy the application, ensuring the service runs persistently.
resource "azurerm_linux_virtual_machine" "vm" { provisioner "remote-exec" { inline = [ "sudo apt update -y", "sudo apt install -y git pm2", "mkdir -p /home/${var.user_name}/.ssh", "echo '${tls_private_key.ssh_key.private_key_pem}' > /home/${var.user_name}/.ssh/id_rsa", "chmod 600 /home/${var.user_name}/.ssh/id_rsa", "ssh-keyscan github.com >> /home/${var.user_name}/.ssh/known_hosts", "git clone [email protected]:YourUsername/YourRepo.git /home/${var.user_name}/YourRepo", "cd /home/${var.user_name}/YourRepo", "pm2 start app.js --name 'myApp'" ] connection { type = "ssh" host = azurerm_public_ip.vm_public_ip.ip_address user = var.user_name private_key = tls_private_key.ssh_key.private_key_pem } } }
To enable automated deployments through GitHub Actions, store Sensitive Data as Secrets: In your GitHub repository settings, add the following secrets:
- VM_USER: The admin username (e.g., azureuser).
- VM_HOST: The public IP address of the Azure VM (obtained from Terraform output).
- VM_SSH_KEY: The private key generated by Terraform, used to authenticate SSH connections.
GitHub Actions Workflow Example:
name: Deploy to Azure VM
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v2
- name: Deploy via SSH
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.VM_HOST }}
username: ${{ secrets.VM_USER }}
key: ${{ secrets.VM_SSH_KEY }}
script: |
cd /home/azureuser/YourRepo
git pull origin main
pm2 restart myApp || pm2 start app.js --name "myApp"- SSH Key Generation: Terraform generates an RSA SSH key pair for secure VM access.
- Azure VM Provisioning: The VM is created in Azure, and the public SSH key is injected during provisioning.
- VM Configuration: A shell script runs during VM initialization, setting up SSH access, cloning a GitHub repository, and deploying the application using PM2.
- Automated Deployment with GitHub Actions: GitHub Actions, configured with appropriate secrets, uses SSH to connect to the VM and update the deployment pipeline automatically.
- To execute this script you need configure your azure cli
az login
- Move to the terraform folder using
cd terraform - Run the terraform plan to confirm the execution plan by adding the required varaibles in the runtime
terraform plan
- After confirming the execution plan run the following command to create the required infra.
terraform apply
- Confirm the Private key in your current directory and try to execute the output command to connect to your vm.
ssh -o identityonly=yes -i ./vm_id_rsa azureuser@VM_IP