Skip to content

sqenchill/mini-finance

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Azure Static Site Deployment — Terraform + Ansible

Terraform Ansible Azure CI

Infrastructure provisioned from code. Application deployed and verified automatically.

This project deploys the Mini Finance static site to an Azure VM using Terraform for infrastructure provisioning and Ansible for configuration, deployment, and verification — with clean separation of concerns between the two tools.


What This Demonstrates

Capability Implementation
Infrastructure as Code Terraform provisions all Azure resources — no manual console interaction
Multi-play Ansible automation Clean separation between install, deploy, and verify plays
Secure by default Key-based SSH only; NSG locked to inbound ports 22 and 80
Verified delivery Play 3 asserts status_code: 200 — the pipeline does not complete successfully unless the site is reachable
Real-world debugging Deployment completed without errors but returned 403 Forbidden — root cause identified, fixed, and revalidated

Architecture

Terraform provisions:
  Azure Resource Group (rg-mini-finance)
  └── Virtual Network  10.0.0.0/16
      └── Subnet       10.0.1.0/24
          ├── NSG      inbound: TCP 22 (SSH), TCP 80 (HTTP)
          ├── NIC + Static Public IP
          └── Ubuntu 22.04 VM  (Standard_B2ats_v2)
               └── Key-based SSH only (password auth disabled)

Ansible configures and deploys:
  Play 1 — Install   apt update → install nginx + git → start and enable nginx
  Play 2 — Deploy    clone repo → sync to /var/www/html/ → set www-data ownership → reload nginx
  Play 3 — Verify    uri module → GET http://<public_ip> → assert status_code == 200

Prerequisites

  • Azure CLI — authenticated (az login)
  • Terraform >= 1.5.0
  • Ansible
  • SSH key pair at ~/.ssh/id_rsa_azure (private) and ~/.ssh/id_rsa_azure.pub (public)

Usage

1. Provision infrastructure

cd terraform/

cp terraform.tfvars.example terraform.tfvars
# Edit terraform.tfvars if you need a different region, VM size, or admin username

terraform init
terraform plan
terraform apply

terraform apply outputs the public_ip on completion. Note it — you need it in the next step.

2. Update the Ansible inventory

Edit ansible/inventory.ini and replace <public_ip> with the value from step 1:

[web]
<public_ip>

[web:vars]
ansible_user=azureuser
ansible_ssh_private_key_file=~/.ssh/id_rsa_azure

3. Verify SSH access

ssh azureuser@<public_ip> "hostname"

Must connect without a password prompt before proceeding.

4. Run the Ansible playbook

cd ansible/
ansible-playbook -i inventory.ini site.yml

A successful run ends with:

TASK [Assert HTTP 200 was returned]
ok: [localhost] => {
    "msg": "Mini Finance site is reachable and returned HTTP 200"
}

5. Verify in browser

Navigate to http://<public_ip> — the Mini Finance site loads.


Debugging: The 403 Incident

The initial deployment completed without errors. The Ansible verify play returned 403 Forbidden, not 200.

Root cause: File ownership. Content had been synced to /var/www/html/ but Nginx could not serve it because the files were not owned by www-data. Play 2 sets owner: www-data and group: www-data on the copy task, and applies recurse: true via the file task — but these were not applied correctly on the first run.

Fix: Corrected the ownership configuration, redeployed, revalidated. The verify play returned HTTP 200.

Why this matters: The verify play (Play 3) exists precisely for this class of problem. "It ran without errors" is not the same as "it works." Automated verification makes the difference observable and actionable without manual checking.


Project Structure

mini-finance/
├── .github/
│   └── workflows/
│       └── ci.yml              # Terraform fmt check + Ansible syntax check on push
├── ansible/
│   ├── inventory.ini           # Host inventory — replace <public_ip> after terraform apply
│   └── site.yml                # Multi-play playbook: install → deploy → verify
├── terraform/
│   ├── .terraform.lock.hcl     # Provider dependency lock file
│   ├── main.tf                 # All Azure resources
│   ├── outputs.tf              # Public IP output
│   ├── providers.tf            # AzureRM provider and version constraints
│   ├── terraform.tfvars.example
│   └── variables.tf            # Input variable definitions with defaults
├── .gitignore
└── README.md

Technologies

  • Terraform — Infrastructure as Code, Azure provider ~> 3.100
  • Ansible — Configuration management and deployment automation
  • Azure — Resource Group, Virtual Network, Subnet, NSG, Public IP, NIC, Ubuntu 22.04 VM
  • Nginx — Web server
  • GitHub Actions — CI: Terraform format check and Ansible syntax check on every push

About

Azure static site deployment using Terraform for infrastructure and Ansible for configuration, deployment, and verification

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages