diff --git a/internal/backend/remote-state/azure/backend.go b/internal/backend/remote-state/azure/backend.go index d82e172101ba..9672eea77553 100644 --- a/internal/backend/remote-state/azure/backend.go +++ b/internal/backend/remote-state/azure/backend.go @@ -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 diff --git a/internal/backend/remote-state/azure/go.mod b/internal/backend/remote-state/azure/go.mod index c1a3a2b6e4bf..aebe2814f5d4 100644 --- a/internal/backend/remote-state/azure/go.mod +++ b/internal/backend/remote-state/azure/go.mod @@ -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.38.0 // indirect golang.org/x/mod v0.24.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 => ../../../.. diff --git a/internal/backend/remote-state/azure/helpers.go b/internal/backend/remote-state/azure/helpers.go index 9ecce81c7e6c..f4e587234963 100644 --- a/internal/backend/remote-state/azure/helpers.go +++ b/internal/backend/remote-state/azure/helpers.go @@ -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")