Skip to content
CAMPUX
Field notes · Infrastructure as code
Bicep modules

Bicep modules: stop copy-pasting your infrastructure

By 6 min read

The moment your Bicep grows past a toy, one giant file becomes unreadable and you start copy-pasting the same storage-account block into every deployment. Modules are how infrastructure-as-code learns the lesson every programmer already knows: factor it into reusable functions.

New to cloud? CAMPUX is a free, build-first course. Start here →

Your first Bicep file is a happy single page. Your tenth is a 900-line monster where the same virtual-network pattern appears three times with tiny differences. That is the exact smell that, in application code, tells you to write a function — and Bicep has the same answer. Microsoft's definition is one sentence: "A module is a Bicep file that another Bicep file deploys." You write a resource pattern once, in its own file, and call it wherever you need it.

Define once, call anywhere

A module is just an ordinary Bicep file — say storageAccount.bicep — with parameters for the bits that vary and outputs for the values callers need back. A parent file consumes it with the module keyword:

module stg './storageAccount.bicep' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
    location: location
  }
}

// use an output the module returned
output endpoint object = stg.outputs.storageEndpoint

That is the whole model: the module declares what varies (parameters) and what it hands back (outputs), and the parent supplies the parameters and reads the outputs. The value that comes out — a storage endpoint, a resource ID — flows into the rest of your deployment. It is functions, for infrastructure.

A main.bicep composes reusable modules (network, storage, compute) instead of repeating raw resources.main.bicepcomposes modulesnetwork.bicepVNet · subnets · NSGstorage.bicepaccounts · containerscompute.bicepVMs · scale setswrite a resource once as a module, then reuse it across every environment
Figure — A Bicep module is just a Bicep file you call from another one, passing parameters and reading back outputs. A top-level main.bicep composes modules — network, storage, compute — instead of repeating raw resource blocks. That keeps each piece small and testable and lets you reuse the same module across dev, test, and prod (varying only the parameters). Compose infrastructure the way you compose code: small units, wired together, not one giant file.

Why it matters

Microsoft names the two payoffs directly: modules "improve the readability of your Bicep files by encapsulating complex details," and you "can easily reuse modules for different deployments." Concretely:

A module is a function for infrastructure: name what varies, return what matters, and stop pasting the same block into every file.

You don't compose complexity — Azure does

Under the hood, your modules are compiled into a single ARM template with nested deployments, and Resource Manager still works out the ordering. Modules deploy in parallel unless one depends on another's output, in which case Bicep infers the dependency for you. So you get clean, factored source files without giving up the orchestration that makes a deployment reliable.

Sharing modules across a team

Reuse gets serious when a module leaves your repo. Bicep supports two homes for shared modules: a private module registry (backed by an Azure Container Registry, so your team pulls versioned modules like packages), and template specs. There is also a public registry of Azure Verified Modules — prebuilt, pre-tested modules that follow Well-Architected best practices, which you reference by a versioned path (br/public:avm/res/storage/storage-account:...). So before you hand-write the hundredth storage-account module, check whether Microsoft already maintains a verified one.

The takeaway

Modules are the step that turns Bicep from scripting into engineering. When a file gets long or a pattern repeats, extract it: a module with clear parameters and outputs, called from a parent that now reads like a table of contents. Reuse it across environments so a fix lands everywhere at once, share it through a registry or template spec, and reach for Azure Verified Modules before reinventing common ones. "Factor the deployment into parameterized modules, compose them in a parent, and pull common ones from the registry" is the working habit of someone who has started treating infrastructure as software they maintain, which, with Bicep, is precisely what it has become.

Questions people also ask

What is a module in Bicep?

A module is a Bicep file that another Bicep file deploys. You write a resource pattern once, in its own file, with parameters for what varies and outputs for what callers need back, then call it from a parent file wherever you need that pattern.

How do you call a module in Bicep?

You use the module keyword, give the call a symbolic name, point path at the module file, and supply a params block. The parent file references outputs through that symbolic name, for example stg.outputs.storageEndpoint, once the module deploys.

What is the difference between a Bicep file and a module?

There is no syntax difference. Any Bicep file becomes a module the moment another Bicep file deploys it with the module keyword. The distinction is a role, not a file type: a module is written to be parameterized and reused, not run on its own.

How do you share Bicep modules across a team?

Publish them to a private module registry backed by an Azure Container Registry, so the team pulls versioned modules like packages, or use template specs. For common patterns, check Azure Verified Modules first, a public registry of prebuilt modules that follow Well-Architected defaults.

Do Bicep modules deploy in parallel?

Yes, unless one module depends on another's output. Bicep compiles modules into a single ARM template with nested deployments, infers dependencies from output references automatically, and Resource Manager orders and parallelizes the deployment for you.

Further reading — the Microsoft docs
Your next class · free
You've read the idea. Class 20 — Infrastructure as Code: Bicep is where you build it, hands-on — no account needed.Start Class 20 →
Captain O
Founder & instructor · CAMPUX Cloud Engineering Bootcamp
LinkedIn
Drilled in Class 20 — Bicep. Next note: Bicep vs Terraform →