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  }