Skip to content

Init annex: Azure

Status: Stable (Public)
Version: 1.0

This annex defines Azure-specific requirements and outputs for hyops init azure.

Global rules are defined in hyops init contract.

1. Config

Default config path:

  • <root>/config/azure.conf

Config format is line-oriented KEY=value.

1.1 Required keys (non-secret)

  • AZ_LOCATION
    Azure region name used as a default for provisioning operations (example: uksouth).

1.2 Optional keys (non-secret)

  • AZ_SP_NAME (default: sp-hybridops-terraform-bootstrap-<env> when --env is used)
    Display name for the bootstrap service principal when created or rotated in interactive mode. It SHOULD be unique per HyOps environment to avoid secret rotation collisions (rotating the client secret for one env will invalidate other envs that share the same service principal).

  • AZ_SUBSCRIPTION_ID (optional)
    If unset, subscription is resolved from the active az context in interactive mode.

  • AZ_TENANT_ID (optional)
    If unset, tenant is resolved from the active az context in interactive mode.

2. Vault keys

Default vault path:

  • <root>/vault/bootstrap.vault.env

Secrets used:

  • AZ_CLIENT_ID
  • AZ_CLIENT_SECRET
  • AZ_TENANT_ID
  • AZ_SUBSCRIPTION_ID

Rules:

  • In --non-interactive mode, all required secrets MUST be present in the vault.
  • In interactive mode, if valid secrets exist they MUST be reused unless rotation is explicitly performed by the implementation.

3. Behaviour

3.1 Interactive mode

When no valid bootstrap credentials are available:

  • user authentication MUST be established via az login
  • interactive bootstrap MUST fail fast with guidance if the active Azure CLI identity is not a user (az account show --query user.type -o tsv != user)
  • a bootstrap service principal MAY be created or rotated
  • updated credentials MUST be persisted to the vault
  • if AZ_SP_NAME appears to be shared across multiple HyOps environments on the same workstation, init SHOULD warn and require explicit operator confirmation before rotating credentials (to prevent accidental cross-env breakage)

Subscription and tenant resolution:

  • if AZ_SUBSCRIPTION_ID is not set, it MUST be resolved from the active az context
  • if AZ_TENANT_ID is not set, it MUST be resolved from the active az context

3.2 Non-interactive mode

When --non-interactive is set:

  • the vault MUST be decrypted
  • credentials MUST be loaded from the vault
  • az login interactive prompts MUST NOT be used
  • service principal creation and rotation MUST NOT be performed

3.3 Credential validation

Credentials MUST be validated prior to writing outputs. Validation MUST confirm:

  • service principal authentication succeeds, and
  • subscription and tenant identifiers are available

4. Outputs

4.1 Credentials tfvars

Default path:

  • <root>/credentials/azure.credentials.tfvars

The file MUST be mode 0600.

The tfvars file MUST include:

  • subscription_id
  • tenant_id
  • client_id
  • client_secret
  • location

4.2 Readiness marker

Default path:

  • <root>/meta/azure.ready.json

The marker MUST reflect status=ready only when:

  • credentials validate successfully, and
  • required vault persistence (if any) has completed, and
  • the credentials tfvars file is written successfully.

4.3 Evidence

Evidence MUST be written under:

  • <root>/logs/init/azure/<run_id>/

Evidence MUST NOT include client secrets or access tokens.

5. Failure semantics

  • If --non-interactive is set and required vault keys are missing or invalid, init MUST fail with exit code 21.
  • If interactive authentication or bootstrap SP operations fail, init MUST fail with exit code 20.
  • If credentials file writing fails, init MUST fail with exit code 30.