DEV Community

Cover image for πŸš€ Secrets Safe, 3-Tier Deployments Fast: Terraform + Azure Key Vault Complete Hands-On Guide
TechOpsBySonali for CareerByteCode

Posted on

πŸš€ Secrets Safe, 3-Tier Deployments Fast: Terraform + Azure Key Vault Complete Hands-On Guide

Deploying the same 3-tier application again and again β€” dev, test, prod β€” shouldn’t feel like dΓ©jΓ  vu every time.
But in many cloud teams, it does.
Manual fixes… copy-pasted Terraform… secrets hardcoded inside .tfvars…
One small change in dev, not updated in prod…
Boom! Configuration drift, broken deployments, security risks.

This hands-on guide shows you exactly how to eliminate all of that using:

βœ… Terraform Modular Architecture
βœ… Azure Key Vault for Secure Secrets Management
βœ… Remote State in Azure Storage
βœ… GitHub Actions for Fully Automated CI/CD

By the end, you’ll be able to deploy dev, test, and prod environments identically, securely, and on autopilot.


πŸ”₯ 1. The Problem: Manual Deployments = Drift + Errors + Chaos

Most teams still deploy environments like this:

  • Copy old Terraform folder
  • Change a few names
  • Adjust IPs manually
  • Forget a network rule
  • Hardcode passwords β€œfor now” πŸ˜…
  • Fix mistakes after something breaks

Result?

❌ Inconsistent infra across environments
❌ Security breaches due to exposed secrets
❌ Time wasted troubleshooting
❌ Zero auditability
❌ No single source of truth

This hands-on solves exactly this.


πŸš€ 2. Why This Use Case Matters

Cloud teams today need consistency + speed + security.
Manually managing infra no longer works.

This use case delivers:

🧱 Reusable Terraform Modules

Resource Group, VNet, Subnet, NSG, VM β€” once written, reused forever.

πŸ” Zero Secret Sprawl

Passwords and sensitive values stored in Azure Key Vault, pulled directly in Terraform.

🚦 Environment-driven Deployment

All differences (dev/test/prod) live in terraform.tfvars.

πŸ€– GitHub Actions = Fully Automated Deployments

Plan β†’ Validate β†’ Apply β†’ Audit logs β€” everything automated.

This is production-grade Terraform, not just a tutorial.


πŸ•’ 3. When You Need This Use Case

You need this setup when:

βœ”οΈ Deploying multiple environments
βœ”οΈ Avoiding inconsistent infra
βœ”οΈ Securing all secrets centrally
βœ”οΈ Enabling fast onboarding
βœ”οΈ Needing auditability and governance
βœ”οΈ Running builds from CI/CD pipelines
βœ”οΈ Scaling infra to multiple regions

This architecture grows as your company grows.


πŸ› οΈ 4. Prerequisites

  • Azure Subscription
  • Azure CLI
  • Terraform Installed
  • Git + GitHub
  • Key Vault access
  • Optional: GitHub Actions Service Principal

You’re ready.


🎯 5. Challenge Questions (Interview-Level)

These make great DevOps interview questions too:

  1. How do you avoid copy-paste Terraform for dev/test/prod?
  2. How do you secure plaintext secrets in Terraform?
  3. How do you stop network drift between environments?
  4. How do you enable new developers to deploy infra securely?
  5. How do you prove that all environments are deployed from the same code?
  6. How do you roll back a Terraform deployment?
  7. How do you prevent faulty tfvars from affecting prod?
  8. How do you design a module for both Linux & Windows VMs?
  9. How do you deploy identical infra to two regions?
  10. Why are modules better than plain Terraform scripts?

πŸ§‘β€πŸ’» 6. Complete Hands-On Implementation

Below is the full real-life end-to-end setup.


STEP 1️⃣ β€” Authenticate to Azure & Configure Git

az login
git config --global user.name "yourname"
git config --global user.email "yourmail@example.com"
Enter fullscreen mode Exit fullscreen mode

Initialize GitHub repository:

git init
echo "# azure-3-tier-architecture" >> README.md
git add .
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/<yourid>/azure-3-tier-architecture.git
git push -u origin main
Enter fullscreen mode Exit fullscreen mode

STEP 2️⃣ β€” Create Backend Resources

LOCATION="eastus"
RG_NAME="tfstate-rg"
STORAGE_NAME="mytfstate12345"
CONTAINER_NAME="tfstate"
KV_NAME="mykeyvault12345"
Enter fullscreen mode Exit fullscreen mode
az group create --name $RG_NAME --location $LOCATION
az storage account create --name $STORAGE_NAME --resource-group $RG_NAME --location $LOCATION --sku Standard_LRS
az storage container create --name $CONTAINER_NAME --account-name $STORAGE_NAME
Enter fullscreen mode Exit fullscreen mode

STEP 3️⃣ β€” Create Key Vault + Secrets

az keyvault create --name $KV_NAME --resource-group $RG_NAME --location $LOCATION
Enter fullscreen mode Exit fullscreen mode

Store secrets

az keyvault secret set --vault-name $KV_NAME --name "vm-username" --value "learning"
az keyvault secret set --vault-name $KV_NAME --name "vm-password" --value "Redhat@12345"
Enter fullscreen mode Exit fullscreen mode

