Skip to content

PF-190: Confirm support for Azure Government in pipelines#3188

Open
gruntwork-ci wants to merge 1 commit into
mainfrom
claude-pr/PF-190-28256470055
Open

PF-190: Confirm support for Azure Government in pipelines#3188
gruntwork-ci wants to merge 1 commit into
mainfrom
claude-pr/PF-190-28256470055

Conversation

@gruntwork-ci

@gruntwork-ci gruntwork-ci commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Implements plan for Linear issue PF-190.

Plan source: https://github.com/gruntwork-io-team/linear-claude-plans/blob/main/plans/PF-190.md


Claude's implementation summary
All good. Final summary by repo:

## Summary of changes

### `pipelines` (gruntwork-io/pipelines)

Plumbed `cloud_environment` through the Azure OIDC stack so Pipelines can target Azure sovereign clouds (US Government, China, Germany, Stack) instead of only the public Azure cloud.

- `internal/config/authentication/authentication.go` — Added `AzureOIDCHCL` (parse-phase struct with `cloud_environment,optional`) and `(*AzureOIDCHCL).Resolve()`. Resolve defaults the value to `"public"` and validates against the azurerm-accepted set (`public`, `usgovernment`, `china`, `german`, `stack`) via `hcl.Diagnostics`. The resolved `AzureOIDC` struct gains a `CloudEnvironment` field. `AuthenticationHCL.Resolve()` now calls into the new Azure resolver.
- `internal/config/oidc/azure/azure.go` — `AzureOIDCConfig` gains a `CloudEnvironment` field; `Hash()` and `LogrusFields()` include it (so credentials cached for `public` don't satisfy a request for `usgovernment`), and `GetOIDCConfig` propagates it from the authentication config.
- `internal/oidc/cloud/azure/azure.go` — `GetCreds` adds `ARM_ENVIRONMENT` to the env map when `CloudEnvironment` is non-empty.
- Tests:
  - `internal/config/authentication/authentication_test.go` — Updated existing Azure cases to expect the new default `"public"`, added cases for `usgovernment`, `china`, `german`, `stack`, and a new `TestAzureOIDCHCLResolve_InvalidCloudEnvironment` that asserts the error lists every valid value.
  - `internal/config/oidc/azure/azure_test.go` (new) — `Hash()` differs across cloud environments; `GetOIDCConfig` propagates `CloudEnvironment` for both plan and apply roles.
  - `internal/oidc/cloud/azure/azure_test.go` — Added stub `OIDCTokenProvider` and two tests covering `ARM_ENVIRONMENT` emission (set when populated, omitted when empty).
- `test-fixtures/pipelines-config/azure-government/` (new) — HCL config fixture exercising `cloud_environment = "usgovernment"`; `expected.json` generated via `go run ./test/plumbing/config/generate_fixtures/main.go`.

`go test ./internal/config/... ./internal/oidc/cloud/... ./test/plumbing/config/...` all pass. The wider `./internal/...` suite has unrelated failures from this sandbox lacking `terragrunt` / `mise` on PATH.

ARCHITECTURE.md was already accurate for this work — no updates required.

### `docs` (gruntwork-io/docs)

- `docs/2.0/reference/pipelines/configurations-as-code/api.mdx` — New `HclListItem name="cloud_environment"` (optional, default `public`) at the end of the `azure_oidc` block attributes, listing all five accepted values and linking to the new tutorial and the azurerm/azuread provider docs.
- `docs/2.0/docs/pipelines/concepts/cloud-auth/azure.md` — Inline comment in the worked example noting the new attribute. New top-level **"Azure sovereign cloud support"** section explaining the default, the accepted values, the `ARM_ENVIRONMENT` plumbing, the provider/backend implications, and links to the new tutorial.
- `docs/2.0/docs/pipelines/tutorials/deploying-to-azure-government.mdx` (new) — Full tutorial modeled on `deploying-to-aws-gov-cloud.mdx`: prerequisites, overview of the three configuration points, Entra ID setup walkthrough via `portal.azure.us` (GitHub/GitLab tabs), HCL update with `cloud_environment`, `root.hcl` provider block update, Boilerplate vending (GitHub/GitLab tabs with `CloudEnvironment: usgovernment`), local testing via `az cloud set --name AzureUSGovernment`, and a troubleshooting table covering common failure modes.
- `sidebars/docs.js` — New entry "Connecting to Azure Government" in the Pipelines → Tutorials category, directly after "Deploying to AWS GovCloud".
- `cspell.json` — Added `azurerm`, `usgovernment`, `usgovcloudapi` to the allowlist.

### `terragrunt-scale-catalog` (gruntwork-io/terragrunt-scale-catalog)

- `templates/boilerplate/.dependencies/azure/subscription/.gruntwork/environment-{{ .SubscriptionName }}.hcl` — `azure_oidc` block now sets `cloud_environment = "{{ .CloudEnvironment }}"` with an explanatory comment.
- `templates/boilerplate/.dependencies/azure/subscription/boilerplate.yml` — New `CloudEnvironment` variable (default `"public"`); existing `State*` variables renumbered to make room.
- `templates/boilerplate/.dependencies/azure/base/root.hcl` — Generated `azurerm` and `azuread` provider blocks now set `environment = "{{ .CloudEnvironment }}"` so local Terragrunt runs target the same cloud as Pipelines.
- `templates/boilerplate/.dependencies/azure/base/boilerplate.yml` — New `CloudEnvironment` variable.
- `templates/boilerplate/azure/{github,gitlab}/subscription/boilerplate.yml` — New `CloudEnvironment` variable so vending a subscription directly threads the value into the dependency template.
- `templates/boilerplate/azure/{github,gitlab}/infrastructure-live/boilerplate.yml` — New `CloudEnvironment` variable so the infrastructure-live render also threads the value through to `root.hcl` and the subscription environment HCL.
- `templates/boilerplate/azure/{github,gitlab}/subscription/README.md` — Documented `CloudEnvironment` in the variable table with a link to the new docs tutorial.

### Caveats for the PR description

- **No end-to-end verification against a real Azure Government tenant.** The CLI change is mechanical (set `ARM_ENVIRONMENT`), but the only true "confirm support" signal is a live plan/apply against `*.usgovcloudapi.net` endpoints, which this PR does not exercise.
- **Bootstrap stack does not yet accept an `environment` value.** The shared `stacks/azure/{github,gitlab}/pipelines-bootstrap` stack (referenced by the rendered `bootstrap/terragrunt.stack.hcl`) still emits an unscoped `provider "azurerm" { features {} }` from its own `root.hcl`. Bootstrapping a fresh Azure Government subscription via this PR will fail at the bootstrap step until that stack is updated to accept a `cloud_environment` input. Adding that input is out of scope for this PR but is the natural follow-up.
- **`german` (Azure Germany) was retired by Microsoft in 2021.** Included to match the azurerm provider's accepted set exactly.
- **No experiment flag.** Default `"public"` preserves the existing behavior bit-for-bit, so per RFC-169 this ships as a pure addition without a `PIPELINES_FEATURE_EXPERIMENT_*` gate.

Related PRs in this change set

Summary by CodeRabbit

  • Documentation

    • Added guidance for using Azure sovereign cloud environments, including Azure Government setup and endpoint matching.
    • Introduced a new tutorial for configuring Pipelines with Azure Government.
    • Updated the Pipelines sidebar to surface the new Azure Government tutorial.
  • Chores

    • Expanded the spellcheck word list with Azure-related terms.

@vercel

vercel Bot commented Jun 26, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview, Comment Jun 26, 2026 6:31pm

Request Review

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Updated Azure Pipelines docs to describe sovereign cloud support for Azure OIDC, add a new Azure Government tutorial, add a tutorial sidebar link, and extend spellcheck terms for the new cloud names.

Changes

Azure sovereign cloud documentation

Layer / File(s) Summary
Azure OIDC docs
docs/2.0/docs/pipelines/concepts/cloud-auth/azure.md, docs/2.0/reference/pipelines/configurations-as-code/api.mdx, cspell.json
The Azure OIDC concept page and API reference add cloud_environment guidance for sovereign cloud targeting, and cspell adds the new cloud and provider terms.
Azure Government tutorial
docs/2.0/docs/pipelines/tutorials/deploying-to-azure-government.mdx
The new tutorial covers Entra ID app registrations, Pipelines cloud_environment configuration, provider and backend alignment, Boilerplate setup, validation, and troubleshooting.
Tutorial sidebar
sidebars/docs.js
The Pipelines Tutorials sidebar adds a link to the Azure Government tutorial.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • Resonance1584
  • yhakbar

Poem

🐇 I hopped through sovereign clouds of blue,
with usgovernment shining through.
The OIDC trail is set just right,
and Azure docs now guide the flight.
Thump-thump! A sidebar hop for you.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding Azure Government support in Pipelines.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude-pr/PF-190-28256470055

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/2.0/docs/pipelines/concepts/cloud-auth/azure.md`:
- Around line 155-157: The Azure provider guidance is incorrect for Azure Stack:
the `environment` attribute on `azurerm` and `azuread` should not be described
as supporting `stack`. Update the docs around the `environment` guidance to say
`stack` is a Pipelines-specific value, while local Terraform/Terragrunt runs
must use the standard provider environments (`public`, `usgovernment`, `china`,
`german`) and configure Azure Stack via `metadata_host`/`ARM_METADATA_HOST` or
the dedicated `azurestack` provider logic in the relevant docs section.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c91c03b8-d12c-440d-a44f-de117b412c32

📥 Commits

Reviewing files that changed from the base of the PR and between ffa5f8b and e7c6b99.

📒 Files selected for processing (5)
  • cspell.json
  • docs/2.0/docs/pipelines/concepts/cloud-auth/azure.md
  • docs/2.0/docs/pipelines/tutorials/deploying-to-azure-government.mdx
  • docs/2.0/reference/pipelines/configurations-as-code/api.mdx
  • sidebars/docs.js

Comment on lines +155 to +157
Accepted values (lowercase, matching the azurerm provider): `public`, `usgovernment`, `china`, `german`, `stack`.

To make local Terragrunt runs target the same cloud as Pipelines, pass the same value to the `environment` attribute of your `azurerm` and `azuread` provider blocks (typically generated by your `root.hcl`). The OpenTofu/Terraform state backend (`backend "azurerm"`) must also be configured for the target cloud.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major

🧩 Analysis chain

🌐 Web query:

azure rm terraform provider environment attribute valid values stack AzureStack

💡 Result:

When using the Terraform AzureRM provider (hashicorp/azurerm), the environment attribute is intended for standard Azure cloud environments [1][2][3]. Valid values for this attribute are public, usgovernment, german, and china [1][2][3]. The environment attribute is not used to target Azure Stack Hub [1]. Instead, to connect to Azure Stack Hub, you should use the dedicated hashicorp/azurestack provider [4][5]. If you are using the azurestack provider: - Do not use the environment attribute for Azure Stack Hub connectivity. - Instead, use the metadata_host attribute to specify the FQDN hostname of your Azure Metadata Service (e.g., management.region.mystack.ca) [4][6]. - This value can also be configured via the ARM_METADATA_HOST environment variable [4][7]. In specialized scenarios where users have attempted to force the azurerm provider to work with non-public Azure clouds (like Azure Stack) by setting environment="STACK", this is generally considered an unsupported or undocumented workaround that typically requires additional configuration via external environment variables (such as AZURE_ENVIRONMENT_FILEPATH) to define custom endpoints [8]. For stable production use, the official azurestack provider remains the supported path for Azure Stack Hub [4][5].

Citations:


🌐 Web query:

azuread terraform provider environment attribute valid values stack AzureStack

💡 Result:

The azuread Terraform provider's environment attribute does not include a specific "AzureStack" value. The environment attribute in the azuread provider is used to define the Azure cloud environment (e.g., global, usgovernmentl4, china) to which the provider connects [1][2][3]. For scenarios involving Azure Stack, the azuread provider is generally not the intended provider for managing Azure Stack resources; instead, the azurestack provider is used [4]. In the azurestack provider, there is no direct environment attribute equivalent to the azuread provider's cloud selection [4]. Instead, you must explicitly configure the metadata_host attribute to point to the Azure Metadata Service endpoint for your specific Azure Stack instance (e.g., https://management.westus.mydomain.ca) [4][5]. In summary: 1. The azuread provider's environment attribute supports: global (or public), usgovernmentl4 (or usgovernment), usgovernmentl5 (or dod), germany (or german), and china [1][3]. 2. There is no AzureStack value for this attribute in the azuread provider [1][2][3]. 3. For Azure Stack, use the azurestack provider and configure the metadata_host argument [4].

Citations:


Correct the Terraform provider guidance for Azure Stack (stack).

The documentation incorrectly states that stack is a valid value for the environment attribute in the azurerm and azuread providers. Official Terraform provider documentation confirms that environment only supports public, usgovernment, china, and german.

For Azure Stack environments, local runs must not use environment = "stack". Instead, users should configure the metadata_host attribute (or set the ARM_METADATA_HOST environment variable) to point to their Azure Stack endpoint, or use the dedicated azurestack provider logic.

Update the text to clarify that while Pipelines accepts stack, local configurations require custom metadata settings rather than a shared environment value.

Suggested doc fix
-Accepted values (lowercase, matching the azurerm provider): `public`, `usgovernment`, `china`, `german`, `stack`.
-
-To make local Terragrunt runs target the same cloud as Pipelines, pass the same value to the `environment` attribute of your `azurerm` and `azuread` provider blocks (typically generated by your `root.hcl`). The OpenTofu/Terraform state backend (`backend "azurerm"`) must also be configured for the target cloud.
+Accepted values for Pipelines are: `public`, `usgovernment`, `china`, `german`, `stack`.
+
+To make local Terragrunt runs target the same cloud as Pipelines, configure `azurerm`, `azuread`, and the `azurerm` backend using the provider/backend settings they document for that cloud. Built-in sovereign clouds can use the `environment` attribute; Azure Stack/custom clouds require configuring the `metadata_host` attribute (or the `ARM_METADATA_HOST` environment variable) as documented by the providers, rather than passing `stack` to `environment`.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Accepted values (lowercase, matching the azurerm provider): `public`, `usgovernment`, `china`, `german`, `stack`.
To make local Terragrunt runs target the same cloud as Pipelines, pass the same value to the `environment` attribute of your `azurerm` and `azuread` provider blocks (typically generated by your `root.hcl`). The OpenTofu/Terraform state backend (`backend "azurerm"`) must also be configured for the target cloud.
Accepted values for Pipelines are: `public`, `usgovernment`, `china`, `german`, `stack`.
To make local Terragrunt runs target the same cloud as Pipelines, configure `azurerm`, `azuread`, and the `azurerm` backend using the provider/backend settings they document for that cloud. Built-in sovereign clouds can use the `environment` attribute; Azure Stack/custom clouds require configuring the `metadata_host` attribute (or the `ARM_METADATA_HOST` environment variable) as documented by the providers, rather than passing `stack` to `environment`.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/2.0/docs/pipelines/concepts/cloud-auth/azure.md` around lines 155 - 157,
The Azure provider guidance is incorrect for Azure Stack: the `environment`
attribute on `azurerm` and `azuread` should not be described as supporting
`stack`. Update the docs around the `environment` guidance to say `stack` is a
Pipelines-specific value, while local Terraform/Terragrunt runs must use the
standard provider environments (`public`, `usgovernment`, `china`, `german`) and
configure Azure Stack via `metadata_host`/`ARM_METADATA_HOST` or the dedicated
`azurestack` provider logic in the relevant docs section.


There are three places where the Azure cloud environment must be set for a working Azure Government setup:

1. **Entra ID application registrations**: created in the [Azure Government portal](https://portal.azure.us), not the public Azure portal.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this not going to be bootstrapped the same way it is for non-government set ups? It doesn't seem like we assume that for the AWS gov cloud setup.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants