Azure VM configuration and deployment with Ansible
This directory automates VM configuration and project deployment after Azure infrastructure is created by Terraform.
Directory structure
playbooks/deploy.yml- entrypoint playbookroles/common- base packagesroles/docker- Docker engine and compose setuproles/app- repository checkout, env rendering, service startupinventories/production.ini.example- inventory templategroup_vars/all.yml.example- deployment variables template
Prerequisites
- Ansible
>= 2.15 - SSH access to VM created by Terraform
- Git access to this repository from the VM
- The VM's SSH host key trusted locally (see "Trust VM host key" below);
host_key_checking = Truemeans a fresh VM fails until its key is in~/.ssh/known_hosts
Configure inventory and vars
cd /path/to/repo
./infra/scripts/generate-ansible-inventory.sh
cd infra/ansible
cp group_vars/all.yml.example group_vars/all.yml
Then edit:
inventories/production.iniif you need custom host alias/key pathgroup_vars/all.ymlfor repository URL/branch and environment variables
Script environment overrides:
SSH_KEY_PATH(default~/.ssh/id_ed25519)INVENTORY_HOSTNAME(defaultrolling-restarts)INVENTORY_PATH(defaultinfra/ansible/inventories/production.ini)TF_DIR(defaultinfra/terraform/azure-vm)
Secrets handling
- Do not commit plaintext secrets in
group_vars/all.yml. - Recommended: encrypt secrets with Ansible Vault (
ansible-vault encrypt group_vars/all.yml).
Trust VM host key
Ansible enables strict host key checking. On a freshly provisioned VM, add its
host key to ~/.ssh/known_hosts before the first run to avoid
Host key verification failed:
VM_IP="$(terraform -chdir=../terraform/azure-vm output -raw vm_public_ip)"
ssh-keyscan -H "$VM_IP" >> ~/.ssh/known_hosts
Or SSH to the VM once interactively and accept the key prompt.
Run deployment
cd infra/ansible
ansible-playbook playbooks/deploy.yml
If your local Ansible version errors on the removed yaml callback plugin, keep
stdout_callback = default in ansible.cfg.
What deployment does
- Installs required system tools
- Installs Docker + Compose plugin
- Clones/updates repository under
/opt/rolling-restarts - Renders
infra/.envfrom Ansible variables - Starts stack from
infra/docker-compose.yamlvia systemd service - Verifies app responds on VM localhost
Post-deployment checks
ssh <admin_username>@<vm-public-ip>
sudo systemctl status rolling-restarts --no-pager
sudo docker ps
If docker ps shows a docker socket permission error, reconnect SSH (or run
newgrp docker) to refresh group membership.