backend/azure: Remove legacy helper/schema dependency [rebased] (#37225)

* backend/azure: Remove legacy helper/schema dependency

This now uses the backendbase package's "SDK-like" helpers instead, which
provide a much smaller subset of the former legacy SDK functionality but
enough for what this backend needs.

* remove unused replace directive

* Fix go.mod file after rebase

* Fix schema errors after self-review of code

* Change `metadata_host` to be an optional field in the schema, to match the current behavior of code

---------

Co-authored-by: Martin Atkins <mart@degeneration.co.uk>
Co-authored-by: James Bardin <j.bardin@gmail.com>
pull/37240/head
Sarah French 11 months ago committed by GitHub
parent 540512e27b
commit 481bef3759
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -10,243 +10,319 @@ import (
"github.com/hashicorp/go-azure-sdk/sdk/auth"
"github.com/hashicorp/go-azure-sdk/sdk/environments"
"github.com/zclconf/go-cty/cty"
"github.com/hashicorp/terraform/internal/backend"
"github.com/hashicorp/terraform/internal/legacy/helper/schema"
"github.com/hashicorp/terraform/internal/backend/backendbase"
"github.com/hashicorp/terraform/internal/configs/configschema"
"github.com/hashicorp/terraform/internal/tfdiags"
)
// New creates a new backend for Azure remote state.
func New() backend.Backend {
s := &schema.Backend{
Schema: map[string]*schema.Schema{
"subscription_id": {
Type: schema.TypeString,
Optional: true,
Description: "The Subscription ID where the Storage Account is located.",
DefaultFunc: schema.EnvDefaultFunc("ARM_SUBSCRIPTION_ID", ""),
},
"resource_group_name": {
Type: schema.TypeString,
Optional: true,
Description: "The Resource Group where the Storage Account is located.",
},
"storage_account_name": {
Type: schema.TypeString,
Required: true,
Description: "The name of the storage account.",
},
"container_name": {
Type: schema.TypeString,
Required: true,
Description: "The container name to use in the Storage Account.",
},
"key": {
Type: schema.TypeString,
Required: true,
Description: "The blob key to use in the Storage Container.",
},
"lookup_blob_endpoint": {
Type: schema.TypeBool,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("ARM_USE_DNS_ZONE_ENDPOINT", false),
Description: "Whether to look up the storage account blob endpoint. This is necessary when the storage account uses the Azure DNS zone endpoint.",
},
"snapshot": {
Type: schema.TypeBool,
Optional: true,
Description: "Whether to enable automatic blob snapshotting.",
DefaultFunc: schema.EnvDefaultFunc("ARM_SNAPSHOT", false),
},
"environment": {
Type: schema.TypeString,
Optional: true,
Description: "The Cloud Environment which should be used. Possible values are public, usgovernment, and china. Defaults to public. Not used and should not be specified when `metadata_host` is specified.",
DefaultFunc: schema.EnvDefaultFunc("ARM_ENVIRONMENT", "public"),
},
"metadata_host": {
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.MultiEnvDefaultFunc([]string{"ARM_METADATA_HOSTNAME", "ARM_METADATA_HOST"}, ""), // TODO: remove support for `METADATA_HOST` in a future version
Description: "The Hostname which should be used for the Azure Metadata Service.",
},
"access_key": {
Type: schema.TypeString,
Optional: true,
Description: "The access key to use when authenticating using a Storage Access Key.",
DefaultFunc: schema.EnvDefaultFunc("ARM_ACCESS_KEY", ""),
},
"sas_token": {
Type: schema.TypeString,
Optional: true,
Description: "The SAS Token to use when authenticating using a SAS Token.",
DefaultFunc: schema.EnvDefaultFunc("ARM_SAS_TOKEN", ""),
},
"tenant_id": {
Type: schema.TypeString,
Optional: true,
Description: "The Tenant ID to use when authenticating using Azure Active Directory.",
DefaultFunc: schema.EnvDefaultFunc("ARM_TENANT_ID", ""),
},
"client_id": {
Type: schema.TypeString,
Optional: true,
Description: "The Client ID to use when authenticating using Azure Active Directory.",
DefaultFunc: schema.EnvDefaultFunc("ARM_CLIENT_ID", ""),
},
"client_id_file_path": {
Type: schema.TypeString,
Optional: true,
Description: "The path to a file containing the Client ID which should be used.",
DefaultFunc: schema.EnvDefaultFunc("ARM_CLIENT_ID_FILE_PATH", nil),
},
"endpoint": {
Type: schema.TypeString,
Optional: true,
Deprecated: "`endpoint` is deprecated in favor of `msi_endpoint`, it will be removed in a future version of Terraform",
},
// Client Certificate specific fields
"client_certificate": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("ARM_CLIENT_CERTIFICATE", ""),
Description: "Base64 encoded PKCS#12 certificate bundle to use when authenticating as a Service Principal using a Client Certificate",
return &Backend{
Base: backendbase.Base{
Schema: &configschema.Block{
Attributes: map[string]*configschema.Attribute{
"subscription_id": {
Type: cty.String,
Optional: true,
Description: "The Subscription ID where the Storage Account is located.",
},
"resource_group_name": {
Type: cty.String,
Optional: true,
Description: "The Resource Group where the Storage Account is located.",
},
"storage_account_name": {
Type: cty.String,
Required: true,
Description: "The name of the storage account.",
},
"container_name": {
Type: cty.String,
Required: true,
Description: "The container name to use in the Storage Account.",
},
"key": {
Type: cty.String,
Required: true,
Description: "The blob key to use in the Storage Container.",
},
"lookup_blob_endpoint": {
Type: cty.Bool,
Optional: true,
Description: "Whether to look up the storage account blob endpoint. This is necessary when the storage account uses the Azure DNS zone endpoint.",
},
"snapshot": {
Type: cty.Bool,
Optional: true,
Description: "Whether to enable automatic blob snapshotting.",
},
"environment": {
Type: cty.String,
Optional: true,
Description: "The Cloud Environment which should be used. Possible values are public, usgovernment, and china. Defaults to public. Not used and should not be specified when `metadata_host` is specified.",
},
"metadata_host": {
Type: cty.String,
Optional: true,
Description: "The Hostname which should be used for the Azure Metadata Service.",
},
"access_key": {
Type: cty.String,
Optional: true,
Description: "The access key to use when authenticating using a Storage Access Key.",
},
"sas_token": {
Type: cty.String,
Optional: true,
Description: "The SAS Token to use when authenticating using a SAS Token.",
},
"tenant_id": {
Type: cty.String,
Optional: true,
Description: "The Tenant ID to use when authenticating using Azure Active Directory.",
},
"client_id": {
Type: cty.String,
Optional: true,
Description: "The Client ID to use when authenticating using Azure Active Directory.",
},
"client_id_file_path": {
Type: cty.String,
Optional: true,
Description: "The path to a file containing the Client ID which should be used.",
},
"endpoint": {
Type: cty.String,
Optional: true,
Deprecated: true,
Description: "`endpoint` is deprecated in favor of `msi_endpoint`, it will be removed in a future version of Terraform",
},
// Client Certificate specific fields
"client_certificate": {
Type: cty.String,
Optional: true,
Description: "Base64 encoded PKCS#12 certificate bundle to use when authenticating as a Service Principal using a Client Certificate",
},
"client_certificate_path": {
Type: cty.String,
Optional: true,
Description: "The path to the Client Certificate associated with the Service Principal for use when authenticating as a Service Principal using a Client Certificate.",
},
"client_certificate_password": {
Type: cty.String,
Optional: true,
Description: "The password associated with the Client Certificate. For use when authenticating as a Service Principal using a Client Certificate",
},
// Client Secret specific fields
"client_secret": {
Type: cty.String,
Optional: true,
Description: "The Client Secret which should be used. For use When authenticating as a Service Principal using a Client Secret.",
},
"client_secret_file_path": {
Type: cty.String,
Optional: true,
Description: "The path to a file containing the Client Secret which should be used. For use When authenticating as a Service Principal using a Client Secret.",
},
// OIDC specific fields
"use_oidc": {
Type: cty.Bool,
Optional: true,
Description: "Allow OpenID Connect to be used for authentication",
},
"ado_pipeline_service_connection_id": {
Type: cty.String,
Optional: true,
Description: "The Azure DevOps Pipeline Service Connection ID.",
},
"oidc_request_token": {
Type: cty.String,
Optional: true,
Description: "The bearer token for the request to the OIDC provider. For use when authenticating as a Service Principal using OpenID Connect.",
},
"oidc_request_url": {
Type: cty.String,
Optional: true,
Description: "The URL for the OIDC provider from which to request an ID token. For use when authenticating as a Service Principal using OpenID Connect.",
},
"oidc_token": {
Type: cty.String,
Optional: true,
Description: "The OIDC ID token for use when authenticating as a Service Principal using OpenID Connect.",
},
"oidc_token_file_path": {
Type: cty.String,
Optional: true,
Description: "The path to a file containing an OIDC ID token for use when authenticating as a Service Principal using OpenID Connect.",
},
// Managed Identity specific fields
"use_msi": {
Type: cty.Bool,
Optional: true,
Description: "Allow Managed Identity to be used for Authentication.",
},
"msi_endpoint": {
Type: cty.String,
Optional: true,
Description: "The path to a custom endpoint for Managed Identity - in most circumstances this should be detected automatically.",
},
// Azure CLI specific fields
"use_cli": {
Type: cty.Bool,
Optional: true,
Description: "Allow Azure CLI to be used for Authentication.",
},
// Azure AKS Workload Identity fields
"use_aks_workload_identity": {
Type: cty.Bool,
Optional: true,
Description: "Allow Azure AKS Workload Identity to be used for Authentication.",
},
// Feature Flags
"use_azuread_auth": {
Type: cty.Bool,
Optional: true,
Description: "Whether to use Azure Active Directory authentication to access the Storage Data Plane APIs.",
},
},
},
"client_certificate_path": {
Type: schema.TypeString,
Optional: true,
Description: "The path to the Client Certificate associated with the Service Principal for use when authenticating as a Service Principal using a Client Certificate.",
DefaultFunc: schema.EnvDefaultFunc("ARM_CLIENT_CERTIFICATE_PATH", ""),
},
"client_certificate_password": {
Type: schema.TypeString,
Optional: true,
Description: "The password associated with the Client Certificate. For use when authenticating as a Service Principal using a Client Certificate",
DefaultFunc: schema.EnvDefaultFunc("ARM_CLIENT_CERTIFICATE_PASSWORD", ""),
},
// Client Secret specific fields
"client_secret": {
Type: schema.TypeString,
Optional: true,
Description: "The Client Secret which should be used. For use When authenticating as a Service Principal using a Client Secret.",
DefaultFunc: schema.EnvDefaultFunc("ARM_CLIENT_SECRET", ""),
},
"client_secret_file_path": {
Type: schema.TypeString,
Optional: true,
Description: "The path to a file containing the Client Secret which should be used. For use When authenticating as a Service Principal using a Client Secret.",
DefaultFunc: schema.EnvDefaultFunc("ARM_CLIENT_SECRET_FILE_PATH", nil),
},
// OIDC specific fields
"use_oidc": {
Type: schema.TypeBool,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("ARM_USE_OIDC", false),
Description: "Allow OpenID Connect to be used for authentication",
},
"ado_pipeline_service_connection_id": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.MultiEnvDefaultFunc([]string{"ARM_ADO_PIPELINE_SERVICE_CONNECTION_ID", "ARM_OIDC_AZURE_SERVICE_CONNECTION_ID"}, nil),
Description: "The Azure DevOps Pipeline Service Connection ID.",
},
"oidc_request_token": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.MultiEnvDefaultFunc([]string{"ARM_OIDC_REQUEST_TOKEN", "ACTIONS_ID_TOKEN_REQUEST_TOKEN", "SYSTEM_ACCESSTOKEN"}, nil),
Description: "The bearer token for the request to the OIDC provider. For use when authenticating as a Service Principal using OpenID Connect.",
},
"oidc_request_url": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.MultiEnvDefaultFunc([]string{"ARM_OIDC_REQUEST_URL", "ACTIONS_ID_TOKEN_REQUEST_URL", "SYSTEM_OIDCREQUESTURI"}, nil),
Description: "The URL for the OIDC provider from which to request an ID token. For use when authenticating as a Service Principal using OpenID Connect.",
},
"oidc_token": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("ARM_OIDC_TOKEN", ""),
Description: "The OIDC ID token for use when authenticating as a Service Principal using OpenID Connect.",
},
"oidc_token_file_path": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("ARM_OIDC_TOKEN_FILE_PATH", ""),
Description: "The path to a file containing an OIDC ID token for use when authenticating as a Service Principal using OpenID Connect.",
},
// Managed Identity specific fields
"use_msi": {
Type: schema.TypeBool,
Optional: true,
Description: "Allow Managed Identity to be used for Authentication.",
DefaultFunc: schema.EnvDefaultFunc("ARM_USE_MSI", false),
},
"msi_endpoint": {
Type: schema.TypeString,
Optional: true,
Description: "The path to a custom endpoint for Managed Identity - in most circumstances this should be detected automatically.",
DefaultFunc: schema.EnvDefaultFunc("ARM_MSI_ENDPOINT", ""),
},
// Azure CLI specific fields
"use_cli": {
Type: schema.TypeBool,
Optional: true,
Default: true,
DefaultFunc: schema.EnvDefaultFunc("ARM_USE_CLI", true),
Description: "Allow Azure CLI to be used for Authentication.",
},
// Azure AKS Workload Identity fields
"use_aks_workload_identity": {
Type: schema.TypeBool,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("ARM_USE_AKS_WORKLOAD_IDENTITY", false),
Description: "Allow Azure AKS Workload Identity to be used for Authentication.",
},
// Feature Flags
"use_azuread_auth": {
Type: schema.TypeBool,
Optional: true,
Description: "Whether to use Azure Active Directory authentication to access the Storage Data Plane APIs.",
DefaultFunc: schema.EnvDefaultFunc("ARM_USE_AZUREAD", false),
SDKLikeDefaults: backendbase.SDKLikeDefaults{
"subscription_id": {
EnvVars: []string{"ARM_SUBSCRIPTION_ID"},
Fallback: "",
},
"lookup_blob_endpoint": {
EnvVars: []string{"ARM_USE_DNS_ZONE_ENDPOINT"},
Fallback: "false",
},
"snapshot": {
EnvVars: []string{"ARM_SNAPSHOT"},
Fallback: "false",
},
"environment": {
EnvVars: []string{"ARM_ENVIRONMENT"},
Fallback: "public",
},
"metadata_host": {
EnvVars: []string{"ARM_METADATA_HOSTNAME", "ARM_METADATA_HOST"}, // TODO: remove support for `METADATA_HOST` in a future version
Fallback: "",
},
"access_key": {
EnvVars: []string{"ARM_ACCESS_KEY"},
Fallback: "",
},
"sas_token": {
EnvVars: []string{"ARM_SAS_TOKEN"},
Fallback: "",
},
"tenant_id": {
EnvVars: []string{"ARM_TENANT_ID"},
Fallback: "",
},
"client_id": {
EnvVars: []string{"ARM_CLIENT_ID"},
Fallback: "",
},
"client_id_file_path": {
EnvVars: []string{"ARM_CLIENT_ID_FILE_PATH"},
// no fallback
},
// Client Certificate specific fields
"client_certificate": {
EnvVars: []string{"ARM_CLIENT_CERTIFICATE"},
Fallback: "",
},
"client_certificate_path": {
EnvVars: []string{"ARM_CLIENT_CERTIFICATE_PATH"},
Fallback: "",
},
"client_certificate_password": {
EnvVars: []string{"ARM_CLIENT_CERTIFICATE_PASSWORD"},
Fallback: "",
},
// Client Secret specific fields
"client_secret": {
EnvVars: []string{"ARM_CLIENT_SECRET"},
Fallback: "",
},
"client_secret_file_path": {
EnvVars: []string{"ARM_CLIENT_SECRET_FILE_PATH"},
// no fallback
},
// OIDC specific fields
"use_oidc": {
EnvVars: []string{"ARM_USE_OIDC"},
Fallback: "false",
},
"ado_pipeline_service_connection_id": {
EnvVars: []string{"ARM_ADO_PIPELINE_SERVICE_CONNECTION_ID", "ARM_OIDC_AZURE_SERVICE_CONNECTION_ID"},
// no fallback
},
"oidc_request_token": {
EnvVars: []string{"ARM_OIDC_REQUEST_TOKEN", "ACTIONS_ID_TOKEN_REQUEST_TOKEN", "SYSTEM_ACCESSTOKEN"},
// no fallback
},
"oidc_request_url": {
EnvVars: []string{"ARM_OIDC_REQUEST_URL", "ACTIONS_ID_TOKEN_REQUEST_URL", "SYSTEM_OIDCREQUESTURI"},
// no fallback
},
"oidc_token": {
EnvVars: []string{"ARM_OIDC_TOKEN"},
Fallback: "",
},
"oidc_token_file_path": {
EnvVars: []string{"ARM_OIDC_TOKEN_FILE_PATH"},
Fallback: "",
},
// Managed Identity specific fields
"use_msi": {
EnvVars: []string{"ARM_USE_MSI"},
Fallback: "false",
},
"msi_endpoint": {
EnvVars: []string{"ARM_MSI_ENDPOINT"},
Fallback: "",
},
// Azure CLI specific fields
"use_cli": {
EnvVars: []string{"ARM_USE_CLI"},
Fallback: "true",
},
// Azure AKS Workload Identity fields
"use_aks_workload_identity": {
EnvVars: []string{"ARM_USE_AKS_WORKLOAD_IDENTITY"},
Fallback: "false",
},
// Feature Flags
"use_azuread_auth": {
EnvVars: []string{"ARM_USE_AZUREAD"},
Fallback: "false",
},
},
},
}
result := &Backend{Backend: s}
result.Backend.ConfigureFunc = result.configure
return result
}
type Backend struct {
*schema.Backend
backendbase.Base
// The fields below are set from configure
apiClient *Client
@ -267,71 +343,74 @@ type BackendConfig struct {
UseAzureADAuthentication bool
}
func (b *Backend) configure(ctx context.Context) error {
func (b *Backend) Configure(configVal cty.Value) tfdiags.Diagnostics {
// This is to make the go-azure-sdk/sdk/client Client happy.
ctx := context.Background()
if _, ok := ctx.Deadline(); !ok {
ctx, _ = context.WithTimeout(ctx, 5*time.Minute)
}
// Grab the resource data
data := schema.FromContextBackendConfig(ctx)
b.containerName = data.Get("container_name").(string)
b.accountName = data.Get("storage_account_name").(string)
b.keyName = data.Get("key").(string)
b.snapshot = data.Get("snapshot").(bool)
// This backend was originally written against the legacy plugin SDK, so
// we use some shimming here to keep things working mostly the same.
data := backendbase.NewSDKLikeData(configVal)
b.containerName = data.String("container_name")
b.accountName = data.String("storage_account_name")
b.keyName = data.String("key")
b.snapshot = data.Bool("snapshot")
var clientCertificateData []byte
if encodedCert := data.Get("client_certificate").(string); encodedCert != "" {
if encodedCert := data.String("client_certificate"); encodedCert != "" {
var err error
clientCertificateData, err = decodeCertificate(encodedCert)
if err != nil {
return err
return backendbase.ErrorAsDiagnostics(err)
}
}
oidcToken, err := getOidcToken(data)
oidcToken, err := getOidcToken(&data)
if err != nil {
return err
return backendbase.ErrorAsDiagnostics(err)
}
clientSecret, err := getClientSecret(data)
clientSecret, err := getClientSecret(&data)
if err != nil {
return err
return backendbase.ErrorAsDiagnostics(err)
}
clientId, err := getClientId(data)
clientId, err := getClientId(&data)
if err != nil {
return err
return backendbase.ErrorAsDiagnostics(err)
}
tenantId, err := getTenantId(data)
tenantId, err := getTenantId(&data)
if err != nil {
return err
return backendbase.ErrorAsDiagnostics(err)
}
var (
env *environments.Environment
envName = data.Get("environment").(string)
metadataHost = data.Get("metadata_host").(string)
envName = data.String("environment")
metadataHost = data.String("metadata_host")
)
if metadataHost != "" {
logEntry("[DEBUG] Configuring cloud environment from Metadata Service at %q", metadataHost)
if env, err = environments.FromEndpoint(ctx, fmt.Sprintf("https://%s", metadataHost)); err != nil {
return err
return backendbase.ErrorAsDiagnostics(err)
}
} else {
logEntry("[DEBUG] Configuring built-in cloud environment by name: %q", envName)
if env, err = environments.FromName(envName); err != nil {
return err
return backendbase.ErrorAsDiagnostics(err)
}
}
var (
enableAzureCli = data.Get("use_cli").(bool)
enableManagedIdentity = data.Get("use_msi").(bool)
enableOidc = data.Get("use_oidc").(bool) || data.Get("use_aks_workload_identity").(bool)
enableAzureCli = data.Bool("use_cli")
enableManagedIdentity = data.Bool("use_msi")
enableOidc = data.Bool("use_oidc") || data.Bool("use_aks_workload_identity")
)
authConfig := &auth.Credentials{
@ -340,16 +419,16 @@ func (b *Backend) configure(ctx context.Context) error {
TenantID: *tenantId,
ClientCertificateData: clientCertificateData,
ClientCertificatePath: data.Get("client_certificate_path").(string),
ClientCertificatePassword: data.Get("client_certificate_password").(string),
ClientCertificatePath: data.String("client_certificate_path"),
ClientCertificatePassword: data.String("client_certificate_password"),
ClientSecret: *clientSecret,
OIDCAssertionToken: *oidcToken,
OIDCTokenRequestURL: data.Get("oidc_request_url").(string),
OIDCTokenRequestToken: data.Get("oidc_request_token").(string),
ADOPipelineServiceConnectionID: data.Get("ado_pipeline_service_connection_id").(string),
OIDCTokenRequestURL: data.String("oidc_request_url"),
OIDCTokenRequestToken: data.String("oidc_request_token"),
ADOPipelineServiceConnectionID: data.String("ado_pipeline_service_connection_id"),
CustomManagedIdentityEndpoint: data.Get("msi_endpoint").(string),
CustomManagedIdentityEndpoint: data.String("msi_endpoint"),
EnableAuthenticatingUsingClientCertificate: true,
EnableAuthenticatingUsingClientSecret: true,
@ -362,28 +441,28 @@ func (b *Backend) configure(ctx context.Context) error {
backendConfig := BackendConfig{
AuthConfig: authConfig,
SubscriptionID: data.Get("subscription_id").(string),
ResourceGroupName: data.Get("resource_group_name").(string),
StorageAccountName: data.Get("storage_account_name").(string),
LookupBlobEndpoint: data.Get("lookup_blob_endpoint").(bool),
AccessKey: data.Get("access_key").(string),
SasToken: data.Get("sas_token").(string),
UseAzureADAuthentication: data.Get("use_azuread_auth").(bool),
SubscriptionID: data.String("subscription_id"),
ResourceGroupName: data.String("resource_group_name"),
StorageAccountName: data.String("storage_account_name"),
LookupBlobEndpoint: data.Bool("lookup_blob_endpoint"),
AccessKey: data.String("access_key"),
SasToken: data.String("sas_token"),
UseAzureADAuthentication: data.Bool("use_azuread_auth"),
}
needToLookupAccessKey := backendConfig.AccessKey == "" && backendConfig.SasToken == "" && !backendConfig.UseAzureADAuthentication
if backendConfig.ResourceGroupName == "" {
if needToLookupAccessKey {
return fmt.Errorf("One of `access_key`, `sas_token`, `use_azuread_auth` and `resource_group_name` must be specifieid")
backendbase.ErrorAsDiagnostics(fmt.Errorf("One of `access_key`, `sas_token`, `use_azuread_auth` and `resource_group_name` must be specifieid"))
}
if backendConfig.LookupBlobEndpoint {
return fmt.Errorf("`resource_group_name` is required when `lookup_blob_endpoint` is set")
backendbase.ErrorAsDiagnostics(fmt.Errorf("`resource_group_name` is required when `lookup_blob_endpoint` is set"))
}
}
client, err := buildClient(ctx, backendConfig)
if err != nil {
return err
return backendbase.ErrorAsDiagnostics(err)
}
b.apiClient = client

@ -8,8 +8,8 @@ require (
github.com/hashicorp/go-azure-sdk/sdk v0.20250131.1134653
github.com/hashicorp/go-uuid v1.0.3
github.com/hashicorp/terraform v0.0.0-00010101000000-000000000000
github.com/hashicorp/terraform/internal/legacy v0.0.0-00010101000000-000000000000
github.com/jackofallops/giovanni v0.28.0
github.com/zclconf/go-cty v1.16.2
)
require (
@ -55,7 +55,6 @@ require (
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
github.com/zclconf/go-cty v1.16.2 // indirect
github.com/zclconf/go-cty-yaml v1.1.0 // indirect
golang.org/x/crypto v0.39.0 // indirect
golang.org/x/mod v0.25.0 // indirect
@ -86,6 +85,4 @@ replace github.com/hashicorp/terraform/internal/backend/remote-state/pg => ../pg
replace github.com/hashicorp/terraform/internal/backend/remote-state/s3 => ../s3
replace github.com/hashicorp/terraform/internal/legacy => ../../../legacy
replace github.com/hashicorp/terraform => ../../../..

@ -12,7 +12,7 @@ import (
"os"
"strings"
"github.com/hashicorp/terraform/internal/legacy/helper/schema"
"github.com/hashicorp/terraform/internal/backend/backendbase"
)
// logEntry avoids log entries showing up in test output
@ -41,10 +41,10 @@ func decodeCertificate(clientCertificate string) ([]byte, error) {
return pfx, nil
}
func getOidcToken(d *schema.ResourceData) (*string, error) {
idToken := strings.TrimSpace(d.Get("oidc_token").(string))
func getOidcToken(d *backendbase.SDKLikeData) (*string, error) {
idToken := strings.TrimSpace(d.String("oidc_token"))
if path := d.Get("oidc_token_file_path").(string); path != "" {
if path := d.String("oidc_token_file_path"); path != "" {
fileTokenRaw, err := os.ReadFile(path)
if err != nil {
@ -60,7 +60,7 @@ func getOidcToken(d *schema.ResourceData) (*string, error) {
idToken = fileToken
}
if d.Get("use_aks_workload_identity").(bool) && os.Getenv("AZURE_FEDERATED_TOKEN_FILE") != "" {
if d.Bool("use_aks_workload_identity") && os.Getenv("AZURE_FEDERATED_TOKEN_FILE") != "" {
path := os.Getenv("AZURE_FEDERATED_TOKEN_FILE")
fileTokenRaw, err := os.ReadFile(os.Getenv("AZURE_FEDERATED_TOKEN_FILE"))
@ -80,10 +80,10 @@ func getOidcToken(d *schema.ResourceData) (*string, error) {
return &idToken, nil
}
func getClientId(d *schema.ResourceData) (*string, error) {
clientId := strings.TrimSpace(d.Get("client_id").(string))
func getClientId(d *backendbase.SDKLikeData) (*string, error) {
clientId := strings.TrimSpace(d.String("client_id"))
if path := d.Get("client_id_file_path").(string); path != "" {
if path := d.String("client_id_file_path"); path != "" {
fileClientIdRaw, err := os.ReadFile(path)
if err != nil {
@ -99,7 +99,7 @@ func getClientId(d *schema.ResourceData) (*string, error) {
clientId = fileClientId
}
if d.Get("use_aks_workload_identity").(bool) && os.Getenv("AZURE_CLIENT_ID") != "" {
if d.Bool("use_aks_workload_identity") && os.Getenv("AZURE_CLIENT_ID") != "" {
aksClientId := os.Getenv("AZURE_CLIENT_ID")
if clientId != "" && clientId != aksClientId {
return nil, fmt.Errorf("mismatch between supplied Client ID and that provided by AKS Workload Identity - please remove, ensure they match, or disable use_aks_workload_identity")
@ -110,10 +110,10 @@ func getClientId(d *schema.ResourceData) (*string, error) {
return &clientId, nil
}
func getClientSecret(d *schema.ResourceData) (*string, error) {
clientSecret := strings.TrimSpace(d.Get("client_secret").(string))
func getClientSecret(d *backendbase.SDKLikeData) (*string, error) {
clientSecret := strings.TrimSpace(d.String("client_secret"))
if path := d.Get("client_secret_file_path").(string); path != "" {
if path := d.String("client_secret_file_path"); path != "" {
fileSecretRaw, err := os.ReadFile(path)
if err != nil {
@ -132,10 +132,10 @@ func getClientSecret(d *schema.ResourceData) (*string, error) {
return &clientSecret, nil
}
func getTenantId(d *schema.ResourceData) (*string, error) {
tenantId := strings.TrimSpace(d.Get("tenant_id").(string))
func getTenantId(d *backendbase.SDKLikeData) (*string, error) {
tenantId := strings.TrimSpace(d.String("tenant_id"))
if d.Get("use_aks_workload_identity").(bool) && os.Getenv("AZURE_TENANT_ID") != "" {
if d.Bool("use_aks_workload_identity") && os.Getenv("AZURE_TENANT_ID") != "" {
aksTenantId := os.Getenv("AZURE_TENANT_ID")
if tenantId != "" && tenantId != aksTenantId {
return nil, fmt.Errorf("mismatch between supplied Tenant ID and that provided by AKS Workload Identity - please remove, ensure they match, or disable use_aks_workload_identity")

Loading…
Cancel
Save