Terraform & GitHub Actions — Beginner Guide (raas-azure-terraform-v2)
A plain‑English tour of the repo you shared. This explains what each part does , how config flows into Terraform , and how the GitHub Actions pipeline runs — with tips for first‑time users.
0) Big Picture
-
Goal: Provision and manage customer infrastructure on Azure using Terraform.
-
Inputs: Customer config files under
configs/(per tenant and per customer), plus environment tfvars. -
Engine: Terraform modules (some included here; others are Git submodules) that create Azure resources.
-
Automation: GitHub Actions workflows to plan/apply/destroy per customer & environment.
1) Repository Layout (high level)
raas-azure-terraform-v2
├─ configs/ # Where customer/tenant configs live (this drives deployments)
│ ├─ m42/ # Multi-tenant examples
│ ├─ raas/ # Multi-tenant examples
│ ├─ mubadala/ # Example customer folder (env json + tfvars)
│ └─ ...
├─ base-vpn/ # Example module (others are submodules)
├─ base-account/ # (submodule)
├─ base-connectivity/ # (submodule)
├─ base-core/ # (submodule)
├─ base-counter/ # (submodule)
├─ base-cifs/ # (submodule)
├─ env-raas/ # (submodule)
├─ env-snapshots/ # (submodule)
├─ scripts/ # Helper scripts (e.g., Cosmos DB query)
└─ .github/workflows/ # Plan/Apply/Destroy workflows + security checks
Many
base-*andenv-*directories are Git submodules. The repo pins them via.gitmodules, and your config files choose which branch/commit to consume.
2) How Configuration Works
2.1 Customer folders
There are two patterns:
-
Multi‑tenant (RaaS/M42):
configs/{raas|m42}/<customer>/ -
Edge:
configs/<customer>/
Each customer folder usually contains:
-
tenant.json— Base module map and shared settings. -
dev.json,prod.json— Environment‑specific module pins/overrides. -
dev.tfvars,prod.tfvars— Variables wired into Terraform for that env (no secrets committed).
2.2 Example (redacted)
-
tenant.json(module selection & pinning):{ "modules": [ { "directory": "base-account", "branch": "main", "commit": "416ed5c4-*-*", "repo_name": "raas-azure-terraform-base-account" } ] }
-
dev.json(env‑specific modules):{ "modules": [ { "directory": "base-counter", "branch": "main", "commit": "b0755039-*-*", "repo_name": "raas-azure-terraform-counter" }, { "directory": "base-core", "branch": "m42/mubadala", "commit": "ebabd9ea--**", "repo_name": "raas-azure-terraform-core" }, { "directory": "env-raas", "branch": "m42/mubadala", "commit": "1bd77c18--**", "repo_name": "raas-azure-terraform-env-raas" }, { "directory": "base-cifs", "branch": "main", "commit": "0abb7eb1--**", "repo_name": "raas-azure-terraform-cifs" }, { "directory": "env-snapshots", "branch": "main", "commit": "68d4f2be--**" } ] }
-
dev.tfvars(variables the modules consume):customer_az_subscription = "2ff7467a-*-*" location = "
" CI_PROJECT_NAME = "ansible-raas-v2.x" ssh_public_key = "ssh-rsa AAAAB3..." admin_username = "adminuser" raas_user = "rhapsody" RaaSS3 = { IAM_USER_CREDS_KV = "S3Creds", AWS_REGION = "us-east-2" } raas_config = { number_of_instances = 1 rules = { / NSG rules per env (keys must be unique) / } asgs = { / VM sizing and disks per env / } } vpns = { / IPSec peer definitions / }Snapshot automation (example)
runbook_name = "Nightly-DataDiskSnapshots" schedule_name = "NightlyAt2AM" schedule_start_time = "2025-04-26T02:00:00Z" schedule_timezone = "America/Phoenix" snapshot_retention_days = 7
3) The GitHub Actions Pipeline (what runs when)
There are dedicated workflows for plan/apply/destroy , both per‑customer and all‑customers.
3.1 Terraform Plan Single (manual trigger)
-
Inputs:
TENANT_NAME(e.g.,m42),CLIENT_NAME(customer folder),DEVOPS_ENV(dev/prod),MODULE(base-core,ALL, etc.). -
Key steps:
-
fetch-azure-credentials (composite action) — queries Cosmos DB for the customer/tenant, exports values into env, logs into Azure via OIDC.
-
terraform-init — sets backend to an Azure Storage Account (
rhapsody-tfstate-<env>container) and uses a state key like<customer>/<region>/<module>.tfstate. -
terraform-plan — points Terraform at the tfvars file from
configs/<tenant>/<customer>/<env>.tfvarsand runsplan.
-
3.2 Terraform Apply Single
- Same inputs; runs
terraform applyagainst the same module + var‑file after init. Gate with manual reviewer if required.
3.3 All‑customer workflows
- Iterate across customers under a tenant path using a strategy/matrix and call the same composite actions.
3.4 Security & scanning
- A separate workflow
callable-security-scan.ymlcan be invoked for IaC checks.
How it fits: Composite actions keep the workflows short and consistent. The pipeline ensures every customer+env combination can be planned/applied/destroyed in a controlled way.
4) Workflow Swimlanes
(Section removed as requested. Previously contained swimlane diagrams; can be re-added later if needed.)