STEP 4️⃣ β€” Create GitHub Service Principal

az ad sp create-for-rbac --name "github-spn" --role="Contributor" --scopes="/subscriptions/<subid>" --sdk-auth
Enter fullscreen mode Exit fullscreen mode

Save JSON output.

Grant Key Vault access:

az role assignment create \
  --assignee <clientId> \
  --role "Key Vault Secrets User" \
  --scope $(az keyvault show --name $KV_NAME --query id -o tsv)
Enter fullscreen mode Exit fullscreen mode

STEP 5️⃣ β€” Create Terraform Structure

terraform/
β”œβ”€β”€ backend.tf
β”œβ”€β”€ main.tf
β”œβ”€β”€ variables.tf
β”œβ”€β”€ environments/
β”‚   β”œβ”€β”€ dev/terraform.tfvars
β”‚   β”œβ”€β”€ test/terraform.tfvars
β”‚   └── prod/terraform.tfvars
└── modules/
    β”œβ”€β”€ rg/
    β”œβ”€β”€ vnet/
    β”œβ”€β”€ subnet/
    β”œβ”€β”€ nsg/
    └── vm/
Enter fullscreen mode Exit fullscreen mode

STEP 6️⃣ β€” Add Root Terraform Files

backend.tf

terraform {
  backend "azurerm" {
    resource_group_name  = "tfstate-rg"
    storage_account_name = "mytfstate12345"
    container_name       = "tfstate"
    key                  = "3tier/dev.tfstate"
  }
}
Enter fullscreen mode Exit fullscreen mode

variables.tf

variable "location" { type = string }
variable "rg_name" { type = string }
variable "vnet_name" { type = string }
variable "vm_name" { type = string }
Enter fullscreen mode Exit fullscreen mode

main.tf

provider "azurerm" {
  features {}
}

module "rg" {
  source   = "./modules/rg"
  name     = var.rg_name
  location = var.location
}

module "vnet" {
  source   = "./modules/vnet"
  name     = var.vnet_name
  location = var.location
  resource_group_name = module.rg.name
}

module "subnet" {
  source = "./modules/subnet"
  name   = "${var.vnet_name}-subnet"
  vnet_name = module.vnet.name
  resource_group_name = module.rg.name
  nsg_id = module.nsg.id
}

module "nsg" {
  source = "./modules/nsg"
  name   = "${var.vnet_name}-nsg"
  location = var.location
  resource_group_name = module.rg.name
}

data "azurerm_key_vault" "kv" {
  name                = "mykeyvault12345"
  resource_group_name = "tfstate-rg"
}

data "azurerm_key_vault_secret" "vm_username" {
  name         = "vm-username"
  key_vault_id = data.azurerm_key_vault.kv.id
}

data "azurerm_key_vault_secret" "vm_password" {
  name         = "vm-password"
  key_vault_id = data.azurerm_key_vault.kv.id
}

module "vm" {
  source              = "./modules/vm"
  name                = var.vm_name
  location            = var.location
  resource_group_name = module.rg.name
  subnet_id           = module.subnet.id
  admin_username      = data.azurerm_key_vault_secret.vm_username.value
  admin_password      = data.azurerm_key_vault_secret.vm_password.value
}
Enter fullscreen mode Exit fullscreen mode

STEP 7️⃣ β€” Environment Variables

dev

rg_name  = "rg-dev"
vnet_name = "vnet-dev"
vm_name   = "vm-dev"
location = "eastus"
Enter fullscreen mode Exit fullscreen mode

STEP 8️⃣ β€” Build Modules

(Example: Resource Group)

modules/rg/main.tf

resource "azurerm_resource_group" "rg" {
  name     = var.name
  location = var.location
}
Enter fullscreen mode Exit fullscreen mode

modules/rg/variables.tf

variable "name" { type = string }
variable "location" { type = string }
Enter fullscreen mode Exit fullscreen mode

modules/rg/outputs.tf

output "name" { value = azurerm_resource_group.rg.name }
Enter fullscreen mode Exit fullscreen mode

Repeat similar for vnet, subnet, nsg, vm.


πŸŽ‰ Final Output

You now have:

βœ”οΈ Modular Terraform
βœ”οΈ Secure secrets with Key Vault
βœ”οΈ Remote state
βœ”οΈ Reusable environments
βœ”οΈ Ready for GitHub Actions automation

This is true enterprise-grade Infrastructure as Code.


⭐ Follow Me for Daily DevOps & Cloud Content

πŸ”΅ LinkedIn: @techopsbysonali
🐦 Twitter / X: @techopsbysonali
πŸ“Έ Instagram: @techopsbysonali
πŸ“ Medium: @techopsbysonali
πŸ“š Dev.to: @techopsbysonali
🌐 Hashnode: techopsbysonali.hashnode.dev
πŸ–‹οΈ Blogger: techopsbysonali.blogspot.com

**

πŸ“² Join My WhatsApp Communities
**
πŸ‘‰ Personalized Guidance: https://wa.me/7620774352
πŸ‘‰ Latest Updates Group: https://lnkd.in/gVTvmRBa
πŸ‘‰ Pune Local Meetup Group: https://lnkd.in/gQbKaUeX

Top comments (0)