Azure / terraform-provider-azapi

Terraform provider for Azure Resource Manager Rest API
https://registry.terraform.io/providers/Azure/azapi/latest
Mozilla Public License 2.0
170 stars 47 forks source link

Azure CLI authentication does not work on Microsoft-Hosted agents #551

Open jaredfholgate opened 2 weeks ago

jaredfholgate commented 2 weeks ago

Hi

Summary

When attempting to use az cli auth in Azure DevOps or GitHub with a Microsoft hosted agent, the provider erroneously attempts MSI auth and fails with the following error:

Error: Failed to retrieve resource
│ 
│   with azapi_resource.resource_group_management,
│   on main.tf line 14, in resource "azapi_resource" "resource_group_management":
│   14: resource "azapi_resource" "resource_group_management" {
│ 
│ checking for presence of existing Resource: (ResourceId
│ "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testing123"
│ / Api Version "2021-04-01"): ChainedTokenCredential authentication failed
│ GET http://169.254.169.254/metadata/identity/oauth2/token
│ --------------------------------------------------------------------------------
│ RESPONSE 400 Bad Request
│ --------------------------------------------------------------------------------
│ {
│   "error": "invalid_request",
│   "error_description": "Identity not found"
│ }
│ --------------------------------------------------------------------------------

This is due to the fact that Microsoft-hosted agents are hosted in Azure and do have an MSI endpoint, but no associated identity.

The same would likely be true for self-hosted agents hosted in Azure with no managed identity attached.

How to Replicate

Replace the subscription GUID...

Pipeline:

trigger:
- main

pool:
  vmImage: ubuntu-latest

steps:
  - task: AzureCLI@2
    displayName: Testing
    inputs:
      azureSubscription: testing123
      scriptType: pscore
      scriptLocation: inlineScript
      inlineScript: |
        terraform init
        terraform validate
        terraform plan -input=false -out=tfplan -no-color
        terraform apply -auto-approve -input=false tfplan
        terraform destroy -auto-approve -input=false

Terraform:

terraform {
  required_version = "~> 1.8"
  required_providers {
    azapi = {
      source  = "Azure/azapi"
      version = "~> 1.13"
    }
  }
}

provider "azapi" {}

resource "azapi_resource" "resource_group_management" {
  parent_id = "/subscriptions/00000000-0000-0000-0000-000000000000"
  type      = "Microsoft.Resources/resourceGroups@2021-04-01"
  name      = "testing123"
  location  = "uksouth"
  body = {
    properties = {}
  }
  schema_validation_enabled = false
}

Suggested Solution

Do not attempt MSI auth unless use_msi is explicity set to true.

Workaround

Explicitly set the environment variables like this:


trigger:
- main

pool:
  vmImage: ubuntu-latest

steps:
  - task: AzureCLI@2
    displayName: Testing
    inputs:
      azureSubscription: testing123
      scriptType: pscore
      scriptLocation: inlineScript
      addSpnToEnvironment: true  # MUST BE TRUE
      inlineScript: |
        terraform init
        terraform validate

        $env:ARM_CLIENT_ID=$env:servicePrincipalId
        $env:ARM_CLIENT_SECRET=$env:servicePrincipalKey
        $env:ARM_TENANT_ID=$env:tenantId
        $env:ARM_SUBSCRIPTION_ID="00000000-0000-0000-0000-000000000000"  # Not required for management group scoped service connection

        terraform plan -input=false -out=tfplan -no-color
        terraform apply -auto-approve -input=false tfplan
        terraform destroy -auto-approve -input=false
jaredfholgate commented 2 weeks ago

This issue is similar to https://github.com/Azure/terraform-provider-azapi/issues/491, but wanted to provide a specific example. This issue is impacting customers as azapi adoption increases. The azurerm provider does not have the same problem.

stemaMSFT commented 2 weeks ago

I believe MSI is the security recommendation nowadays @jaredfholgate but correct me if I'm wrong. If so, would there be a way in your eyes to be more resilient with MSI auth or do you think we need to explicitly require a user to enable MSI auth?

jaredfholgate commented 2 weeks ago

For deploy time secrets (as in this use case) the recommendation is OIDC (Workload identity federation). MSI is not recommended if you can use OIDC instead. But MSI is better than anything involving a secret.

With regards to az CLI, this can support OIDC, MSI and other types of auth. It is not just for user auth. Using az CLI is a good option as it has built in support for renewing OIDC creds. Unfortunately, the azurerm backend does not support az CLI for these scenarios, which is a real limitation at the moment.

To summarise, I don't believe we should be attempting MSI auth unless it is explicitly specified. The default should be az CLI as per the other providers and we should have first class support for OIDC and id token expiration renewal. Happy to discuss further around this and help explain, feel free to ping me on Teams.