github.com/opentofu/opentofu@v1.7.1/internal/backend/remote-state/azure/backend_test.go (about)

     1  // Copyright (c) The OpenTofu Authors
     2  // SPDX-License-Identifier: MPL-2.0
     3  // Copyright (c) 2023 HashiCorp, Inc.
     4  // SPDX-License-Identifier: MPL-2.0
     5  
     6  package azure
     7  
     8  import (
     9  	"context"
    10  	"os"
    11  	"testing"
    12  
    13  	"github.com/opentofu/opentofu/internal/backend"
    14  	"github.com/opentofu/opentofu/internal/encryption"
    15  	"github.com/opentofu/opentofu/internal/legacy/helper/acctest"
    16  )
    17  
    18  func TestBackend_impl(t *testing.T) {
    19  	var _ backend.Backend = new(Backend)
    20  }
    21  
    22  func TestBackendConfig(t *testing.T) {
    23  	// This test just instantiates the client. Shouldn't make any actual
    24  	// requests nor incur any costs.
    25  
    26  	config := map[string]interface{}{
    27  		"storage_account_name": "tfaccount",
    28  		"container_name":       "tfcontainer",
    29  		"key":                  "state",
    30  		"snapshot":             false,
    31  		// Access Key must be Base64
    32  		"access_key": "QUNDRVNTX0tFWQ0K",
    33  	}
    34  
    35  	b := backend.TestBackendConfig(t, New(encryption.StateEncryptionDisabled()), backend.TestWrapConfig(config)).(*Backend)
    36  
    37  	if b.containerName != "tfcontainer" {
    38  		t.Fatalf("Incorrect bucketName was populated")
    39  	}
    40  	if b.keyName != "state" {
    41  		t.Fatalf("Incorrect keyName was populated")
    42  	}
    43  	if b.snapshot != false {
    44  		t.Fatalf("Incorrect snapshot was populated")
    45  	}
    46  }
    47  
    48  func TestAccBackendAccessKeyBasic(t *testing.T) {
    49  	testAccAzureBackend(t)
    50  	rs := acctest.RandString(4)
    51  	res := testResourceNames(rs, "testState")
    52  	armClient := buildTestClient(t, res)
    53  
    54  	ctx := context.TODO()
    55  	err := armClient.buildTestResources(ctx, &res)
    56  	defer armClient.destroyTestResources(ctx, res)
    57  	if err != nil {
    58  		armClient.destroyTestResources(ctx, res)
    59  		t.Fatalf("Error creating Test Resources: %q", err)
    60  	}
    61  
    62  	b := backend.TestBackendConfig(t, New(encryption.StateEncryptionDisabled()), backend.TestWrapConfig(map[string]interface{}{
    63  		"storage_account_name": res.storageAccountName,
    64  		"container_name":       res.storageContainerName,
    65  		"key":                  res.storageKeyName,
    66  		"access_key":           res.storageAccountAccessKey,
    67  		"environment":          os.Getenv("ARM_ENVIRONMENT"),
    68  		"endpoint":             os.Getenv("ARM_ENDPOINT"),
    69  	})).(*Backend)
    70  
    71  	backend.TestBackendStates(t, b)
    72  }
    73  
    74  func TestAccBackendSASTokenBasic(t *testing.T) {
    75  	testAccAzureBackend(t)
    76  	rs := acctest.RandString(4)
    77  	res := testResourceNames(rs, "testState")
    78  	armClient := buildTestClient(t, res)
    79  
    80  	ctx := context.TODO()
    81  	err := armClient.buildTestResources(ctx, &res)
    82  	defer armClient.destroyTestResources(ctx, res)
    83  	if err != nil {
    84  		t.Fatalf("Error creating Test Resources: %q", err)
    85  	}
    86  
    87  	sasToken, err := buildSasToken(res.storageAccountName, res.storageAccountAccessKey)
    88  	if err != nil {
    89  		t.Fatalf("Error building SAS Token: %+v", err)
    90  	}
    91  
    92  	b := backend.TestBackendConfig(t, New(encryption.StateEncryptionDisabled()), backend.TestWrapConfig(map[string]interface{}{
    93  		"storage_account_name": res.storageAccountName,
    94  		"container_name":       res.storageContainerName,
    95  		"key":                  res.storageKeyName,
    96  		"sas_token":            *sasToken,
    97  		"environment":          os.Getenv("ARM_ENVIRONMENT"),
    98  		"endpoint":             os.Getenv("ARM_ENDPOINT"),
    99  	})).(*Backend)
   100  
   101  	backend.TestBackendStates(t, b)
   102  }
   103  
   104  func TestAccBackendOIDCBasic(t *testing.T) {
   105  	testAccAzureBackend(t)
   106  	rs := acctest.RandString(4)
   107  	res := testResourceNames(rs, "testState")
   108  	armClient := buildTestClient(t, res)
   109  
   110  	ctx := context.TODO()
   111  	err := armClient.buildTestResources(ctx, &res)
   112  	defer armClient.destroyTestResources(ctx, res)
   113  	if err != nil {
   114  		t.Fatalf("Error creating Test Resources: %q", err)
   115  	}
   116  
   117  	b := backend.TestBackendConfig(t, New(encryption.StateEncryptionDisabled()), backend.TestWrapConfig(map[string]interface{}{
   118  		"storage_account_name": res.storageAccountName,
   119  		"container_name":       res.storageContainerName,
   120  		"key":                  res.storageKeyName,
   121  		"resource_group_name":  res.resourceGroup,
   122  		"use_oidc":             true,
   123  		"subscription_id":      os.Getenv("ARM_SUBSCRIPTION_ID"),
   124  		"tenant_id":            os.Getenv("ARM_TENANT_ID"),
   125  		"environment":          os.Getenv("ARM_ENVIRONMENT"),
   126  		"endpoint":             os.Getenv("ARM_ENDPOINT"),
   127  	})).(*Backend)
   128  
   129  	backend.TestBackendStates(t, b)
   130  }
   131  
   132  func TestAccBackendManagedServiceIdentityBasic(t *testing.T) {
   133  	testAccAzureBackendRunningInAzure(t)
   134  	rs := acctest.RandString(4)
   135  	res := testResourceNames(rs, "testState")
   136  	armClient := buildTestClient(t, res)
   137  
   138  	ctx := context.TODO()
   139  	err := armClient.buildTestResources(ctx, &res)
   140  	defer armClient.destroyTestResources(ctx, res)
   141  	if err != nil {
   142  		t.Fatalf("Error creating Test Resources: %q", err)
   143  	}
   144  
   145  	b := backend.TestBackendConfig(t, New(encryption.StateEncryptionDisabled()), backend.TestWrapConfig(map[string]interface{}{
   146  		"storage_account_name": res.storageAccountName,
   147  		"container_name":       res.storageContainerName,
   148  		"key":                  res.storageKeyName,
   149  		"resource_group_name":  res.resourceGroup,
   150  		"use_msi":              true,
   151  		"subscription_id":      os.Getenv("ARM_SUBSCRIPTION_ID"),
   152  		"tenant_id":            os.Getenv("ARM_TENANT_ID"),
   153  		"environment":          os.Getenv("ARM_ENVIRONMENT"),
   154  		"endpoint":             os.Getenv("ARM_ENDPOINT"),
   155  	})).(*Backend)
   156  
   157  	backend.TestBackendStates(t, b)
   158  }
   159  
   160  func TestAccBackendServicePrincipalClientCertificateBasic(t *testing.T) {
   161  	testAccAzureBackend(t)
   162  
   163  	clientCertPassword := os.Getenv("ARM_CLIENT_CERTIFICATE_PASSWORD")
   164  	clientCertPath := os.Getenv("ARM_CLIENT_CERTIFICATE_PATH")
   165  	if clientCertPath == "" {
   166  		t.Skip("Skipping since `ARM_CLIENT_CERTIFICATE_PATH` is not specified!")
   167  	}
   168  
   169  	rs := acctest.RandString(4)
   170  	res := testResourceNames(rs, "testState")
   171  	armClient := buildTestClient(t, res)
   172  
   173  	ctx := context.TODO()
   174  	err := armClient.buildTestResources(ctx, &res)
   175  	defer armClient.destroyTestResources(ctx, res)
   176  	if err != nil {
   177  		t.Fatalf("Error creating Test Resources: %q", err)
   178  	}
   179  
   180  	b := backend.TestBackendConfig(t, New(encryption.StateEncryptionDisabled()), backend.TestWrapConfig(map[string]interface{}{
   181  		"storage_account_name":        res.storageAccountName,
   182  		"container_name":              res.storageContainerName,
   183  		"key":                         res.storageKeyName,
   184  		"resource_group_name":         res.resourceGroup,
   185  		"subscription_id":             os.Getenv("ARM_SUBSCRIPTION_ID"),
   186  		"tenant_id":                   os.Getenv("ARM_TENANT_ID"),
   187  		"client_id":                   os.Getenv("ARM_CLIENT_ID"),
   188  		"client_certificate_password": clientCertPassword,
   189  		"client_certificate_path":     clientCertPath,
   190  		"environment":                 os.Getenv("ARM_ENVIRONMENT"),
   191  		"endpoint":                    os.Getenv("ARM_ENDPOINT"),
   192  	})).(*Backend)
   193  
   194  	backend.TestBackendStates(t, b)
   195  }
   196  
   197  func TestAccBackendServicePrincipalClientSecretBasic(t *testing.T) {
   198  	testAccAzureBackend(t)
   199  	rs := acctest.RandString(4)
   200  	res := testResourceNames(rs, "testState")
   201  	armClient := buildTestClient(t, res)
   202  
   203  	ctx := context.TODO()
   204  	err := armClient.buildTestResources(ctx, &res)
   205  	defer armClient.destroyTestResources(ctx, res)
   206  	if err != nil {
   207  		t.Fatalf("Error creating Test Resources: %q", err)
   208  	}
   209  
   210  	b := backend.TestBackendConfig(t, New(encryption.StateEncryptionDisabled()), backend.TestWrapConfig(map[string]interface{}{
   211  		"storage_account_name": res.storageAccountName,
   212  		"container_name":       res.storageContainerName,
   213  		"key":                  res.storageKeyName,
   214  		"resource_group_name":  res.resourceGroup,
   215  		"subscription_id":      os.Getenv("ARM_SUBSCRIPTION_ID"),
   216  		"tenant_id":            os.Getenv("ARM_TENANT_ID"),
   217  		"client_id":            os.Getenv("ARM_CLIENT_ID"),
   218  		"client_secret":        os.Getenv("ARM_CLIENT_SECRET"),
   219  		"environment":          os.Getenv("ARM_ENVIRONMENT"),
   220  		"endpoint":             os.Getenv("ARM_ENDPOINT"),
   221  	})).(*Backend)
   222  
   223  	backend.TestBackendStates(t, b)
   224  }
   225  
   226  func TestAccBackendServicePrincipalClientSecretCustomEndpoint(t *testing.T) {
   227  	testAccAzureBackend(t)
   228  
   229  	// this is only applicable for Azure Stack.
   230  	endpoint := os.Getenv("ARM_ENDPOINT")
   231  	if endpoint == "" {
   232  		t.Skip("Skipping as ARM_ENDPOINT isn't configured")
   233  	}
   234  
   235  	rs := acctest.RandString(4)
   236  	res := testResourceNames(rs, "testState")
   237  	armClient := buildTestClient(t, res)
   238  
   239  	ctx := context.TODO()
   240  	err := armClient.buildTestResources(ctx, &res)
   241  	defer armClient.destroyTestResources(ctx, res)
   242  	if err != nil {
   243  		t.Fatalf("Error creating Test Resources: %q", err)
   244  	}
   245  
   246  	b := backend.TestBackendConfig(t, New(encryption.StateEncryptionDisabled()), backend.TestWrapConfig(map[string]interface{}{
   247  		"storage_account_name": res.storageAccountName,
   248  		"container_name":       res.storageContainerName,
   249  		"key":                  res.storageKeyName,
   250  		"resource_group_name":  res.resourceGroup,
   251  		"subscription_id":      os.Getenv("ARM_SUBSCRIPTION_ID"),
   252  		"tenant_id":            os.Getenv("ARM_TENANT_ID"),
   253  		"client_id":            os.Getenv("ARM_CLIENT_ID"),
   254  		"client_secret":        os.Getenv("ARM_CLIENT_SECRET"),
   255  		"environment":          os.Getenv("ARM_ENVIRONMENT"),
   256  		"endpoint":             endpoint,
   257  	})).(*Backend)
   258  
   259  	backend.TestBackendStates(t, b)
   260  }
   261  
   262  func TestAccBackendAccessKeyLocked(t *testing.T) {
   263  	testAccAzureBackend(t)
   264  	rs := acctest.RandString(4)
   265  	res := testResourceNames(rs, "testState")
   266  	armClient := buildTestClient(t, res)
   267  
   268  	ctx := context.TODO()
   269  	err := armClient.buildTestResources(ctx, &res)
   270  	defer armClient.destroyTestResources(ctx, res)
   271  	if err != nil {
   272  		t.Fatalf("Error creating Test Resources: %q", err)
   273  	}
   274  
   275  	b1 := backend.TestBackendConfig(t, New(encryption.StateEncryptionDisabled()), backend.TestWrapConfig(map[string]interface{}{
   276  		"storage_account_name": res.storageAccountName,
   277  		"container_name":       res.storageContainerName,
   278  		"key":                  res.storageKeyName,
   279  		"access_key":           res.storageAccountAccessKey,
   280  		"environment":          os.Getenv("ARM_ENVIRONMENT"),
   281  		"endpoint":             os.Getenv("ARM_ENDPOINT"),
   282  	})).(*Backend)
   283  
   284  	b2 := backend.TestBackendConfig(t, New(encryption.StateEncryptionDisabled()), backend.TestWrapConfig(map[string]interface{}{
   285  		"storage_account_name": res.storageAccountName,
   286  		"container_name":       res.storageContainerName,
   287  		"key":                  res.storageKeyName,
   288  		"access_key":           res.storageAccountAccessKey,
   289  		"environment":          os.Getenv("ARM_ENVIRONMENT"),
   290  		"endpoint":             os.Getenv("ARM_ENDPOINT"),
   291  	})).(*Backend)
   292  
   293  	backend.TestBackendStateLocks(t, b1, b2)
   294  	backend.TestBackendStateForceUnlock(t, b1, b2)
   295  
   296  	backend.TestBackendStateLocksInWS(t, b1, b2, "foo")
   297  	backend.TestBackendStateForceUnlockInWS(t, b1, b2, "foo")
   298  }
   299  
   300  func TestAccBackendServicePrincipalLocked(t *testing.T) {
   301  	testAccAzureBackend(t)
   302  	rs := acctest.RandString(4)
   303  	res := testResourceNames(rs, "testState")
   304  	armClient := buildTestClient(t, res)
   305  
   306  	ctx := context.TODO()
   307  	err := armClient.buildTestResources(ctx, &res)
   308  	defer armClient.destroyTestResources(ctx, res)
   309  	if err != nil {
   310  		t.Fatalf("Error creating Test Resources: %q", err)
   311  	}
   312  
   313  	b1 := backend.TestBackendConfig(t, New(encryption.StateEncryptionDisabled()), backend.TestWrapConfig(map[string]interface{}{
   314  		"storage_account_name": res.storageAccountName,
   315  		"container_name":       res.storageContainerName,
   316  		"key":                  res.storageKeyName,
   317  		"access_key":           res.storageAccountAccessKey,
   318  		"subscription_id":      os.Getenv("ARM_SUBSCRIPTION_ID"),
   319  		"tenant_id":            os.Getenv("ARM_TENANT_ID"),
   320  		"client_id":            os.Getenv("ARM_CLIENT_ID"),
   321  		"client_secret":        os.Getenv("ARM_CLIENT_SECRET"),
   322  		"environment":          os.Getenv("ARM_ENVIRONMENT"),
   323  		"endpoint":             os.Getenv("ARM_ENDPOINT"),
   324  	})).(*Backend)
   325  
   326  	b2 := backend.TestBackendConfig(t, New(encryption.StateEncryptionDisabled()), backend.TestWrapConfig(map[string]interface{}{
   327  		"storage_account_name": res.storageAccountName,
   328  		"container_name":       res.storageContainerName,
   329  		"key":                  res.storageKeyName,
   330  		"access_key":           res.storageAccountAccessKey,
   331  		"subscription_id":      os.Getenv("ARM_SUBSCRIPTION_ID"),
   332  		"tenant_id":            os.Getenv("ARM_TENANT_ID"),
   333  		"client_id":            os.Getenv("ARM_CLIENT_ID"),
   334  		"client_secret":        os.Getenv("ARM_CLIENT_SECRET"),
   335  		"environment":          os.Getenv("ARM_ENVIRONMENT"),
   336  		"endpoint":             os.Getenv("ARM_ENDPOINT"),
   337  	})).(*Backend)
   338  
   339  	backend.TestBackendStateLocks(t, b1, b2)
   340  	backend.TestBackendStateForceUnlock(t, b1, b2)
   341  
   342  	backend.TestBackendStateLocksInWS(t, b1, b2, "foo")
   343  	backend.TestBackendStateForceUnlockInWS(t, b1, b2, "foo")
   344  }