This project uses Terraform to deploy Azure resources using remote state stored in Azure Storage. The setup is split into two stages:
- Bootstrap → Creates the Terraform state backend
- Main Deployment → Deploys actual Azure resources using that remote state
This README covers everything needed to initialize, authenticate, and run both stages.
- Linux Mint / Ubuntu
- Azure CLI
- Terraform ≥ 1.5
ARM_SUBSCRIPTION_IDenvironment variable configured
Log in using the Azure CLI:
az loginIf you have multiple subscriptions, select the correct one:
az account list --output table
az account set --subscription "<subscription-id-or-name>"Verify:
az account show --output tableTerraform uses environment variables for Azure authentication.
Set ARM_SUBSCRIPTION_ID in your ~/.bashrc (NO sudo):
echo 'export ARM_SUBSCRIPTION_ID="$(az account show --query id -o tsv)"' >> ~/.bashrc
source ~/.bashrcConfirm:
echo $ARM_SUBSCRIPTION_IDImportant: Do NOT use
sudowhen modifying your.bashrc. It will cause permission issues and break your environment variables.
The bootstrap deployment sets up the Azure Storage backend used for Terraform state.
Navigate to the bootstrap directory:
cd ~/tf-azure-bootstrapInitialize:
terraform initDeploy:
terraform applyThis creates:
- A resource group for remote state (e.g.,
rg-tfstate-dev) - A storage account with a randomized suffix
- A private
tfstateblob container
Save the outputs — you will need them for the main deployment backend configuration.
Generate backend-lab.hcl with bootstrap outputs:
cd ~/terraform-azurelab
# Read outputs from the bootstrap state
rg_name=$(terraform -chdir=tf-azure-bootstrap output -raw tfstate_resource_group_name)
sa_name=$(terraform -chdir=tf-azure-bootstrap output -raw tfstate_storage_account_name)
container_name=$(terraform -chdir=tf-azure-bootstrap output -raw tfstate_container_name)
# Write backend config for tf-lab
cat > tf-lab/backend-lab.hcl <<EOF
resource_group_name = "$rg_name"
storage_account_name = "$sa_name"
container_name = "$container_name"
key = "lab.tfstate"
use_azuread_auth = true
EOF
echo "Wrote tf-lab/backend-lab.hcl"Navigate to your main Terraform project:
cd ~/tf-azure-mainInitialize Terraform, linking it to your backend storage account:
terraform initDeploy your actual infrastructure:
terraform plan
terraform applyThis will:
- Connect Terraform to the remote backend in Azure
- Deploy your main resources (example: resource group + storage account)
terraform-azurelab/
├── .gitignore
├── README.md
│
├── tf-azure-bootstrap/ # Remote state backend deployment
│ ├── main.tf # rg-tfstate-dev, storage account, container
│ ├── providers.tf
│ ├── outputs.tf
│ └── terraform.tfstate # Remote or local (not committed)
│
└── tf-lab/ # Your actual lab environment (Phase 1)
├── main.tf # Calls modules for RG, VNet, Subnets, VM later
├── providers.tf # AzureRM provider + backend block
├── backend-lab.hcl # Backend config (gitignored)
│
└── modules/
├── network/ # Network module (RG + VNet + Subnets)
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
│
└── vm_cloudflare/ (future)
├── main.tf # Cloudflare VM
├── variables.tf
└── outputs.tf
To destroy bootstrap resources:
cd tf-azure-bootstrap
terraform destroyTo destroy main deployment resources:
cd tf-lab
terraform destroy