diff --git a/internal/services/compute/virtual_machine_data_source.go b/internal/services/compute/virtual_machine_data_source.go index 886f6d384e0b..2a0b58d2fc6c 100644 --- a/internal/services/compute/virtual_machine_data_source.go +++ b/internal/services/compute/virtual_machine_data_source.go @@ -8,6 +8,7 @@ import ( "strings" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema" "github.com/hashicorp/go-azure-helpers/resourcemanager/identity" @@ -85,7 +86,9 @@ func dataSourceVirtualMachineRead(d *pluginsdk.ResourceData, meta interface{}) e id := virtualmachines.NewVirtualMachineID(subscriptionId, d.Get("resource_group_name").(string), d.Get("name").(string)) - resp, err := client.Get(ctx, id, virtualmachines.DefaultGetOperationOptions()) + options := virtualmachines.DefaultGetOperationOptions() + options.Expand = pointer.To(virtualmachines.InstanceViewTypesInstanceView) + resp, err := client.Get(ctx, id, options) if err != nil { if response.WasNotFound(resp.HttpResponse) { return fmt.Errorf("%s was not found", id) diff --git a/internal/services/compute/virtual_machine_data_source_test.go b/internal/services/compute/virtual_machine_data_source_test.go index 8b7b4b954217..4c5184b91b17 100644 --- a/internal/services/compute/virtual_machine_data_source_test.go +++ b/internal/services/compute/virtual_machine_data_source_test.go @@ -26,6 +26,7 @@ func TestAccDataSourceAzureRMVirtualMachine_basicLinux(t *testing.T) { check.That(data.ResourceName).Key("identity.0.principal_id").Exists(), check.That(data.ResourceName).Key("identity.0.tenant_id").Exists(), check.That(data.ResourceName).Key("private_ip_address").HasValue("10.0.2.4"), + check.That(data.ResourceName).Key("power_state").HasValue("running"), ), }, }) @@ -44,6 +45,7 @@ func TestAccDataSourceAzureRMVirtualMachine_basicWindows(t *testing.T) { check.That(data.ResourceName).Key("identity.0.principal_id").Exists(), check.That(data.ResourceName).Key("identity.0.tenant_id").Exists(), check.That(data.ResourceName).Key("private_ip_address").HasValue("10.0.2.4"), + check.That(data.ResourceName).Key("power_state").HasValue("running"), ), }, }) diff --git a/internal/services/compute/virtual_machine_scale_set_data_source.go b/internal/services/compute/virtual_machine_scale_set_data_source.go index ca5b329986ff..1502926815a8 100644 --- a/internal/services/compute/virtual_machine_scale_set_data_source.go +++ b/internal/services/compute/virtual_machine_scale_set_data_source.go @@ -170,12 +170,32 @@ func dataSourceVirtualMachineScaleSetRead(d *pluginsdk.ResourceData, meta interf instances := make([]interface{}, 0) virtualMachineScaleSetId := virtualmachinescalesetvms.NewVirtualMachineScaleSetID(subscriptionId, id.ResourceGroupName, id.VirtualMachineScaleSetName) - result, err := instancesClient.ListComplete(ctx, virtualMachineScaleSetId, virtualmachinescalesetvms.DefaultListOperationOptions()) + + // If the VMSS is in Uniform Orchestration Mode, we can use instanceView for the VMSS instances + // Flexible VMSS instances cannot use instanceView from the VMSS API + // Instead we need to use the VM API for instanceView + optionsVMSS := virtualmachinescalesetvms.DefaultListOperationOptions() + optionsVM := virtualmachines.DefaultGetOperationOptions() + var orchestrationMode string + if props := resp.Model.Properties; props != nil { + if *props.OrchestrationMode == virtualmachinescalesets.OrchestrationModeUniform { + expandStr := "instanceView" + optionsVMSS.Expand = &expandStr + orchestrationMode = "Uniform" + } + if *props.OrchestrationMode == virtualmachinescalesets.OrchestrationModeFlexible { + optionsVM.Expand = pointer.To(virtualmachines.InstanceViewTypesInstanceView) + orchestrationMode = "Flexible" + } + } + + result, err := instancesClient.ListComplete(ctx, virtualMachineScaleSetId, optionsVMSS) if err != nil { return fmt.Errorf("listing VM Instances for %q: %+v", id, err) } var connInfo *connectionInfo + var vmModel *virtualmachines.VirtualMachine for _, item := range result.Items { if item.InstanceId != nil { vmId := networkinterfaces.NewVirtualMachineID(subscriptionId, id.ResourceGroupName, id.VirtualMachineScaleSetName, *item.InstanceId) @@ -187,12 +207,13 @@ func dataSourceVirtualMachineScaleSetRead(d *pluginsdk.ResourceData, meta interf // Network Interfaces of VM in Flexible VMSS are accessed from single VM virtualMachineId := virtualmachines.NewVirtualMachineID(subscriptionId, id.ResourceGroupName, *item.InstanceId) - vm, err := virtualMachinesClient.Get(ctx, virtualMachineId, virtualmachines.DefaultGetOperationOptions()) + vm, err := virtualMachinesClient.Get(ctx, virtualMachineId, optionsVM) if err != nil { return fmt.Errorf("retrieving VM Instance %q for %q: %+v", *item.InstanceId, id, err) } connInfoRaw := retrieveConnectionInformation(ctx, networkInterfacesClient, publicIPAddressesClient, vm.Model.Properties) connInfo = &connInfoRaw + vmModel = vm.Model } else { connInfo, err = getVirtualMachineScaleSetVMConnectionInfo(ctx, nics.Items, id.ResourceGroupName, id.VirtualMachineScaleSetName, *item.InstanceId, vmssPublicIpAddressesClient) if err != nil { @@ -200,7 +221,7 @@ func dataSourceVirtualMachineScaleSetRead(d *pluginsdk.ResourceData, meta interf } } - flattenedInstances := flattenVirtualMachineScaleSetVM(item, connInfo) + flattenedInstances := flattenVirtualMachineScaleSetVM(item, connInfo, vmModel, orchestrationMode) instances = append(instances, flattenedInstances) } } @@ -275,29 +296,53 @@ func getVirtualMachineScaleSetVMConnectionInfo(ctx context.Context, networkInter }, nil } -func flattenVirtualMachineScaleSetVM(input virtualmachinescalesetvms.VirtualMachineScaleSetVM, connectionInfo *connectionInfo) map[string]interface{} { +func flattenVirtualMachineScaleSetVM(input virtualmachinescalesetvms.VirtualMachineScaleSetVM, connectionInfo *connectionInfo, vm *virtualmachines.VirtualMachine, mode string) map[string]interface{} { output := make(map[string]interface{}) output["name"] = *input.Name output["instance_id"] = *input.InstanceId - if props := input.Properties; props != nil { - if props.LatestModelApplied != nil { - output["latest_model_applied"] = *props.LatestModelApplied - } + if mode == "Flexible" && vm != nil { + if props := vm.Properties; props != nil { + if props.VMId != nil { + output["virtual_machine_id"] = *props.VMId + } - if props.VMId != nil { - output["virtual_machine_id"] = *props.VMId - } + if profile := props.OsProfile; profile != nil && profile.ComputerName != nil { + output["computer_name"] = *profile.ComputerName + } - if profile := props.OsProfile; profile != nil && profile.ComputerName != nil { - output["computer_name"] = *profile.ComputerName + if instance := props.InstanceView; instance != nil { + if statuses := instance.Statuses; statuses != nil { + for _, status := range *statuses { + if status.Code != nil && strings.HasPrefix(strings.ToLower(*status.Code), "powerstate/") { + output["power_state"] = strings.SplitN(*status.Code, "/", 2)[1] + } + } + } + } } + } + + if mode == "Uniform" { + if props := input.Properties; props != nil { + if props.LatestModelApplied != nil { + output["latest_model_applied"] = *props.LatestModelApplied + } - if instance := props.InstanceView; instance != nil { - if statuses := instance.Statuses; statuses != nil { - for _, status := range *statuses { - if status.Code != nil && strings.HasPrefix(strings.ToLower(*status.Code), "powerstate/") { - output["power_state"] = strings.SplitN(*status.Code, "/", 2)[1] + if props.VMId != nil { + output["virtual_machine_id"] = *props.VMId + } + + if profile := props.OsProfile; profile != nil && profile.ComputerName != nil { + output["computer_name"] = *profile.ComputerName + } + + if instance := props.InstanceView; instance != nil { + if statuses := instance.Statuses; statuses != nil { + for _, status := range *statuses { + if status.Code != nil && strings.HasPrefix(strings.ToLower(*status.Code), "powerstate/") { + output["power_state"] = strings.SplitN(*status.Code, "/", 2)[1] + } } } } diff --git a/internal/services/compute/virtual_machine_scale_set_data_source_test.go b/internal/services/compute/virtual_machine_scale_set_data_source_test.go index fd8910658bda..51d3f101ba3f 100644 --- a/internal/services/compute/virtual_machine_scale_set_data_source_test.go +++ b/internal/services/compute/virtual_machine_scale_set_data_source_test.go @@ -27,6 +27,7 @@ func TestAccDataSourceVirtualMachineScaleSet_basicLinux(t *testing.T) { check.That(data.ResourceName).Key("instances.#").HasValue("1"), check.That(data.ResourceName).Key("instances.0.instance_id").HasValue("0"), check.That(data.ResourceName).Key("instances.0.private_ip_address").HasValue("10.0.2.4"), + check.That(data.ResourceName).Key("instances.0.power_state").HasValue("running"), ), }, })