A library of reusable, independently-versioned Terraform modules for Azure, Entra ID, FortiGate and GitHub.
This is a module library, not a deployment repository. There is no root configuration, no state and no environment composition here — modules are consumed from other repositories by git source ref.
module "example" {
source = "git::https://github.com/emberstack/terraform.git//src/modules/<module-name>?ref=<ref>"
# ...
}Pinning: this repository does not yet publish version tags. Until it does, pin
refto a commit SHA rather than a branch — trackingmainordevelopmeans an unannounced change lands on your nextterraform init.
Modules declare required_providers but never configure a provider. The consuming configuration is
responsible for authenticating and configuring the provider.
Directory names follow AVM-style <provider>-<kind>-<service>-<resource>:
| Segment | Values |
|---|---|
| provider | azure (azurerm), entra (azuread), fortios (FortiGate), github |
| kind | res, ptn, utl |
res— resource module. Wraps a single logical resource plus tightly-coupled children.ptn— pattern module. Composes or fans out, usuallyfor_eachover a map input.utl— utility module. Pure computation: no resources, no providers.
FortiGate modules carry an extra platform segment: fortios-<kind>-fortigate-<service>-<resource>.
63 modules plus 11 nested submodules. Each family guide lists every module in it and explains how that provider family behaves.
| Family | Provider | Modules | |
|---|---|---|---|
| Azure | hashicorp/azurerm |
17 | Guide |
| Entra ID | hashicorp/azuread |
4 | Guide |
| FortiGate | fortinetdev/fortios |
39 | Guide |
| GitHub | integrations/github |
3 | Guide |
Terraform >= 1.15 across every module. Provider constraints are declared per module in its
versions.tf and all carry an upper bound below the next major, so a provider major release cannot
reach you unannounced — see the version matrix.
Every module directory contains four required files — main.tf, variables.tf, outputs.tf, versions.tf —
optionally alongside README.md, examples/ and modules/ for nested submodules.
.terraform.lock.hcl is deliberately not committed: lock files in reusable modules cause cross-platform
checksum mismatches. Consumers pin their own.
There is no CI. Checks are run locally, per module:
terraform fmt -recursive
cd src/modules/<module-name> && terraform init -backend=false && terraform validate| Guide | |
|---|---|
| Usage | Consuming a module: source refs, pinning, provider wiring, upgrades |
| Conventions | Naming, module anatomy, variable and comment style |
| Contributing | Local validation loop, adding a module, deferred work |
Per-module inputs and outputs are not duplicated in the docs — every variable and output carries a
description, so variables.tf and outputs.tf are the reference.