Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New data source - azurerm_virtual_machine_scale_set_network_interfaces #6752

Closed
wants to merge 18 commits into from
Closed
Original file line number Diff line number Diff line change
@@ -0,0 +1,275 @@
package network

import (
"fmt"
"time"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts"
)

func dataSourceArmVirtualMachineScaleSetNetworkInterfaces() *schema.Resource {
return &schema.Resource{
Read: dataSourceArmVirtualMachineScaleSetNetworkInterfacesRead,

Timeouts: &schema.ResourceTimeout{
Read: schema.DefaultTimeout(5 * time.Minute),
},

Schema: map[string]*schema.Schema{
"virtual_machine_scale_set_name": {
Type: schema.TypeString,
Required: true,
},

"resource_group_name": azure.SchemaResourceGroupNameForDataSource(),

"network_interfaces": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{

"name": {
Type: schema.TypeString,
Computed: true,
},

"network_security_group_id": {
Type: schema.TypeString,
Computed: true,
},

"mac_address": {
Type: schema.TypeString,
Computed: true,
},

"virtual_machine_id": {
Type: schema.TypeString,
Computed: true,
},

"id": {
Type: schema.TypeString,
Computed: true,
},

"ip_configuration": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Computed: true,
},

"subnet_id": {
Type: schema.TypeString,
Computed: true,
},

"private_ip_address": {
Type: schema.TypeString,
Computed: true,
},

"private_ip_address_version": {
Type: schema.TypeString,
Computed: true,
},

"private_ip_address_allocation": {
Type: schema.TypeString,
Computed: true,
},

"public_ip_address_id": {
Type: schema.TypeString,
Computed: true,
},

"application_gateway_backend_address_pools_ids": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},

"load_balancer_backend_address_pools_ids": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},

"load_balancer_inbound_nat_rules_ids": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},

"application_security_group_ids": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is a Computed attribute, we should just use TypeList instead of TypeSet. And this would also benefit the users when they are trying to use one of the element.


"primary": {
Type: schema.TypeBool,
Computed: true,
},
},
},
},

"dns_servers": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is a Computed attribute, we should just use TypeList instead of TypeSet. And this would also benefit the users when they are trying to use one of the element.


"internal_dns_name_label": {
Type: schema.TypeString,
Computed: true,
},

"applied_dns_servers": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar with the above, should use TypeList


"enable_accelerated_networking": {
Type: schema.TypeBool,
Computed: true,
},

"enable_ip_forwarding": {
Type: schema.TypeBool,
Computed: true,
},

"private_ip_address": {
Type: schema.TypeString,
Computed: true,
},

"private_ip_addresses": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
},
},
},
}
}

func dataSourceArmVirtualMachineScaleSetNetworkInterfacesRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Network.InterfacesClient
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
defer cancel()

resGroup := d.Get("resource_group_name").(string)
vmssName := d.Get("virtual_machine_scale_set_name").(string)

resp, err := client.ListVirtualMachineScaleSetNetworkInterfaces(ctx, resGroup, vmssName)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this API is a pagable request, could we switch to the ListVirtualMachineScaleSetNetworkInterfacesComplete method and use the iterator to iterate the result?

if err != nil {
return fmt.Errorf("Error making Read request on Azure VMSS %q (Resource Group %q): %+v", vmssName, resGroup, err)
}

results := make([]interface{}, 0)

for _, iface := range resp.Values() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually the result may have multiple pages, therefore you should add an outer loop to iterate all of the pages.
But it would be more clear if you use the ListVirtualMachineScaleSetNetworkInterfacesComplete and iterate over the iterator.

result := make(map[string]interface{})

