hashicorp / terraform-provider-azuread

Terraform provider for Azure Active Directory
https://registry.terraform.io/providers/hashicorp/azuread/latest/docs
Mozilla Public License 2.0
415 stars 280 forks source link

OIDC / Github auth requires undocumented flag #1396

Closed roy-work closed 1 month ago

roy-work commented 1 month ago

Community Note

Terraform (and AzureAD Provider) Version

v2.50.0 & HEAD of the provider.

Terraform v1.5.7

Affected Resource(s)

Terraform Configuration Files

# Copy-paste your Terraform configurations here - for large Terraform configs,
# please use a service like Dropbox and share a link to the ZIP file. For
# security, you can also encrypt the files using our GPG public key: https://keybase.io/hashicorp

Debug Output

Debug output ``` 024-05-30T19:56:33.785Z [INFO] provider.terraform-provider-azuread_v2.50.0_x5: 2024/05/30 19:56:33 [DEBUG] Configuring built-in cloud environment by name: "global": timestamp=2024-05-30T19:56:33.785Z 2024-05-30T19:56:33.786Z [INFO] provider.terraform-provider-azuread_v2.50.0_x5: 2024/05/30 19:56:33 [DEBUG] az-cli invocation: az version -o=json: timestamp=2024-05-30T19:56:33.785Z Error: -30T19:56:40.716Z [ERROR] vertex "provider[\"registry.terraform.io/hashicorp/azuread\"]" error: unable to build authorizer: could not configure AzureCli Authorizer: obtaining subscription ID: obtaining account details: running Azure CLI: exit status 1: ERROR: Please run 'az login' to setup account. Error: -30T19:56:40.717Z [ERROR] provider.terraform-provider-azuread_v2.50.0_x5: Response contains error diagnostic: diagnostic_severity=ERROR diagnostic_summary="unable to build authorizer: could not configure AzureCli Authorizer: obtaining subscription ID: obtaining account details: running Azure CLI: exit status 1: ERROR: Please run 'az login' to setup account." tf_proto_version=5.4 tf_req_id=ac1f31db-ce6e-ba21-9124-19b6d377aa6d @module=sdk.proto diagnostic_detail= tf_provider_addr=provider tf_rpc=Configure @caller=github.com/hashicorp/terraform-plugin-go@v0.19.0/tfprotov5/internal/diag/diagnostics.go:58 timestamp=2024-05-30T19:56:40.716Z ```

Panic Output

Expected Behavior

Set up OIDC authentication with Github & Azure, following the documentation here, subsection "GitHub Actions"

One expects that to work.

Actual Behavior

Authentication will fail, with a spurious message about being unable to find az. The message is a red herring.

│ Error: unable to build authorizer: could not configure AzureCli Authorizer: obtaining subscription ID: obtaining account details: running Azure CLI: exit status 1: ERROR: Please run 'az login' to setup account.
│ 
│   with provider["registry.terraform.io/hashicorp/azuread"],
│   on main.tf line 23, in provider "azuread":
│   23: provider "azuread" {

Steps to Reproduce

  1. terraform plan

Important Factoids

This bug applies equally to azurerm, AFAICT.

The provider sets up this structure (here in the code):

        authConfig := &auth.Credentials{
            Environment: *env,
            ClientID:    *clientId,
            TenantID:    *tenantId,

            ClientCertificateData:     certData,
            ClientCertificatePassword: d.Get("client_certificate_password").(string),
            ClientCertificatePath:     d.Get("client_certificate_path").(string),
            ClientSecret:              *clientSecret,

            OIDCAssertionToken:          *idToken,
            GitHubOIDCTokenRequestURL:   d.Get("oidc_request_url").(string),
            GitHubOIDCTokenRequestToken: d.Get("oidc_request_token").(string),

            CustomManagedIdentityEndpoint: d.Get("msi_endpoint").(string),

            EnableAuthenticatingUsingAzureCLI:          enableAzureCli,
            EnableAuthenticatingUsingClientCertificate: true,
            EnableAuthenticatingUsingClientSecret:      true,
            EnableAuthenticatingUsingManagedIdentity:   enableManagedIdentity,
            EnableAuthenticationUsingGitHubOIDC:        enableOidc,
            EnableAuthenticationUsingOIDC:              enableOidc,
        }

I think this is the operative flag; it gets used here:

vendor/github.com/hashicorp/go-azure-sdk/sdk/auth/auth.go                                         
93:     if c.EnableAuthenticationUsingGitHubOIDC && strings.TrimSpace(c.TenantID) != "" && strings.TrimSpace(c.ClientID) != "" && strings.TrimSpace(c.GitHubOIDCTokenRequestURL) != "" && strings.TrimSpace(c.GitHubOIDCTokenRequestToken) != "" {                                                    

So EnableAuthenticationUsingGitHubOIDC needs to be true. Thus enableOidc must be true. In a custom build of the provider I did, I logged this variable, and it was false, even after I'd followed the linked docs to the best of my ability.

Tugging on the root (same file),

        var (
            enableAzureCli        = d.Get("use_cli").(bool)
            enableManagedIdentity = d.Get("use_msi").(bool)
            enableOidc            = d.Get("use_oidc").(bool) || d.Get("use_aks_workload_identity").(bool)
        )

We're not an AKS workload identity, so d.get("use_oidc") needs to evaluate to true. That is a flag (still same file):

            // OIDC specific fields
            "use_oidc": {
                Type:        pluginsdk.TypeBool,
                Optional:    true,
                DefaultFunc: pluginsdk.EnvDefaultFunc("ARM_USE_OIDC", false),
                Description: "Allow OpenID Connect to be used for authentication",
            },

And we can see that that is defaulted to false. The documentation _never instructs the user to set ARM_USE_OIDC_, so this seems like probably an error in the documentation, or possibly a bad default, but as a user it isn't clear to be how this is supposed to work. The variable is never explained nor mentioned along the relevant documentation path, AFAICT, but AFAICT, it is required to be set in order for this flow to work.

(The docs do make a mention of this environment variable, but only in an example in an unrelated section, "Azure DevOps Pipelines", which I didn't follow as it wasn't relevant. The example is in some language I'm not familiar with, too, so I didn't know it was a env var until later when I knew it was. Similarly, there are mentions of use_oidc in the Terraform provider {} block setup, but all occurrences are similarly in sections not relevant to me, and thus, unread. They're also "not recommended".)

References

manicminer commented 1 month ago

Hi @roy-work, thanks for opening this issue. Whilst I appreciate your attention to detail and thorough issue description, our documentation does actually cover the use_oidc provider property (and its corresponding ARM_USE_OIDC environment variable). It's included in the provider reference documentation, where it's described along with the default setting, and additionally in our OpenID Connect Guide which you linked to above, and which has complete examples for configuration via environment variable and in the provider block.

Also mentioned in the documentation is the use_cli provider property, which for both historical and UX reasons defaults to true. You can disable this auth mechanism to prevent the provider attempting to fall back to calling Azure CLI. This could probably also be covered in our various authentication guides, so I'll look to add a note to those in case that option isn't clear in the provider reference. I would contend that it's not necessarily a red herring to surface this error message since, statistically, a majority of users running Terraform locally, do use Azure CLI for authentication.

Since I believe we do actually cover this in detail in our docs (and you can find similar coverage in the AzureRM provider documentation), I'll go ahead and close this issue. If you'd like any further help with usage of the Azure providers, I encourage you to join our Slack community - details in the README - as we try to keep GitHub issues focused on bug reports and feature requests.