hashicorp / terraform

Terraform enables you to safely and predictably create, change, and improve infrastructure. It is a source-available tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned.
https://www.terraform.io/
Other
41.76k stars 9.42k forks source link

Error: Error building ARM Config: Authenticating using the Azure CLI is only supported as a User (not a Service Principal). #34456

Closed krupavanigundraju closed 1 week ago

krupavanigundraju commented 6 months ago

Terraform Version

1.4.6

Terraform Configuration Files

          displayName: 'Terraform > Initialize'
          addSpnToEnvironment: true
          inputs:
            azureSubscription:  'serviceconnectioname'
            scriptType: bash
            addSpnToEnvironment: true
            useGlobalConfig: true
            scriptLocation: inlineScript          
            inlineScript: |
                terraform -chdir=${{ parameters.workdir }} init -backend-config=$(backend.secureFilePath)

Debug Output

terraform initialize should work without any error

Expected Behavior

terraform initialize should work without any error

Actual Behavior

│ Error: Error building ARM Config: Authenticating using the Azure CLI is only supported as a User (not a Service Principal).
│ 
│ To authenticate to Azure using a Service Principal, you can use the separate 'Authenticate using a Service Principal'
│ auth method - instructions for which can be found here: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/service_principal_client_secret
│ 
│ Alternatively you can authenticate using the Azure CLI by using a User Account.

Steps to Reproduce

    - task: AzureCLI@2
      displayName: 'Terraform > Initialize'
      addSpnToEnvironment: true
      inputs:
        azureSubscription:  'xxx'
        scriptType: bash
        addSpnToEnvironment: true
        useGlobalConfig: true
        scriptLocation: inlineScript          
        inlineScript: |
            terraform -chdir=${{ parameters.workdir }} init -backend-config=$(backend.secureFilePath)

Additional Context

Hi Team,

We are trying to authenticate azure using azurecli with service connection, but the connectivity failed with above error.

References

No response

git-of-aj commented 6 months ago

@krupavanigundraju I faced same issue with Azure Pipelines and did some testing.

My Observation :

The Work Around I am using is declaring the secrets using environment variables Do You have any other suggestions?

gutzi commented 6 months ago

I noticed the same behavior when I set up the login process using the 'Login With OpenID Connect (OIDC)' method, as described in Azure Login GitHub Marketplace Action. This login variant is marked as recommended.

However, I am still trying to fully understand this behavior. I'm uncertain if it's due to a technical limitation that I've overlooked, or if it's a feature not yet implemented but planned for future release. Information about a timeline for this would be helpful.

Generally speaking, logging in via OIDC and using a service principle is highly advantageous, as it eliminates the need to persist secrets.

justinmchase commented 6 months ago

I am also seeing this issue this morning. As of Friday the same pipeline was able to authenticate with OIDC in GitHub actions but this morning I'm seeing this issue. It appears to be a breaking change in the Azure provider perhaps which released version v3.87.0 on Friday but I'm not sure of the root cause yet.

hegerdes commented 4 months ago

I also encountered this in github actions quite a while ago. But I opened a issue in the azure provider. Does this need to be fixed in terraform or the provider?

Link: https://github.com/hashicorp/terraform-provider-azurerm/issues/22034

Using az auth with service principals is allowed for creating ressources but not for backend config. This is really counter intuitive and requires additional configuration which should not be needed.

crw commented 3 months ago

To be honest, I'm not sure. Looking at the "Terraform Config" section of the original post, that is all YAML. I assume it is the configuration for some kind of CI/CD process that is running terraform (Azure Pipelines?), so I am unclear if this is even an issue in Terraform at all.

In any case, if it has to do with the Azure state storage backend, the issue belongs in the core repo (here). If the issue is in some aspect of the provider, it belongs in terraform-provider-azure. In both cases, the Azure Provider team will be looking at the issue.

hegerdes commented 3 months ago

I think this is a terraform issue @crw. Terraform is responsible for handling/saving the state, this includes the different backend providers. So terraform also needs to authenticate against the state backend providers (here azure) additionally to the terraform resource provider/plugin (azurerm). The problem is (which causes the above issue) that the state backend provider for azure and the terraform resource provider (azurerm) use different methods to authenticate against the azure api.

I looked into the code thinking of fixing this and creating a PR but I found that terraform uses its own github.com/hashicorp/go-azure-helpers module for auth. The used version is v0.43.0 form 1 1/2 years ago the latest version is v0.66.2 which has quiet some differences and breaking changes. I did not find the usage of the standard go-azure-sdk (used in azurerm) which would make cli auth easy. But at this point I decided that this issue is too big for an outsider and I would probably break stuff because I'm not familiar enough with terraforms codebase.

It would be great if some hashicorp/azure devs cloud look into this and in the best case use the same auth mechanism for state and resources.

Dipak-Mistry-WTW commented 3 months ago

This does work now. Follow instructions here: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/service_principal_oidc backend https://developer.hashicorp.com/terraform/language/settings/backends/azurerm In the end all I had to do was add use_oidc = true to both provider block and backend block.

nickveldrin commented 2 months ago

edit
I had run into this issue on my runner config, but i think the problem was somehow on my secrets or configuration.

After i re-inputted my secrets and then set them up in the env, i was able to run the terraform init.

env was as follows: env: ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }} ARM_CLIENT_SECRET: ${{ secrets.ARM_CLIENT_SECRET }} ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }} ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }} RESOURCE_GROUP: ${{ secrets.RESOURCE_GROUP }} STORAGE_ACCOUNT: ${{ secrets.STORAGE_ACCOUNT }} CONTAINER_NAME: ${{ secrets.CONTAINER_NAME }} KEY: ${{ secrets.KEY }}

Then my run:

terraform init -reconfigure -input=false -backend-config="storage_account_name=${{ env.STORAGE_ACCOUNT }}" -backend-config="container_name=${{ env.CONTAINER_NAME }}" -backend-config="key=${{ env.KEY }}" -backend-config="resource_group_name=${{ env.RESOURCE_GROUP }}"

alejo-maya commented 1 week ago

Hi guys, I had exactly the same problem in my workflow and I solved it by reading your comments. Thank you very much!

crw commented 1 week ago

Going to close this issue as it seems to be resolved, please let me know if this is in fact not resolved. Thanks!