github.com/swisspost/terratest@v0.0.0-20230214120104-7ec6de2e1ae0/test/azure/terraform_azure_vm_example_test.go (about)

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