2017-03-30 16:33:54 +02:00
package azure
import (
"context"
"fmt"
2021-05-17 17:42:17 +02:00
"github.com/hashicorp/terraform/internal/backend"
2020-11-18 16:07:30 +01:00
"github.com/hashicorp/terraform/internal/legacy/helper/schema"
2017-03-30 16:33:54 +02:00
)
2018-11-21 22:06:03 +01:00
// New creates a new backend for Azure remote state.
2017-03-30 16:33:54 +02:00
func New ( ) backend . Backend {
s := & schema . Backend {
Schema : map [ string ] * schema . Schema {
2017-09-04 13:04:11 +02:00
"storage_account_name" : {
2017-03-30 16:33:54 +02:00
Type : schema . TypeString ,
Required : true ,
Description : "The name of the storage account." ,
} ,
2017-09-04 13:04:11 +02:00
"container_name" : {
2017-03-30 16:33:54 +02:00
Type : schema . TypeString ,
Required : true ,
Description : "The container name." ,
} ,
2017-09-04 13:04:11 +02:00
"key" : {
2017-03-30 16:33:54 +02:00
Type : schema . TypeString ,
Required : true ,
Description : "The blob key." ,
} ,
2020-08-13 00:04:40 +02:00
"metadata_host" : {
Type : schema . TypeString ,
Required : true ,
DefaultFunc : schema . EnvDefaultFunc ( "ARM_METADATA_HOST" , "" ) ,
Description : "The Metadata URL which will be used to obtain the Cloud Environment." ,
} ,
2017-09-04 13:04:11 +02:00
"environment" : {
2017-03-30 16:33:54 +02:00
Type : schema . TypeString ,
Optional : true ,
Description : "The Azure cloud environment." ,
2018-11-21 22:06:03 +01:00
DefaultFunc : schema . EnvDefaultFunc ( "ARM_ENVIRONMENT" , "public" ) ,
2017-03-30 16:33:54 +02:00
} ,
2017-09-04 13:04:11 +02:00
"access_key" : {
2017-03-30 16:33:54 +02:00
Type : schema . TypeString ,
Optional : true ,
Description : "The access key." ,
DefaultFunc : schema . EnvDefaultFunc ( "ARM_ACCESS_KEY" , "" ) ,
} ,
2018-11-22 18:02:33 +01:00
"sas_token" : {
Type : schema . TypeString ,
Optional : true ,
Description : "A SAS Token used to interact with the Blob Storage Account." ,
DefaultFunc : schema . EnvDefaultFunc ( "ARM_SAS_TOKEN" , "" ) ,
} ,
2020-06-25 11:50:16 +02:00
"snapshot" : {
Type : schema . TypeBool ,
Optional : true ,
Description : "Enable/Disable automatic blob snapshotting" ,
DefaultFunc : schema . EnvDefaultFunc ( "ARM_SNAPSHOT" , false ) ,
} ,
2017-09-04 13:04:11 +02:00
"resource_group_name" : {
2017-03-30 16:33:54 +02:00
Type : schema . TypeString ,
Optional : true ,
Description : "The resource group name." ,
} ,
2018-11-26 11:19:43 +01:00
"client_id" : {
2017-03-30 16:33:54 +02:00
Type : schema . TypeString ,
Optional : true ,
Description : "The Client ID." ,
DefaultFunc : schema . EnvDefaultFunc ( "ARM_CLIENT_ID" , "" ) ,
} ,
2020-08-07 11:58:33 +02:00
"endpoint" : {
2017-03-30 16:33:54 +02:00
Type : schema . TypeString ,
Optional : true ,
2020-08-07 11:58:33 +02:00
Description : "A custom Endpoint used to access the Azure Resource Manager API's." ,
DefaultFunc : schema . EnvDefaultFunc ( "ARM_ENDPOINT" , "" ) ,
2017-03-30 16:33:54 +02:00
} ,
2018-11-26 11:19:43 +01:00
"subscription_id" : {
Type : schema . TypeString ,
Optional : true ,
Description : "The Subscription ID." ,
DefaultFunc : schema . EnvDefaultFunc ( "ARM_SUBSCRIPTION_ID" , "" ) ,
} ,
"tenant_id" : {
2017-03-30 16:33:54 +02:00
Type : schema . TypeString ,
Optional : true ,
Description : "The Tenant ID." ,
DefaultFunc : schema . EnvDefaultFunc ( "ARM_TENANT_ID" , "" ) ,
} ,
2018-11-21 22:06:03 +01:00
2020-08-07 11:58:33 +02:00
// Service Principal (Client Certificate) specific
"client_certificate_password" : {
Type : schema . TypeString ,
Optional : true ,
Description : "The password associated with the Client Certificate specified in `client_certificate_path`" ,
DefaultFunc : schema . EnvDefaultFunc ( "ARM_CLIENT_CERTIFICATE_PASSWORD" , "" ) ,
} ,
"client_certificate_path" : {
Type : schema . TypeString ,
Optional : true ,
Description : "The path to the PFX file used as the Client Certificate when authenticating as a Service Principal" ,
DefaultFunc : schema . EnvDefaultFunc ( "ARM_CLIENT_CERTIFICATE_PATH" , "" ) ,
} ,
// Service Principal (Client Secret) specific
"client_secret" : {
Type : schema . TypeString ,
Optional : true ,
Description : "The Client Secret." ,
DefaultFunc : schema . EnvDefaultFunc ( "ARM_CLIENT_SECRET" , "" ) ,
} ,
// Managed Service Identity specific
2018-11-22 16:52:27 +01:00
"use_msi" : {
Type : schema . TypeBool ,
Optional : true ,
2021-03-22 17:33:57 +01:00
Description : "Should Managed Service Identity be used?" ,
2018-11-22 16:52:27 +01:00
DefaultFunc : schema . EnvDefaultFunc ( "ARM_USE_MSI" , false ) ,
} ,
"msi_endpoint" : {
Type : schema . TypeString ,
Optional : true ,
Description : "The Managed Service Identity Endpoint." ,
DefaultFunc : schema . EnvDefaultFunc ( "ARM_MSI_ENDPOINT" , "" ) ,
} ,
2021-03-22 17:33:57 +01:00
// Feature Flags
"use_azuread_auth" : {
Type : schema . TypeBool ,
Optional : true ,
Description : "Should Terraform use AzureAD Authentication to access the Blob?" ,
DefaultFunc : schema . EnvDefaultFunc ( "ARM_USE_AZUREAD" , false ) ,
} ,
2021-11-17 18:40:21 +01:00
"use_microsoft_graph" : {
Type : schema . TypeBool ,
Optional : true ,
2021-11-17 20:24:22 +01:00
Description : "Should Terraform obtain an MSAL auth token and use Microsoft Graph rather than Azure Active Directory?" ,
2021-11-17 18:40:21 +01:00
DefaultFunc : schema . EnvDefaultFunc ( "ARM_USE_MSGRAPH" , false ) ,
} ,
2017-03-30 16:33:54 +02:00
} ,
}
result := & Backend { Backend : s }
result . Backend . ConfigureFunc = result . configure
return result
}
type Backend struct {
* schema . Backend
// The fields below are set from configure
2018-11-21 22:06:03 +01:00
armClient * ArmClient
2017-03-30 16:33:54 +02:00
containerName string
keyName string
2020-05-20 17:29:02 +02:00
accountName string
2020-06-25 11:50:16 +02:00
snapshot bool
2017-03-30 16:33:54 +02:00
}
2017-09-04 13:04:43 +02:00
type BackendConfig struct {
2018-11-21 22:06:03 +01:00
// Required
2017-09-04 13:04:43 +02:00
StorageAccountName string
2018-11-21 22:06:03 +01:00
// Optional
2018-11-26 14:42:16 +01:00
AccessKey string
ClientID string
2020-08-07 11:58:33 +02:00
ClientCertificatePassword string
ClientCertificatePath string
2018-11-26 14:42:16 +01:00
ClientSecret string
CustomResourceManagerEndpoint string
2020-08-13 00:04:40 +02:00
MetadataHost string
2018-11-26 14:42:16 +01:00
Environment string
MsiEndpoint string
ResourceGroupName string
SasToken string
SubscriptionID string
TenantID string
UseMsi bool
2021-03-22 17:33:57 +01:00
UseAzureADAuthentication bool
2021-11-17 18:40:21 +01:00
UseMicrosoftGraph bool
2017-09-04 13:04:43 +02:00
}
2017-03-30 16:33:54 +02:00
func ( b * Backend ) configure ( ctx context . Context ) error {
if b . containerName != "" {
return nil
}
// Grab the resource data
data := schema . FromContextBackendConfig ( ctx )
b . containerName = data . Get ( "container_name" ) . ( string )
2020-05-20 17:29:02 +02:00
b . accountName = data . Get ( "storage_account_name" ) . ( string )
2017-03-30 16:33:54 +02:00
b . keyName = data . Get ( "key" ) . ( string )
2020-06-25 11:50:16 +02:00
b . snapshot = data . Get ( "snapshot" ) . ( bool )
2017-03-30 16:33:54 +02:00
2017-09-04 13:04:43 +02:00
config := BackendConfig {
2018-11-26 14:42:16 +01:00
AccessKey : data . Get ( "access_key" ) . ( string ) ,
2021-03-22 17:26:06 +01:00
ClientID : data . Get ( "client_id" ) . ( string ) ,
2020-08-07 11:58:33 +02:00
ClientCertificatePassword : data . Get ( "client_certificate_password" ) . ( string ) ,
ClientCertificatePath : data . Get ( "client_certificate_path" ) . ( string ) ,
2021-03-22 17:26:06 +01:00
ClientSecret : data . Get ( "client_secret" ) . ( string ) ,
2018-11-26 14:42:16 +01:00
CustomResourceManagerEndpoint : data . Get ( "endpoint" ) . ( string ) ,
2020-08-13 00:04:40 +02:00
MetadataHost : data . Get ( "metadata_host" ) . ( string ) ,
2018-11-26 14:42:16 +01:00
Environment : data . Get ( "environment" ) . ( string ) ,
MsiEndpoint : data . Get ( "msi_endpoint" ) . ( string ) ,
ResourceGroupName : data . Get ( "resource_group_name" ) . ( string ) ,
SasToken : data . Get ( "sas_token" ) . ( string ) ,
StorageAccountName : data . Get ( "storage_account_name" ) . ( string ) ,
2021-03-22 17:26:06 +01:00
SubscriptionID : data . Get ( "subscription_id" ) . ( string ) ,
TenantID : data . Get ( "tenant_id" ) . ( string ) ,
2018-11-26 14:42:16 +01:00
UseMsi : data . Get ( "use_msi" ) . ( bool ) ,
2021-03-22 17:33:57 +01:00
UseAzureADAuthentication : data . Get ( "use_azuread_auth" ) . ( bool ) ,
2021-11-17 18:40:21 +01:00
UseMicrosoftGraph : data . Get ( "use_microsoft_graph" ) . ( bool ) ,
2017-09-04 13:04:43 +02:00
}
2020-10-05 20:43:46 +02:00
armClient , err := buildArmClient ( context . TODO ( ) , config )
2017-03-30 16:33:54 +02:00
if err != nil {
return err
}
2021-03-22 17:33:57 +01:00
thingsNeededToLookupAccessKeySpecified := config . AccessKey == "" && config . SasToken == "" && config . ResourceGroupName == ""
if thingsNeededToLookupAccessKeySpecified && ! config . UseAzureADAuthentication {
return fmt . Errorf ( "Either an Access Key / SAS Token or the Resource Group for the Storage Account must be specified - or Azure AD Authentication must be enabled" )
2017-03-30 16:33:54 +02:00
}
2018-11-21 22:06:03 +01:00
b . armClient = armClient
return nil
2017-03-30 16:33:54 +02:00
}