github.com/darmach/terratest@v0.34.8-0.20210517103231-80931f95e3ff/test/azure/terraform_azure_vm_example_test.go (about) 1 // +build azure azureslim,compute 2 3 // NOTE: We use build tags to differentiate azure testing because we currently do not have azure access setup for 4 // CircleCI. 5 6 package test 7 8 import ( 9 "fmt" 10 "strings" 11 "testing" 12 13 "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-07-01/compute" 14 "github.com/gruntwork-io/terratest/modules/azure" 15 "github.com/gruntwork-io/terratest/modules/random" 16 "github.com/gruntwork-io/terratest/modules/terraform" 17 "github.com/stretchr/testify/assert" 18 ) 19 20 func TestTerraformAzureVmExample(t *testing.T) { 21 t.Parallel() 22 23 subscriptionID := "" 24 uniquePostfix := random.UniqueId() 25 26 // Configure Terraform setting up a path to Terraform code. 27 terraformOptions := &terraform.Options{ 28 // The path to where our Terraform code is located. 29 TerraformDir: "../../examples/azure/terraform-azure-vm-example", 30 31 // Variables to pass to our Terraform code using -var options. 32 Vars: map[string]interface{}{ 33 "postfix": uniquePostfix, 34 }, 35 } 36 37 // At the end of the test, run `terraform destroy` to clean up any resources that were created. 38 defer terraform.Destroy(t, terraformOptions) 39 40 // Run `terraform init` and `terraform apply`. Fail the test if there are any errors. 41 terraform.InitAndApply(t, terraformOptions) 42 43 // Run tests for the Virtual Machine. 44 testStrategiesForVMs(t, terraformOptions, subscriptionID) 45 testMultipleVMs(t, terraformOptions, subscriptionID) 46 testInformationOfVM(t, terraformOptions, subscriptionID) 47 testDisksOfVM(t, terraformOptions, subscriptionID) 48 testNetworkOfVM(t, terraformOptions, subscriptionID) 49 } 50 51 // These 3 tests check for the same property but illustrate different testing strategies for 52 // retriving the data. The first strategy is used in the other tests of this module while 53 // the other two can be extended by the user as needed. 54 func testStrategiesForVMs(t *testing.T, terraformOptions *terraform.Options, subscriptionID string) { 55 // Run `terraform output` to get the values of output variables. 56 resourceGroupName := terraform.Output(t, terraformOptions, "resource_group_name") 57 virtualMachineName := terraform.Output(t, terraformOptions, "vm_name") 58 expectedVMSize := compute.VirtualMachineSizeTypes(terraform.Output(t, terraformOptions, "vm_size")) 59 60 // 1. Check the VM Size directly. This strategy gets one specific property of the VM per method. 61 actualVMSize := azure.GetSizeOfVirtualMachine(t, virtualMachineName, resourceGroupName, subscriptionID) 62 assert.Equal(t, expectedVMSize, actualVMSize) 63 64 // 2. Check the VM size by reference. This strategy is beneficial when checking multiple properties 65 // by using one VM reference. Optional parameters have to be checked first to avoid nil panics. 66 vmByRef := azure.GetVirtualMachine(t, virtualMachineName, resourceGroupName, subscriptionID) 67 actualVMSize = vmByRef.HardwareProfile.VMSize 68 assert.Equal(t, expectedVMSize, actualVMSize) 69 70 // 3. Check the VM size by instance. This strategy is beneficial when checking multiple properties 71 // by using one VM instance and making calls against it with the added benefit of property check abstraction. 72 vmInstance := azure.Instance{VirtualMachine: vmByRef} 73 actualVMSize = vmInstance.GetVirtualMachineInstanceSize() 74 assert.Equal(t, expectedVMSize, actualVMSize) 75 } 76 77 // These tests check for the multiple Virtual Machines in a Resource Group. 78 func testMultipleVMs(t *testing.T, terraformOptions *terraform.Options, subscriptionID string) { 79 // Run `terraform output` to get the values of output variables. 80 resourceGroupName := terraform.Output(t, terraformOptions, "resource_group_name") 81 expectedVMName := terraform.Output(t, terraformOptions, "vm_name") 82 expectedVMSize := compute.VirtualMachineSizeTypes(terraform.Output(t, terraformOptions, "vm_size")) 83 expectedAvsName := terraform.Output(t, terraformOptions, "availability_set_name") 84 85 // Check against all VM names in a Resource Group. 86 vmList := azure.ListVirtualMachinesForResourceGroup(t, resourceGroupName, subscriptionID) 87 expectedVMCount := 1 88 assert.Equal(t, expectedVMCount, len(vmList)) 89 assert.Contains(t, vmList, expectedVMName) 90 91 // Check Availability Set for multiple VMs. 92 actualVMsInAvs := azure.GetAvailabilitySetVMNamesInCaps(t, expectedAvsName, resourceGroupName, subscriptionID) 93 assert.Contains(t, actualVMsInAvs, strings.ToUpper(expectedVMName)) 94 95 // Get all VMs in a Resource Group, including their properties, therefore avoiding 96 // multiple SDK calls. The penalty for this approach is introducing direct references 97 // which need to be checked for nil for optional configurations. 98 vmsByRef := azure.GetVirtualMachinesForResourceGroup(t, resourceGroupName, subscriptionID) 99 thisVM := vmsByRef[expectedVMName] 100 assert.Equal(t, expectedVMSize, thisVM.HardwareProfile.VMSize) 101 102 // Check for the VM negative test. 103 fakeVM := fmt.Sprintf("vm-%s", random.UniqueId()) 104 assert.Nil(t, vmsByRef[fakeVM].VMID) 105 } 106 107 // These tests check information directly related to the specified Azure Virtual Machine. 108 func testInformationOfVM(t *testing.T, terraformOptions *terraform.Options, subscriptionID string) { 109 // Run `terraform output` to get the values of output variables. 110 resourceGroupName := terraform.Output(t, terraformOptions, "resource_group_name") 111 virtualMachineName := terraform.Output(t, terraformOptions, "vm_name") 112 expectedVmAdminUser := terraform.OutputList(t, terraformOptions, "vm_admin_username") 113 expectedImageSKU := terraform.OutputList(t, terraformOptions, "vm_image_sku") 114 expectedImageVersion := terraform.OutputList(t, terraformOptions, "vm_image_version") 115 expectedAvsName := terraform.Output(t, terraformOptions, "availability_set_name") 116 expectedVMTags := terraform.OutputMap(t, terraformOptions, "vm_tags") 117 118 // Check if the Virtual Machine exists. 119 assert.True(t, azure.VirtualMachineExists(t, virtualMachineName, resourceGroupName, subscriptionID)) 120 121 // Check the Admin User of the VM. 122 actualVM := azure.GetVirtualMachine(t, virtualMachineName, resourceGroupName, subscriptionID) 123 actualVmAdminUser := *actualVM.OsProfile.AdminUsername 124 assert.Equal(t, expectedVmAdminUser[0], actualVmAdminUser) 125 126 // Check the Storage Image properties of the VM. 127 actualImage := azure.GetVirtualMachineImage(t, virtualMachineName, resourceGroupName, subscriptionID) 128 assert.Contains(t, expectedImageSKU[0], actualImage.SKU) 129 assert.Contains(t, expectedImageVersion[0], actualImage.Version) 130 131 // Check the Availability Set of the VM. 132 // The AVS ID returned from the VM is always CAPS so ignoring case in the assertion. 133 actualexpectedAvsName := azure.GetVirtualMachineAvailabilitySetID(t, virtualMachineName, resourceGroupName, subscriptionID) 134 assert.True(t, strings.EqualFold(expectedAvsName, actualexpectedAvsName)) 135 136 // Check the assigned Tags of the VM, assert empty if no tags. 137 actualVMTags := azure.GetVirtualMachineTags(t, virtualMachineName, resourceGroupName, "") 138 assert.Equal(t, expectedVMTags, actualVMTags) 139 } 140 141 // These tests check the OS Disk and Attached Managed Disks for the Azure Virtual Machine. 142 // The following Terratest Azure module is utilized in addition to the compute module: 143 // - disk 144 // See the terraform_azure_disk_example_test.go for other related tests. 145 func testDisksOfVM(t *testing.T, terraformOptions *terraform.Options, subscriptionID string) { 146 // Run `terraform output` to get the values of output variables. 147 resourceGroupName := terraform.Output(t, terraformOptions, "resource_group_name") 148 virtualMachineName := terraform.Output(t, terraformOptions, "vm_name") 149 expectedOSDiskName := terraform.Output(t, terraformOptions, "os_disk_name") 150 expectedDiskName := terraform.Output(t, terraformOptions, "managed_disk_name") 151 expectedDiskType := terraform.Output(t, terraformOptions, "managed_disk_type") 152 153 // Check the OS Disk name of the VM. 154 actualOSDiskName := azure.GetVirtualMachineOSDiskName(t, virtualMachineName, resourceGroupName, subscriptionID) 155 assert.Equal(t, expectedOSDiskName, actualOSDiskName) 156 157 // Check the VM Managed Disk exists in the list of all VM Managed Disks. 158 actualManagedDiskNames := azure.GetVirtualMachineManagedDisks(t, virtualMachineName, resourceGroupName, subscriptionID) 159 assert.Contains(t, actualManagedDiskNames, expectedDiskName) 160 161 // Check the Managed Disk count of the VM. 162 expectedManagedDiskCount := 1 163 assert.Equal(t, expectedManagedDiskCount, len(actualManagedDiskNames)) 164 165 // Check the Disk Type of the Managed Disk of the VM. 166 // This does not apply to VHD disks saved under a storage account. 167 actualDisk := azure.GetDisk(t, expectedDiskName, resourceGroupName, subscriptionID) 168 actualDiskType := actualDisk.Sku.Name 169 assert.Equal(t, compute.DiskStorageAccountTypes(expectedDiskType), actualDiskType) 170 } 171 172 // These tests check the underlying Virtual Network, Network Interface and associated Public IP Address. 173 // The following Terratest Azure modules are utilized in addition to the compute module: 174 // - networkinterface 175 // - publicaddress 176 // - virtualnetwork 177 // See the terraform_azure_network_example_test.go for other related tests. 178 func testNetworkOfVM(t *testing.T, terraformOptions *terraform.Options, subscriptionID string) { 179 // Run `terraform output` to get the values of output variables. 180 resourceGroupName := terraform.Output(t, terraformOptions, "resource_group_name") 181 virtualMachineName := terraform.Output(t, terraformOptions, "vm_name") 182 expectedVNetName := terraform.Output(t, terraformOptions, "virtual_network_name") 183 expectedSubnetName := terraform.Output(t, terraformOptions, "subnet_name") 184 expectedPublicAddressName := terraform.Output(t, terraformOptions, "public_ip_name") 185 expectedNicName := terraform.Output(t, terraformOptions, "network_interface_name") 186 expectedPrivateIPAddress := terraform.Output(t, terraformOptions, "private_ip") 187 188 // VirtualNetwork and Subnet tests 189 // Check the Subnet exists in the Virtual Network. 190 actualVnetSubnets := azure.GetVirtualNetworkSubnets(t, expectedVNetName, resourceGroupName, subscriptionID) 191 assert.NotNil(t, actualVnetSubnets[expectedVNetName]) 192 193 // Check the Private IP is in the Subnet Range. 194 actualVMNicIPInSubnet := azure.CheckSubnetContainsIP(t, expectedPrivateIPAddress, expectedSubnetName, expectedVNetName, resourceGroupName, subscriptionID) 195 assert.True(t, actualVMNicIPInSubnet) 196 197 // Network Interface Card tests 198 // Check the VM Network Interface exists in the list of all VM Network Interfaces. 199 actualNics := azure.GetVirtualMachineNics(t, virtualMachineName, resourceGroupName, subscriptionID) 200 assert.Contains(t, actualNics, expectedNicName) 201 202 // Check the Network Interface count of the VM. 203 expectedNICCount := 1 204 assert.Equal(t, expectedNICCount, len(actualNics)) 205 206 // Check for the Private IP in the NICs IP list. 207 actualPrivateIPAddress := azure.GetNetworkInterfacePrivateIPs(t, expectedNicName, resourceGroupName, subscriptionID) 208 assert.Contains(t, actualPrivateIPAddress, expectedPrivateIPAddress) 209 210 // Public IP Address test 211 // Check for the Public IP for the NIC. No expected value since it is assigned runtime. 212 actualPublicIP := azure.GetIPOfPublicIPAddressByName(t, expectedPublicAddressName, resourceGroupName, subscriptionID) 213 assert.NotNil(t, actualPublicIP) 214 215 }