if iface.Name != nil {
result["name"] = *iface.Name
} else {
result["name"] = ""
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually we would write this like this:

Suggested change
if iface.Name != nil {
result["name"] = *iface.Name
} else {
result["name"] = ""
}
name := "" // var name string also works
if iface.Name != nil {
name = *iface.Name
}
// other fields
results = append(results, map[string]interface{}{
"name": name,
// other fields
})


if iface.NetworkSecurityGroup != nil {
result["network_security_group_id"] = *iface.NetworkSecurityGroup.ID
} else {
result["network_security_group_id"] = ""
}

if iface.MacAddress != nil {
result["mac_address"] = *iface.MacAddress
} else {
result["mac_address"] = ""
}

if iface.VirtualMachine != nil {
result["virtual_machine_id"] = *iface.VirtualMachine.ID
} else {
result["virtual_machine_id"] = ""
}

if iface.ID != nil {
result["id"] = *iface.ID
} else {
result["id"] = ""
}

if iface.IPConfigurations != nil && len(*iface.IPConfigurations) > 0 {
configs := *iface.IPConfigurations

result["private_ip_address"] = *configs[0].InterfaceIPConfigurationPropertiesFormat.PrivateIPAddress

addresses := make([]interface{}, 0)
for _, config := range configs {
if config.InterfaceIPConfigurationPropertiesFormat != nil {
addresses = append(addresses, config.InterfaceIPConfigurationPropertiesFormat.PrivateIPAddress)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we please extract this into an flatten function? Which may make this more clear

result["private_ip_addresses"] = addresses
}

if iface.IPConfigurations != nil {
result["ip_configuration"] = flattenNetworkInterfaceIPConfigurations(iface.IPConfigurations)
}

var appliedDNSServers []string
var dnsServers []string
if dnsSettings := iface.DNSSettings; dnsSettings != nil {
if s := dnsSettings.AppliedDNSServers; s != nil {
appliedDNSServers = *s
}

if s := dnsSettings.DNSServers; s != nil {
dnsServers = *s
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually we have a built-in helper function utils.FlattenStringSlice(), could we please use this function instead? By doing this, these nil-checks can be removed.


if dnsSettings.InternalDNSNameLabel != nil {
result["internal_dns_name_label"] = *dnsSettings.InternalDNSNameLabel
} else {
result["internal_dns_name_label"] = ""
}
}

result["applied_dns_servers"] = appliedDNSServers
result["dns_servers"] = dnsServers
result["enable_ip_forwarding"] = *iface.EnableIPForwarding
result["enable_accelerated_networking"] = *iface.EnableAcceleratedNetworking
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two would also need nil-checks

results = append(results, result)
}

d.SetId(time.Now().UTC().String())
if err := d.Set("network_interfaces", results); err != nil {
return fmt.Errorf("Error setting `network_interfaces`: %+v", err)
}
return nil
}
47 changes: 24 additions & 23 deletions azurerm/internal/services/network/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,30 @@ func (r Registration) WebsiteCategories() []string {
// SupportedDataSources returns the supported Data Sources supported by this Service
func (r Registration) SupportedDataSources() map[string]*schema.Resource {
return map[string]*schema.Resource{
"azurerm_application_security_group": dataSourceArmApplicationSecurityGroup(),
"azurerm_express_route_circuit": dataSourceArmExpressRouteCircuit(),
"azurerm_firewall": dataSourceArmFirewall(),
"azurerm_lb": dataSourceArmLoadBalancer(),
"azurerm_lb_backend_address_pool": dataSourceArmLoadBalancerBackendAddressPool(),
"azurerm_nat_gateway": dataSourceArmNatGateway(),
"azurerm_network_ddos_protection_plan": dataSourceNetworkDDoSProtectionPlan(),
"azurerm_network_interface": dataSourceArmNetworkInterface(),
"azurerm_network_security_group": dataSourceArmNetworkSecurityGroup(),
"azurerm_network_watcher": dataSourceArmNetworkWatcher(),
"azurerm_private_endpoint_connection": dataSourceArmPrivateEndpointConnection(),
"azurerm_private_link_service": dataSourceArmPrivateLinkService(),
"azurerm_private_link_service_endpoint_connections": dataSourceArmPrivateLinkServiceEndpointConnections(),
"azurerm_public_ip": dataSourceArmPublicIP(),
"azurerm_public_ips": dataSourceArmPublicIPs(),
"azurerm_public_ip_prefix": dataSourceArmPublicIpPrefix(),
"azurerm_route_table": dataSourceArmRouteTable(),
"azurerm_network_service_tags": dataSourceNetworkServiceTags(),
"azurerm_subnet": dataSourceArmSubnet(),
"azurerm_virtual_hub": dataSourceArmVirtualHub(),
"azurerm_virtual_network_gateway": dataSourceArmVirtualNetworkGateway(),
"azurerm_virtual_network_gateway_connection": dataSourceArmVirtualNetworkGatewayConnection(),
"azurerm_virtual_network": dataSourceArmVirtualNetwork(),
"azurerm_application_security_group": dataSourceArmApplicationSecurityGroup(),
"azurerm_express_route_circuit": dataSourceArmExpressRouteCircuit(),
"azurerm_firewall": dataSourceArmFirewall(),
"azurerm_lb": dataSourceArmLoadBalancer(),
"azurerm_lb_backend_address_pool": dataSourceArmLoadBalancerBackendAddressPool(),
"azurerm_nat_gateway": dataSourceArmNatGateway(),
"azurerm_network_ddos_protection_plan": dataSourceNetworkDDoSProtectionPlan(),
"azurerm_network_interface": dataSourceArmNetworkInterface(),
"azurerm_network_security_group": dataSourceArmNetworkSecurityGroup(),
"azurerm_network_watcher": dataSourceArmNetworkWatcher(),
"azurerm_private_endpoint_connection": dataSourceArmPrivateEndpointConnection(),
"azurerm_private_link_service": dataSourceArmPrivateLinkService(),
"azurerm_private_link_service_endpoint_connections": dataSourceArmPrivateLinkServiceEndpointConnections(),
"azurerm_public_ip": dataSourceArmPublicIP(),
"azurerm_public_ips": dataSourceArmPublicIPs(),
"azurerm_public_ip_prefix": dataSourceArmPublicIpPrefix(),
"azurerm_route_table": dataSourceArmRouteTable(),
"azurerm_network_service_tags": dataSourceNetworkServiceTags(),
"azurerm_subnet": dataSourceArmSubnet(),
"azurerm_virtual_hub": dataSourceArmVirtualHub(),
"azurerm_virtual_machine_scale_set_network_interfaces": dataSourceArmVirtualMachineScaleSetNetworkInterfaces(),
"azurerm_virtual_network_gateway": dataSourceArmVirtualNetworkGateway(),
"azurerm_virtual_network_gateway_connection": dataSourceArmVirtualNetworkGatewayConnection(),
"azurerm_virtual_network": dataSourceArmVirtualNetwork(),
}
}

Expand Down
Loading