Skip to content

Commit

Permalink
New data source: azurerm_network_service_tags (#6229)
Browse files Browse the repository at this point in the history
Service Tags / address prefixes are useful when using firewall rules or UDRs in some scenarios.
  • Loading branch information
r0bnet authored Mar 26, 2020
1 parent 122ae76 commit 5543fec
Show file tree
Hide file tree
Showing 8 changed files with 233 additions and 2 deletions.
5 changes: 5 additions & 0 deletions azurerm/internal/services/network/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type Client struct {
RouteTablesClient *network.RouteTablesClient
SecurityGroupClient *network.SecurityGroupsClient
SecurityRuleClient *network.SecurityRulesClient
ServiceTagsClient *network.ServiceTagsClient
SubnetsClient *network.SubnetsClient
NatGatewayClient *network.NatGatewaysClient
VnetGatewayConnectionsClient *network.VirtualNetworkGatewayConnectionsClient
Expand Down Expand Up @@ -126,6 +127,9 @@ func NewClient(o *common.ClientOptions) *Client {
SecurityRuleClient := network.NewSecurityRulesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&SecurityRuleClient.Client, o.ResourceManagerAuthorizer)

ServiceTagsClient := network.NewServiceTagsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&ServiceTagsClient.Client, o.ResourceManagerAuthorizer)

SubnetsClient := network.NewSubnetsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&SubnetsClient.Client, o.ResourceManagerAuthorizer)

Expand Down Expand Up @@ -177,6 +181,7 @@ func NewClient(o *common.ClientOptions) *Client {
RouteTablesClient: &RouteTablesClient,
SecurityGroupClient: &SecurityGroupClient,
SecurityRuleClient: &SecurityRuleClient,
ServiceTagsClient: &ServiceTagsClient,
SubnetsClient: &SubnetsClient,
NatGatewayClient: &NatGatewayClient,
VnetGatewayConnectionsClient: &VnetGatewayConnectionsClient,
Expand Down
113 changes: 113 additions & 0 deletions azurerm/internal/services/network/data_source_network_service_tags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package network

import (
"fmt"
"strings"
"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/location"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts"
)

func dataSourceNetworkServiceTags() *schema.Resource {
return &schema.Resource{
Read: dataSourceNetworkServiceTagsRead,

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

Schema: map[string]*schema.Schema{
"location": azure.SchemaLocation(),

"service": {
Type: schema.TypeString,
Required: true,
},

"location_filter": {
Type: schema.TypeString,
Optional: true,
StateFunc: azure.NormalizeLocation,
DiffSuppressFunc: location.DiffSuppressFunc,
},

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

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

location := azure.NormalizeLocation(d.Get("location"))
res, err := client.List(ctx, location)
if err != nil {
return fmt.Errorf("error listing network service tags: %+v", err)
}

if res.Values == nil {
return fmt.Errorf("unexpected nil value for service tag information")
}

service := d.Get("service").(string)
locationFilter := azure.NormalizeLocation(d.Get("location_filter"))

for _, sti := range *res.Values {
if sti.Name == nil || !isServiceTagOf(*sti.Name, service) {
continue
}

if props := sti.Properties; props != nil {
if props.Region == nil {
continue
}

if azure.NormalizeLocation(*props.Region) == locationFilter {
addressPrefixes := make([]string, 0)
if props.AddressPrefixes != nil {
addressPrefixes = *props.AddressPrefixes
}
err = d.Set("address_prefixes", addressPrefixes)
if err != nil {
return fmt.Errorf("error setting `address_prefixes`: %+v", err)
}

if sti.ID == nil {
return fmt.Errorf("unexcepted nil ID for service tag")
}

d.SetId(*sti.ID)
return nil
}
}
}
errSuffix := "globally"
if locationFilter != "" {
errSuffix = "for region " + locationFilter
}
return fmt.Errorf("specified service tag `%s` not found %s", service, errSuffix)
}

// isServiceTagOf is used to check whether a service tag name belongs to the service of name `serviceName`.
// Service tag name has format as below:
// - (regional) serviceName.locationName
// - (all) serviceName
func isServiceTagOf(stName, serviceName string) bool {
stNameComponents := strings.Split(stName, ".")
if len(stNameComponents) != 1 && len(stNameComponents) != 2 {
return false
}
return stNameComponents[0] == serviceName
}
1 change: 1 addition & 0 deletions azurerm/internal/services/network/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ func (r Registration) SupportedDataSources() map[string]*schema.Resource {
"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(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package tests

import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance"
)

func TestAccDataSourceAzureRMServiceTags_basic(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azurerm_network_service_tags", "test")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.PreCheck(t) },
Providers: acceptance.SupportedProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceAzureRMServiceTags_basic(),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(data.ResourceName, "address_prefixes.#", "210"),
),
},
},
})
}

func TestAccDataSourceAzureRMServiceTags_region(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azurerm_network_service_tags", "test")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.PreCheck(t) },
Providers: acceptance.SupportedProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceAzureRMServiceTags_region(),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(data.ResourceName, "address_prefixes.#", "3"),
),
},
},
})
}

func testAccDataSourceAzureRMServiceTags_basic() string {
return `data "azurerm_network_service_tags" "test" {
location = "northeurope"
service = "AzureKeyVault"
}`
}

func testAccDataSourceAzureRMServiceTags_region() string {
return `data "azurerm_network_service_tags" "test" {
location = "northeurope"
service = "AzureKeyVault"
location_filter = "australiacentral"
}`
}
2 changes: 1 addition & 1 deletion website/allowed-subcategories
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Compute
Container
CosmosDB (DocumentDB)
Cost Management
Custom Provider
Custom Providers
DNS
Data Explorer
Data Factory
Expand Down
4 changes: 4 additions & 0 deletions website/azurerm.erb
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,10 @@
<a href="/docs/providers/azurerm/d/netapp_snapshot.html">azurerm_netapp_snapshot</a>
</li>

<li>
<a href="/docs/providers/azurerm/d/network_service_tags.html">azurerm_network_service_tags</a>
</li>

<li>
<a href="/docs/providers/azurerm/d/platform_image.html">azurerm_platform_image</a>
</li>
Expand Down
51 changes: 51 additions & 0 deletions website/docs/d/network_service_tags.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
subcategory: "Network"
layout: "azurerm"
page_title: "Azure Resource Manager: azurerm_network_service_tags"
description: |-
Gets information about Service Tags for a specific service type.
---

# Data Source: azurerm__network_service_tags

Use this data source to access information about Service Tags.

## Example Usage

```hcl
data "azurerm_network_service_tags" "example" {
location = "West Europe"
service = "AzureKeyVault"
location_filter = "northeurope"
}
output "address_prefixes" {
value = data.azurerm_service_tags.example.address_prefixes
}
```

## Arguments Reference

The following arguments are supported:

* `location` - (Required) The Azure Region where the Service Tags exists. This value is not used to filter the results but for specifying the region to request. For filtering by region use `location_filter` instead. More information can be found here: [Service Tags URL parameters](https://docs.microsoft.com/en-us/rest/api/virtualnetwork/servicetags/list#uri-parameters).

* `service` - (Required) The type of the service for which address prefixes will be fetched. Available service tags can be found here: [Available service tags](https://docs.microsoft.com/en-us/azure/virtual-network/service-tags-overview#available-service-tags).

---

* `location_filter` - (Optional) Changes the scope of the service tags. Can be any value that is also valid for `location`. If this field is empty then all address prefixes are considered instead of only location specific ones.

## Attributes Reference

In addition to the Arguments listed above - the following Attributes are exported:

* `id` - The ID of this Service Tags block.

* `address_prefixes` - List of address prefixes for the service type (and optionally a specific region).

## Timeouts

The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration/resources.html#timeouts) for certain actions:

* `read` - (Defaults to 5 minutes) Used when retrieving the Service Tags.
2 changes: 1 addition & 1 deletion website/docs/r/custom_provider.html.markdown
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
subcategory: "Custom Provider"
subcategory: "Custom Providers"
layout: "azurerm"
page_title: "Azure Resource Manager: azurerm_custom_provider"
description: |-
Expand Down

0 comments on commit 5543fec

Please sign in to comment.