github.com/graywolf-at-work-2/terraform-vendor@v1.4.5/internal/backend/remote-state/azure/backend.go (about) 1 package azure 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/hashicorp/terraform/internal/backend" 8 "github.com/hashicorp/terraform/internal/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 // OIDC auth specific fields 139 "use_oidc": { 140 Type: schema.TypeBool, 141 Optional: true, 142 DefaultFunc: schema.EnvDefaultFunc("ARM_USE_OIDC", false), 143 Description: "Allow OIDC to be used for authentication", 144 }, 145 "oidc_token": { 146 Type: schema.TypeString, 147 Optional: true, 148 DefaultFunc: schema.EnvDefaultFunc("ARM_OIDC_TOKEN", ""), 149 Description: "A generic JWT token that can be used for OIDC authentication. Should not be used in conjunction with `oidc_request_token`.", 150 }, 151 "oidc_token_file_path": { 152 Type: schema.TypeString, 153 Optional: true, 154 DefaultFunc: schema.EnvDefaultFunc("ARM_OIDC_TOKEN_FILE_PATH", ""), 155 Description: "Path to file containing a generic JWT token that can be used for OIDC authentication. Should not be used in conjunction with `oidc_request_token`.", 156 }, 157 "oidc_request_url": { 158 Type: schema.TypeString, 159 Optional: true, 160 DefaultFunc: schema.MultiEnvDefaultFunc([]string{"ARM_OIDC_REQUEST_URL", "ACTIONS_ID_TOKEN_REQUEST_URL"}, ""), 161 Description: "The URL of the OIDC provider from which to request an ID token. Needs to be used in conjunction with `oidc_request_token`. This is meant to be used for Github Actions.", 162 }, 163 "oidc_request_token": { 164 Type: schema.TypeString, 165 Optional: true, 166 DefaultFunc: schema.MultiEnvDefaultFunc([]string{"ARM_OIDC_REQUEST_TOKEN", "ACTIONS_ID_TOKEN_REQUEST_TOKEN"}, ""), 167 Description: "The bearer token to use for the request to the OIDC providers `oidc_request_url` URL to fetch an ID token. Needs to be used in conjunction with `oidc_request_url`. This is meant to be used for Github Actions.", 168 }, 169 170 // Feature Flags 171 "use_azuread_auth": { 172 Type: schema.TypeBool, 173 Optional: true, 174 Description: "Should Terraform use AzureAD Authentication to access the Blob?", 175 DefaultFunc: schema.EnvDefaultFunc("ARM_USE_AZUREAD", false), 176 }, 177 }, 178 } 179 180 result := &Backend{Backend: s} 181 result.Backend.ConfigureFunc = result.configure 182 return result 183 } 184 185 type Backend struct { 186 *schema.Backend 187 188 // The fields below are set from configure 189 armClient *ArmClient 190 containerName string 191 keyName string 192 accountName string 193 snapshot bool 194 } 195 196 type BackendConfig struct { 197 // Required 198 StorageAccountName string 199 200 // Optional 201 AccessKey string 202 ClientID string 203 ClientCertificatePassword string 204 ClientCertificatePath string 205 ClientSecret string 206 CustomResourceManagerEndpoint string 207 MetadataHost string 208 Environment string 209 MsiEndpoint string 210 OIDCToken string 211 OIDCTokenFilePath string 212 OIDCRequestURL string 213 OIDCRequestToken string 214 ResourceGroupName string 215 SasToken string 216 SubscriptionID string 217 TenantID string 218 UseMsi bool 219 UseOIDC bool 220 UseAzureADAuthentication bool 221 } 222 223 func (b *Backend) configure(ctx context.Context) error { 224 if b.containerName != "" { 225 return nil 226 } 227 228 // Grab the resource data 229 data := schema.FromContextBackendConfig(ctx) 230 b.containerName = data.Get("container_name").(string) 231 b.accountName = data.Get("storage_account_name").(string) 232 b.keyName = data.Get("key").(string) 233 b.snapshot = data.Get("snapshot").(bool) 234 235 config := BackendConfig{ 236 AccessKey: data.Get("access_key").(string), 237 ClientID: data.Get("client_id").(string), 238 ClientCertificatePassword: data.Get("client_certificate_password").(string), 239 ClientCertificatePath: data.Get("client_certificate_path").(string), 240 ClientSecret: data.Get("client_secret").(string), 241 CustomResourceManagerEndpoint: data.Get("endpoint").(string), 242 MetadataHost: data.Get("metadata_host").(string), 243 Environment: data.Get("environment").(string), 244 MsiEndpoint: data.Get("msi_endpoint").(string), 245 OIDCToken: data.Get("oidc_token").(string), 246 OIDCTokenFilePath: data.Get("oidc_token_file_path").(string), 247 OIDCRequestURL: data.Get("oidc_request_url").(string), 248 OIDCRequestToken: data.Get("oidc_request_token").(string), 249 ResourceGroupName: data.Get("resource_group_name").(string), 250 SasToken: data.Get("sas_token").(string), 251 StorageAccountName: data.Get("storage_account_name").(string), 252 SubscriptionID: data.Get("subscription_id").(string), 253 TenantID: data.Get("tenant_id").(string), 254 UseMsi: data.Get("use_msi").(bool), 255 UseOIDC: data.Get("use_oidc").(bool), 256 UseAzureADAuthentication: data.Get("use_azuread_auth").(bool), 257 } 258 259 armClient, err := buildArmClient(context.TODO(), config) 260 if err != nil { 261 return err 262 } 263 264 thingsNeededToLookupAccessKeySpecified := config.AccessKey == "" && config.SasToken == "" && config.ResourceGroupName == "" 265 if thingsNeededToLookupAccessKeySpecified && !config.UseAzureADAuthentication { 266 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") 267 } 268 269 b.armClient = armClient 270 return nil 271 }