diff --git a/azurerm/internal/services/network/client/client.go b/azurerm/internal/services/network/client/client.go index 9794b251ef66..9675cba23a2d 100644 --- a/azurerm/internal/services/network/client/client.go +++ b/azurerm/internal/services/network/client/client.go @@ -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 @@ -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) @@ -177,6 +181,7 @@ func NewClient(o *common.ClientOptions) *Client { RouteTablesClient: &RouteTablesClient, SecurityGroupClient: &SecurityGroupClient, SecurityRuleClient: &SecurityRuleClient, + ServiceTagsClient: &ServiceTagsClient, SubnetsClient: &SubnetsClient, NatGatewayClient: &NatGatewayClient, VnetGatewayConnectionsClient: &VnetGatewayConnectionsClient, diff --git a/azurerm/internal/services/network/data_source_network_service_tags.go b/azurerm/internal/services/network/data_source_network_service_tags.go new file mode 100644 index 000000000000..3120f88fb8cc --- /dev/null +++ b/azurerm/internal/services/network/data_source_network_service_tags.go @@ -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 +} diff --git a/azurerm/internal/services/network/registration.go b/azurerm/internal/services/network/registration.go index eaff7337d986..1bd4e2ba5bc4 100644 --- a/azurerm/internal/services/network/registration.go +++ b/azurerm/internal/services/network/registration.go @@ -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(), diff --git a/azurerm/internal/services/network/tests/data_source_network_service_tags_test.go b/azurerm/internal/services/network/tests/data_source_network_service_tags_test.go new file mode 100644 index 000000000000..76b49d03c9f7 --- /dev/null +++ b/azurerm/internal/services/network/tests/data_source_network_service_tags_test.go @@ -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" +}` +} diff --git a/website/allowed-subcategories b/website/allowed-subcategories index 2d680938ea24..ee7a2eb1ce6f 100644 --- a/website/allowed-subcategories +++ b/website/allowed-subcategories @@ -14,7 +14,7 @@ Compute Container CosmosDB (DocumentDB) Cost Management -Custom Provider +Custom Providers DNS Data Explorer Data Factory diff --git a/website/azurerm.erb b/website/azurerm.erb index aa90e37c4d75..65a57c6cdd94 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -394,6 +394,10 @@ azurerm_netapp_snapshot +
  • + azurerm_network_service_tags +
  • +
  • azurerm_platform_image
  • diff --git a/website/docs/d/network_service_tags.html.markdown b/website/docs/d/network_service_tags.html.markdown new file mode 100644 index 000000000000..0df0026fd61d --- /dev/null +++ b/website/docs/d/network_service_tags.html.markdown @@ -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. diff --git a/website/docs/r/custom_provider.html.markdown b/website/docs/r/custom_provider.html.markdown index ab37aa672e6c..118c14f14d0e 100644 --- a/website/docs/r/custom_provider.html.markdown +++ b/website/docs/r/custom_provider.html.markdown @@ -1,5 +1,5 @@ --- -subcategory: "Custom Provider" +subcategory: "Custom Providers" layout: "azurerm" page_title: "Azure Resource Manager: azurerm_custom_provider" description: |-