Skip to content

Repository Structure of the Template Library

The library is one repository (a monorepo) for all modules and both technologies. The structure is predictable on purpose: the automation (tests, documentation, versioning) finds everything by its place. The decision is in Decision summaries.

Layout

managed-templates/
├── README.md              Overview and the generated template index (a table of all modules)
├── .terraform-docs.yml    Configuration of the documentation generator for Terraform
├── dependencies/          Shared resources for the tests (virtual network, Log Analytics workspace, Key Vault, ...)
├── docs/                  Manual documentation: user guide, ambassador guide, pull request template
├── examples/              Examples of how to call each module. Also used for the integration tests.
│   ├── bicep/
│   │   └── <module>/main.bicep
│   └── terraform/
│       └── <module>/main.tf
├── iac_accelerator/       The example project for consumers (Terraform and Bicep)
├── modules/               The code of the shared modules
│   ├── bicep/
│   │   └── <module>/
│   └── terraform/
│       └── <module>/
├── pipelines/             Pipeline definitions
│   └── templates/
├── scripts/               PowerShell scripts for documentation, releases and publishing
│   └── helper/
├── tests/                 Definitions of the test process
│   ├── bicep/
│   ├── terraform/
│   └── Get-PolicyResult.ps1
├── utils/bicep/types/     Shared Bicep type definitions
└── .github/, .devcontainer/, .vscode/    Repository automation and the developer environment
Folder Holds Notes
modules/<technology>/<module> The module code, its version.json, its changelog and its generated documentation One folder per module. The module's version and its documentation live next to the code. See Inside a module folder.
examples/<technology>/<module> A call of the module with realistic values The integration test deploys the example. Keep it minimal and working.
tests/<technology> The tests (Terratest for Terraform, Pester for Bicep) See Testing. The script Get-PolicyResult.ps1 is shared by both.
dependencies/ Terraform code for the shared resources that many modules need Created by the pipeline when they do not exist yet, and reused by all tests. The storage account for the state is the exception: a small Bicep template creates it. See Shared resources.
pipelines/ The pipelines for testing, documentation, release and manual deployment See Pipelines and scripts.
scripts/ Scripts that generate documentation and the template index, calculate versions, create tags and publish Bicep modules See Pipelines and scripts.
iac_accelerator/ An end-to-end example project with pipelines and Renovate configuration For consumers. See IaC Accelerator. It has its own Renovate configuration in .github/.
docs/ Manually written documentation: the user guide, the ambassador guide and the pull request template Module reference documentation is generated, and not written by hand.
utils/bicep/types Type definitions that several Bicep modules import
.devcontainer/ A development container with Terraform, terraform-docs, Azure CLI with Bicep, PowerShell, Go and Git Gives contributors the same tools.

The structure can grow. A change to it is a decision: record it (Decision summaries).

Inside a module folder

A module folder holds everything that belongs to the module. The generated files are marked.

File or folder Terraform Bicep
Code main.tf, variables*.tf, outputs.tf (or output.tf), locals.tf, terraform.tf main.bicep, and child templates in subfolders for helpers
Compiled template - main.json (generated from main.bicep)
Version and release filter version.json version.json
Changelog CHANGELOG.md CHANGELOG.md
Documentation _header.md (hand-written intro and notes), README.md (generated) README.md (generated)
Example for the documentation docs_examples/defaults/main.example.tf docs_examples/defaults/main.example.bicep
Upgrade notes upgrade/notes-v<major>.md, when a major version needs steps from you The same

The _header.md is the place for notes that are not generated: features, limitations, and policy notes (Known findings). Do not edit the generated README by hand.

Why this structure

  • It divides the code by functionality, technology and module. A module, its example, its tests and its version are easy to find from each other.
  • It follows the folder convention of the Azure Verified Modules project, with a small addition: a level for the technology (Bicep and Terraform), so several technologies and many modules fit in one repository.
  • It keeps changes at an early stage cheap: the structure is simple enough to change.

Naming

  • The module folder has the same name in modules, examples and tests of the same technology (for example storage_account), with two spellings in the tests: the Terraform test file is <module>_test.go (with windows and linux shortened to win and lin), and the Bicep test file is the module name in camel case with the suffix .Tests.ps1.
  • A new module needs a folder in each of the three places: the module, its example and its tests (Create and contribute modules).