Exercise 12 ยท 60 minutes

Compose a reusable module

Extract the managed identity into a local module, preserve its state address with a moved block, and instantiate a second identity through a clear module contract.

ModuleBuild modulesAzure costNone expectedCreatesSecond identity

Before you start

Goal and prerequisites

Your goal

Create a module that owns one managed identity and can be reused without copying resource configuration.

You need

  • The working sandbox from Exercise 10
  • Exercise 11 completed
  • A clean no-change plan
  • The current identity resource address
  • The standard tag contract

Participant task

Refactor without replacement

  1. 01

    Define the module boundary

    Create modules/managed-identity. Decide which values callers control, which values the module derives, and which outputs callers need.

  2. 02

    Move the resource

    Move the identity resource into the module and call it once from the root configuration. Add a moved block from the old address to the new module address.

  3. 03

    Prove address continuity

    Initialize the local module and save a plan. The plan must not destroy or recreate the existing identity. Resolve the address mapping before continuing.

    terraform init
    terraform validate
    terraform plan -out refactor.tfplan
  4. 04

    Add a second instance

    Instantiate a second identity for a different sandbox role. Reuse the module contract and standard tags; do not duplicate the resource block.

  5. 05

    Apply and inspect outputs

    Review a fresh saved plan, apply it, and confirm that callers can consume each module instance's resource ID and principal ID.

    terraform plan -out main.tfplan
    terraform apply main.tfplan
    terraform output

Expected outcome

Check reuse and state safety

Validation

  • The original identity keeps its Azure resource ID.
  • No resource configuration is copied.
  • The module declares typed inputs and useful outputs.
  • The second identity has the required tags.

Optional extension

Replace separate module calls with for_each. Add the necessary moved block and require a no-replacement plan before apply.

Finish

Document the module contract

Add a short module README covering purpose, inputs, outputs, and one usage example. Keep both identities for Exercise 14.