Secrets and variables¶
The full list of what to set on the landing-zone repository, in one place. Most of the variables are written by the bootstrap; the secrets you set yourself.
Repository variables¶
Set under Settings, Secrets and variables, Actions, Variables.
| Variable | Required | Purpose |
|---|---|---|
AZURE_TENANT_ID |
yes | Tenant id. |
AZURE_SUBSCRIPTION_ID |
yes | Subscription id for the state account and default context. |
BACKEND_AZURE_RESOURCE_GROUP_NAME |
yes | State storage resource group, read by root.hcl. |
BACKEND_AZURE_STORAGE_ACCOUNT_NAME |
yes | State storage account, read by root.hcl. |
BACKEND_AZURE_STORAGE_ACCOUNT_CONTAINER_NAME |
yes | State container, read by root.hcl. |
RUNNER_LABEL |
for private state | Self-hosted runner label. Falls back to ubuntu-latest. |
TFPR_EXTRA_TOOLS |
for the gates | Space-separated gate tools to install per run. infracost on the self-hosted posture (conftest and checkov are baked into the runner image); conftest checkov infracost on a GitHub-hosted posture. |
ENGINE_APP_CLIENT_ID |
yes | Engine App client id. Authenticates the private engine checkout and the prebuilt-binary download. Set by the bootstrap when engine_app_client_id is supplied. |
TFPR_CHECKS_APP_CLIENT_ID |
yes | Checks App client id. The engine's check rows, the merge gate included, are written under this App. Set by the bootstrap when checks_app_client_id is supplied. |
TFPR_ALLOW_UNREVIEWED_APPLY |
only for a repo with no required reviews | Set to true to allow /apply when the repository requires no approving reviews. Leave unset everywhere else. |
TFPR_PLAN_ENVIRONMENT |
optional | Override the plan environment name. Default plan. |
TFPR_APPLY_ENVIRONMENT |
optional | Override the apply environment name. Default apply. |
TFPR_UNLOCK_ENVIRONMENT |
optional | Override the environment the unlock job binds. Defaults to the plan environment. |
TFPR_LOCK_STORAGE_ACCOUNT |
optional | Storage account for the cross-PR unit lock table. Defaults to the BACKEND_AZURE_STORAGE_ACCOUNT_NAME account; required only for a plain Terraform repo with no backend variables. |
TFPR_LOCK_TABLE |
optional | Table name for the unit locks. Default tfprlocks. |
TFPR_INIT_ARGS |
optional | Extra arguments appended to every init the engine runs. |
TFPR_DISABLE_LOCKS |
optional | Set to true to turn cross-PR unit locking off. Leave unset everywhere else. |
TFPR_MINIMIZE_OUTDATED |
optional | Outdated run reports are minimized by default, with a banner linking to the report that replaced them. Set to false to opt out and keep every run's comment at full size. |
TFPR_ALLOW_UNREVIEWED_APPLY is a real relaxation
The engine reads GitHub's review decision to gate /apply. A repository that
requires no approving reviews reports an empty decision, which the engine
refuses, so /apply never runs and there is nothing to approve to unblock it.
Only that case needs this variable.
An empty decision is refused rather than allowed because it cannot be told apart from a ruleset that was deleted. Setting the variable gives that up knowingly. The usual reason is a single-writer organization, which cannot self-approve on GitHub and so sets the required review count to 0 on purpose. Everywhere else, set the required review count instead and leave this unset.
Variables or ARM secrets
The workflow reads the identity as vars.AZURE_* || secrets.ARM_*. Prefer the
AZURE_* variables written by the bootstrap. The ARM_* secrets exist as a
fallback for demos that set the identity by hand.
Repository secrets¶
Set under Settings, Secrets and variables, Actions, Secrets.
| Secret | Required | Purpose |
|---|---|---|
ENGINE_APP_PRIVATE_KEY |
yes | Engine App private key. Required in reusable mode: it authenticates the private engine checkout and the prebuilt-binary download. Set by the bootstrap when TF_VAR_engine_app_private_key is exported. |
TFPR_CHECKS_APP_PRIVATE_KEY |
yes | Checks App private key. Signs the engine's check rows. Set by the bootstrap when TF_VAR_checks_app_private_key is exported. |
INFRACOST_API_KEY |
for the cost gate | Hosted pricing API key. Until set, the infracost gate notes it and skips. |
ARM_CLIENT_ID |
fallback only | Identity client id when not using AZURE_* variables. |
ARM_TENANT_ID |
fallback only | Tenant id fallback. |
ARM_SUBSCRIPTION_ID |
fallback only | Subscription id fallback. |
GITHUB_TOKEN is provided automatically by GitHub Actions and posts the comments,
checks, and statuses. You do not set it.
Environments¶
Two GitHub environments on the repo, each with an Azure federated credential:
| Environment | Identity | Used by |
|---|---|---|
plan |
Reader (read-only) | PR plan jobs and the daily drift plan. |
apply |
Owner | The apply job. |
Each environment carries its own AZURE_CLIENT_ID variable, pointing at that
environment's identity. The bootstrap sets both. It is an environment variable,
not a repository variable: a single repository-level value would give the plan jobs
the Owner identity, or the apply jobs the Reader one.
The OIDC subject binds the repository and the environment name, built with immutable
repository ids (repo:org@id/repo@id:environment:env) for repos created after
GitHub's rollout, so keep the names stable. If you must rename them, set
TFPR_PLAN_ENVIRONMENT and TFPR_APPLY_ENVIRONMENT and update the
federated credential subjects to match.
Branch protection¶
Make tf-pr-ops / merge-gate a required status check on the main
branch, and set the required reviews you want /apply to respect.
The bootstrap provisions a require-approved-pr-to-main ruleset that requires an
approved pull request. It adds the required status check only when its
required_status_checks variable is set, and that variable is empty by default,
so by default the merge gate is not required. Set the variable to
["tf-pr-ops / merge-gate"] before running the bootstrap, or add the check by
hand afterwards.
The cost gate key¶
The infracost gate uses the legacy infracost line. Get a static API key from the
Infracost dashboard, set it as INFRACOST_API_KEY, and add infracost to
TFPR_EXTRA_TOOLS. See the gates for detail and the data
residency note.