github.com/hugorut/terraform@v1.1.3/src/backend/remote-state/azure/backend.go (about) 1 package azure 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/hugorut/terraform/src/backend" 8 "github.com/hugorut/terraform/src/legacy/helper/schema" 9 ) 10 11 // New creates a new backend for Azure remote state. 12 func New() backend.Backend { 13 s := &schema.Backend{ 14 Schema: map[string]*schema.Schema{ 15 "storage_account_name": { 16 Type: schema.TypeString, 17 Required: true, 18 Description: "The name of the storage account.", 19 }, 20 21 "container_name": { 22 Type: schema.TypeString, 23 Required: true, 24 Description: "The container name.", 25 }, 26 27 "key": { 28 Type: schema.TypeString, 29 Required: true, 30 Description: "The blob key.", 31 }, 32 33 "metadata_host": { 34 Type: schema.TypeString, 35 Required: true, 36 DefaultFunc: schema.EnvDefaultFunc("ARM_METADATA_HOST", ""), 37 Description: "The Metadata URL which will be used to obtain the Cloud Environment.", 38 }, 39 40 "environment": { 41 Type: schema.TypeString, 42 Optional: true, 43 Description: "The Azure cloud environment.", 44 DefaultFunc: schema.EnvDefaultFunc("ARM_ENVIRONMENT", "public"), 45 }, 46 47 "access_key": { 48 Type: schema.TypeString, 49 Optional: true, 50 Description: "The access key.", 51 DefaultFunc: schema.EnvDefaultFunc("ARM_ACCESS_KEY", ""), 52 }, 53 54 "sas_token": { 55 Type: schema.TypeString, 56 Optional: true, 57 Description: "A SAS Token used to interact with the Blob Storage Account.", 58 DefaultFunc: schema.EnvDefaultFunc("ARM_SAS_TOKEN", ""), 59 }, 60 61 "snapshot": { 62 Type: schema.TypeBool, 63 Optional: true, 64 Description: "Enable/Disable automatic blob snapshotting", 65 DefaultFunc: schema.EnvDefaultFunc("ARM_SNAPSHOT", false), 66 }, 67 68 "resource_group_name": { 69 Type: schema.TypeString, 70 Optional: true, 71 Description: "The resource group name.", 72 }, 73 74 "client_id": { 75 Type: schema.TypeString, 76 Optional: true, 77 Description: "The Client ID.", 78 DefaultFunc: schema.EnvDefaultFunc("ARM_CLIENT_ID", ""), 79 }, 80 81 "endpoint": { 82 Type: schema.TypeString, 83 Optional: true, 84 Description: "A custom Endpoint used to access the Azure Resource Manager API's.", 85 DefaultFunc: schema.EnvDefaultFunc("ARM_ENDPOINT", ""), 86 }, 87 88 "subscription_id": { 89 Type: schema.TypeString, 90 Optional: true, 91 Description: "The Subscription ID.", 92 DefaultFunc: schema.EnvDefaultFunc("ARM_SUBSCRIPTION_ID", ""), 93 }, 94 95 "tenant_id": { 96 Type: schema.TypeString, 97 Optional: true, 98 Description: "The Tenant ID.", 99 DefaultFunc: schema.EnvDefaultFunc("ARM_TENANT_ID", ""), 100 }, 101 102 // Service Principal (Client Certificate) specific 103 "client_certificate_password": { 104 Type: schema.TypeString, 105 Optional: true, 106 Description: "The password associated with the Client Certificate specified in `client_certificate_path`", 107 DefaultFunc: schema.EnvDefaultFunc("ARM_CLIENT_CERTIFICATE_PASSWORD", ""), 108 }, 109 "client_certificate_path": { 110 Type: schema.TypeString, 111 Optional: true, 112 Description: "The path to the PFX file used as the Client Certificate when authenticating as a Service Principal", 113 DefaultFunc: schema.EnvDefaultFunc("ARM_CLIENT_CERTIFICATE_PATH", ""), 114 }, 115 116 // Service Principal (Client Secret) specific 117 "client_secret": { 118 Type: schema.TypeString, 119 Optional: true, 120 Description: "The Client Secret.", 121 DefaultFunc: schema.EnvDefaultFunc("ARM_CLIENT_SECRET", ""), 122 }, 123 124 // Managed Service Identity specific 125 "use_msi": { 126 Type: schema.TypeBool, 127 Optional: true, 128 Description: "Should Managed Service Identity be used?", 129 DefaultFunc: schema.EnvDefaultFunc("ARM_USE_MSI", false), 130 }, 131 "msi_endpoint": { 132 Type: schema.TypeString, 133 Optional: true, 134 Description: "The Managed Service Identity Endpoint.", 135 DefaultFunc: schema.EnvDefaultFunc("ARM_MSI_ENDPOINT", ""), 136 }, 137 138 // Feature Flags 139 "use_azuread_auth": { 140 Type: schema.TypeBool, 141 Optional: true, 142 Description: "Should Terraform use AzureAD Authentication to access the Blob?", 143 DefaultFunc: schema.EnvDefaultFunc("ARM_USE_AZUREAD", false), 144 }, 145 "use_microsoft_graph": { 146 Type: schema.TypeBool, 147 Optional: true, 148 Description: "Should Terraform obtain an MSAL auth token and use Microsoft Graph rather than Azure Active Directory?", 149 DefaultFunc: schema.EnvDefaultFunc("ARM_USE_MSGRAPH", false), 150 }, 151 }, 152 } 153 154 result := &Backend{Backend: s} 155 result.Backend.ConfigureFunc = result.configure 156 return result 157 } 158 159 type Backend struct { 160 *schema.Backend 161 162 // The fields below are set from configure 163 armClient *ArmClient 164 containerName string 165 keyName string 166 accountName string 167 snapshot bool 168 } 169 170 type BackendConfig struct { 171 // Required 172 StorageAccountName string 173 174 // Optional 175 AccessKey string 176 ClientID string 177 ClientCertificatePassword string 178 ClientCertificatePath string 179 ClientSecret string 180 CustomResourceManagerEndpoint string 181 MetadataHost string 182 Environment string 183 MsiEndpoint string 184 ResourceGroupName string 185 SasToken string 186 SubscriptionID string 187 TenantID string 188 UseMsi bool 189 UseAzureADAuthentication bool 190 UseMicrosoftGraph bool 191 } 192 193 func (b *Backend) configure(ctx context.Context) error { 194 if b.containerName != "" { 195 return nil 196 } 197 198 // Grab the resource data 199 data := schema.FromContextBackendConfig(ctx) 200 b.containerName = data.Get("container_name").(string) 201 b.accountName = data.Get("storage_account_name").(string) 202 b.keyName = data.Get("key").(string) 203 b.snapshot = data.Get("snapshot").(bool) 204 205 config := BackendConfig{ 206 AccessKey: data.Get("access_key").(string), 207 ClientID: data.Get("client_id").(string), 208 ClientCertificatePassword: data.Get("client_certificate_password").(string), 209 ClientCertificatePath: data.Get("client_certificate_path").(string), 210 ClientSecret: data.Get("client_secret").(string), 211 CustomResourceManagerEndpoint: data.Get("endpoint").(string), 212 MetadataHost: data.Get("metadata_host").(string), 213 Environment: data.Get("environment").(string), 214 MsiEndpoint: data.Get("msi_endpoint").(string), 215 ResourceGroupName: data.Get("resource_group_name").(string), 216 SasToken: data.Get("sas_token").(string), 217 StorageAccountName: data.Get("storage_account_name").(string), 218 SubscriptionID: data.Get("subscription_id").(string), 219 TenantID: data.Get("tenant_id").(string), 220 UseMsi: data.Get("use_msi").(bool), 221 UseAzureADAuthentication: data.Get("use_azuread_auth").(bool), 222 UseMicrosoftGraph: data.Get("use_microsoft_graph").(bool), 223 } 224 225 armClient, err := buildArmClient(context.TODO(), config) 226 if err != nil { 227 return err 228 } 229 230 thingsNeededToLookupAccessKeySpecified := config.AccessKey == "" && config.SasToken == "" && config.ResourceGroupName == "" 231 if thingsNeededToLookupAccessKeySpecified && !config.UseAzureADAuthentication { 232 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") 233 } 234 235 b.armClient = armClient 236 return nil 237 }