github.com/pgray/terraform@v0.5.4-0.20170822184730-b6a464c5214d/backend/remote-state/azure/backend_test.go (about) 1 package azure 2 3 import ( 4 "fmt" 5 "os" 6 "testing" 7 8 "github.com/Azure/azure-sdk-for-go/arm/resources/resources" 9 armStorage "github.com/Azure/azure-sdk-for-go/arm/storage" 10 "github.com/Azure/azure-sdk-for-go/storage" 11 "github.com/Azure/go-autorest/autorest" 12 "github.com/Azure/go-autorest/autorest/adal" 13 "github.com/Azure/go-autorest/autorest/azure" 14 "github.com/hashicorp/terraform/backend" 15 "github.com/hashicorp/terraform/helper/acctest" 16 ) 17 18 // verify that we are doing ACC tests or the Azure tests specifically 19 func testACC(t *testing.T) { 20 skip := os.Getenv("TF_ACC") == "" && os.Getenv("TF_AZURE_TEST") == "" 21 if skip { 22 t.Log("azure backend tests require setting TF_ACC or TF_AZURE_TEST") 23 t.Skip() 24 } 25 } 26 27 func TestBackend_impl(t *testing.T) { 28 var _ backend.Backend = new(Backend) 29 } 30 31 func TestBackendConfig(t *testing.T) { 32 // This test just instantiates the client. Shouldn't make any actual 33 // requests nor incur any costs. 34 35 config := map[string]interface{}{ 36 "storage_account_name": "tfaccount", 37 "container_name": "tfcontainer", 38 "key": "state", 39 // Access Key must be Base64 40 "access_key": "QUNDRVNTX0tFWQ0K", 41 } 42 43 b := backend.TestBackendConfig(t, New(), config).(*Backend) 44 45 if b.containerName != "tfcontainer" { 46 t.Fatalf("Incorrect bucketName was populated") 47 } 48 if b.keyName != "state" { 49 t.Fatalf("Incorrect keyName was populated") 50 } 51 } 52 53 func TestBackend(t *testing.T) { 54 testACC(t) 55 56 keyName := "testState" 57 res := setupResources(t, keyName) 58 defer destroyResources(t, res.resourceGroupName) 59 60 b := backend.TestBackendConfig(t, New(), map[string]interface{}{ 61 "storage_account_name": res.storageAccountName, 62 "container_name": res.containerName, 63 "key": keyName, 64 "access_key": res.accessKey, 65 }).(*Backend) 66 67 backend.TestBackend(t, b, nil) 68 } 69 70 func TestBackendLocked(t *testing.T) { 71 testACC(t) 72 73 keyName := "testState" 74 res := setupResources(t, keyName) 75 defer destroyResources(t, res.resourceGroupName) 76 77 b1 := backend.TestBackendConfig(t, New(), map[string]interface{}{ 78 "storage_account_name": res.storageAccountName, 79 "container_name": res.containerName, 80 "key": keyName, 81 "access_key": res.accessKey, 82 }).(*Backend) 83 84 b2 := backend.TestBackendConfig(t, New(), map[string]interface{}{ 85 "storage_account_name": res.storageAccountName, 86 "container_name": res.containerName, 87 "key": keyName, 88 "access_key": res.accessKey, 89 }).(*Backend) 90 91 backend.TestBackend(t, b1, b2) 92 } 93 94 type testResources struct { 95 resourceGroupName string 96 storageAccountName string 97 containerName string 98 keyName string 99 accessKey string 100 } 101 102 func setupResources(t *testing.T, keyName string) testResources { 103 clients := getTestClient(t) 104 105 ri := acctest.RandInt() 106 rs := acctest.RandString(4) 107 res := testResources{ 108 resourceGroupName: fmt.Sprintf("terraform-backend-testing-%d", ri), 109 storageAccountName: fmt.Sprintf("tfbackendtesting%s", rs), 110 containerName: "terraform", 111 keyName: keyName, 112 } 113 114 location := os.Getenv("ARM_LOCATION") 115 if location == "" { 116 location = "westus" 117 } 118 119 t.Logf("creating resource group %s", res.resourceGroupName) 120 _, err := clients.groupsClient.CreateOrUpdate(res.resourceGroupName, resources.Group{Location: &location}) 121 if err != nil { 122 t.Fatalf("failed to create test resource group: %s", err) 123 } 124 125 t.Logf("creating storage account %s", res.storageAccountName) 126 _, createError := clients.storageAccountsClient.Create(res.resourceGroupName, res.storageAccountName, armStorage.AccountCreateParameters{ 127 Sku: &armStorage.Sku{ 128 Name: armStorage.StandardLRS, 129 Tier: armStorage.Standard, 130 }, 131 Location: &location, 132 }, make(chan struct{})) 133 createErr := <-createError 134 if createErr != nil { 135 destroyResources(t, res.resourceGroupName) 136 t.Fatalf("failed to create test storage account: %s", err) 137 } 138 139 t.Log("fetching access key for storage account") 140 resp, err := clients.storageAccountsClient.ListKeys(res.resourceGroupName, res.storageAccountName) 141 if err != nil { 142 destroyResources(t, res.resourceGroupName) 143 t.Fatalf("failed to list storage account keys %s:", err) 144 } 145 146 keys := *resp.Keys 147 res.accessKey = *keys[0].Value 148 149 storageClient, err := storage.NewClient(res.storageAccountName, res.accessKey, 150 clients.environment.StorageEndpointSuffix, storage.DefaultAPIVersion, true) 151 if err != nil { 152 destroyResources(t, res.resourceGroupName) 153 t.Fatalf("failed to list storage account keys %s:", err) 154 } 155 156 t.Logf("creating container %s", res.containerName) 157 blobService := storageClient.GetBlobService() 158 container := blobService.GetContainerReference(res.containerName) 159 err = container.Create(&storage.CreateContainerOptions{}) 160 if err != nil { 161 destroyResources(t, res.resourceGroupName) 162 t.Fatalf("failed to create storage container: %s", err) 163 } 164 165 return res 166 } 167 168 func destroyResources(t *testing.T, resourceGroupName string) { 169 warning := "WARNING: Failed to delete the test Azure resources. They may incur charges. (error was %s)" 170 171 clients := getTestClient(t) 172 173 t.Log("destroying created resources") 174 175 // destroying is simple as deleting the resource group will destroy everything else 176 _, deleteErr := clients.groupsClient.Delete(resourceGroupName, make(chan struct{})) 177 err := <-deleteErr 178 if err != nil { 179 t.Logf(warning, err) 180 return 181 } 182 183 t.Log("Azure resources destroyed") 184 } 185 186 type testClient struct { 187 subscriptionID string 188 tenantID string 189 clientID string 190 clientSecret string 191 environment azure.Environment 192 groupsClient resources.GroupsClient 193 storageAccountsClient armStorage.AccountsClient 194 } 195 196 func getTestClient(t *testing.T) testClient { 197 client := testClient{ 198 subscriptionID: os.Getenv("ARM_SUBSCRIPTION_ID"), 199 tenantID: os.Getenv("ARM_TENANT_ID"), 200 clientID: os.Getenv("ARM_CLIENT_ID"), 201 clientSecret: os.Getenv("ARM_CLIENT_SECRET"), 202 } 203 204 if client.subscriptionID == "" || client.tenantID == "" || client.clientID == "" || client.clientSecret == "" { 205 t.Fatal("Azure credentials missing or incomplete") 206 } 207 208 env, err := getAzureEnvironment(os.Getenv("ARM_ENVIRONMENT")) 209 if err != nil { 210 t.Fatalf("Failed to detect Azure environment from ARM_ENVIRONMENT value: %s", os.Getenv("ARM_ENVIRONMENT")) 211 } 212 client.environment = env 213 214 oauthConfig, err := adal.NewOAuthConfig(env.ActiveDirectoryEndpoint, client.tenantID) 215 if err != nil { 216 t.Fatalf("Failed to get OAuth config: %s", err) 217 } 218 219 spt, err := adal.NewServicePrincipalToken(*oauthConfig, client.clientID, client.clientSecret, env.ResourceManagerEndpoint) 220 if err != nil { 221 t.Fatalf("Failed to create Service Principal Token: %s", err) 222 } 223 224 client.groupsClient = resources.NewGroupsClientWithBaseURI(env.ResourceManagerEndpoint, client.subscriptionID) 225 client.groupsClient.Authorizer = autorest.NewBearerAuthorizer(spt) 226 227 client.storageAccountsClient = armStorage.NewAccountsClientWithBaseURI(env.ResourceManagerEndpoint, client.subscriptionID) 228 client.storageAccountsClient.Authorizer = autorest.NewBearerAuthorizer(spt) 229 230 return client 231 }