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  }