diff --git a/azurerm/resource_arm_network_security_rule.go b/azurerm/resource_arm_network_security_rule.go index edcdd3a32ce3..5dbbc075a732 100644 --- a/azurerm/resource_arm_network_security_rule.go +++ b/azurerm/resource_arm_network_security_rule.go @@ -52,23 +52,59 @@ func resourceArmNetworkSecurityRule() *schema.Resource { }, "source_port_range": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"source_port_ranges"}, + }, + + "source_port_ranges": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + ConflictsWith: []string{"source_port_range"}, }, "destination_port_range": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"destination_port_ranges"}, + }, + + "destination_port_ranges": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + ConflictsWith: []string{"destination_port_range"}, }, "source_address_prefix": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"source_address_prefixes"}, + }, + + "source_address_prefixes": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + ConflictsWith: []string{"source_address_prefix"}, }, "destination_address_prefix": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"destination_address_prefixes"}, + }, + + "destination_address_prefixes": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + ConflictsWith: []string{"destination_address_prefix"}, }, "access": { @@ -138,6 +174,46 @@ func resourceArmNetworkSecurityRuleCreate(d *schema.ResourceData, meta interface rule.SecurityRulePropertiesFormat.Description = &description } + if r, ok := d.GetOk("source_port_ranges"); ok { + var sourcePortRanges []string + r := r.(*schema.Set).List() + for _, v := range r { + s := v.(string) + sourcePortRanges = append(sourcePortRanges, s) + } + rule.SecurityRulePropertiesFormat.SourcePortRanges = &sourcePortRanges + } + + if r, ok := d.GetOk("destination_port_ranges"); ok { + var destinationPortRanges []string + r := r.(*schema.Set).List() + for _, v := range r { + s := v.(string) + destinationPortRanges = append(destinationPortRanges, s) + } + rule.SecurityRulePropertiesFormat.DestinationPortRanges = &destinationPortRanges + } + + if r, ok := d.GetOk("source_address_prefixes"); ok { + var sourceAddressPrefixes []string + r := r.(*schema.Set).List() + for _, v := range r { + s := v.(string) + sourceAddressPrefixes = append(sourceAddressPrefixes, s) + } + rule.SecurityRulePropertiesFormat.SourceAddressPrefixes = &sourceAddressPrefixes + } + + if r, ok := d.GetOk("destination_address_prefixes"); ok { + var destinationAddressPrefixes []string + r := r.(*schema.Set).List() + for _, v := range r { + s := v.(string) + destinationAddressPrefixes = append(destinationAddressPrefixes, s) + } + rule.SecurityRulePropertiesFormat.DestinationAddressPrefixes = &destinationAddressPrefixes + } + _, createErr := client.CreateOrUpdate(resGroup, nsgName, name, rule, make(chan struct{})) err := <-createErr if err != nil { @@ -190,6 +266,10 @@ func resourceArmNetworkSecurityRuleRead(d *schema.ResourceData, meta interface{} d.Set("protocol", string(props.Protocol)) d.Set("source_address_prefix", props.SourceAddressPrefix) d.Set("source_port_range", props.SourcePortRange) + d.Set("source_address_prefixes", props.SourceAddressPrefixes) + d.Set("destination_address_prefixes", props.DestinationAddressPrefixes) + d.Set("source_port_ranges", props.SourcePortRanges) + d.Set("destination_port_ranges", props.DestinationPortRanges) } return nil diff --git a/azurerm/resource_arm_network_security_rule_test.go b/azurerm/resource_arm_network_security_rule_test.go index 966bfd0c16a2..9e590d8ba48c 100644 --- a/azurerm/resource_arm_network_security_rule_test.go +++ b/azurerm/resource_arm_network_security_rule_test.go @@ -74,6 +74,23 @@ func TestAccAzureRMNetworkSecurityRule_addingRules(t *testing.T) { }) } +func TestAccAzureRMNetworkSecurityRule_augmented(t *testing.T) { + rInt := acctest.RandInt() + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNetworkSecurityRuleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMNetworkSecurityRule_augmented(rInt, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkSecurityRuleExists("azurerm_network_security_rule.test1"), + ), + }, + }, + }) +} + func testCheckAzureRMNetworkSecurityRuleExists(name string) resource.TestCheckFunc { return func(s *terraform.State) error { @@ -259,3 +276,32 @@ resource "azurerm_network_security_rule" "test2" { } `, rInt, location) } + +func testAccAzureRMNetworkSecurityRule_augmented(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test1" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_network_security_group" "test1" { + name = "acceptanceTestSecurityGroup2" + location = "${azurerm_resource_group.test1.location}" + resource_group_name = "${azurerm_resource_group.test1.name}" +} + +resource "azurerm_network_security_rule" "test1" { + name = "test123" + priority = 100 + direction = "Outbound" + access = "Allow" + protocol = "Tcp" + source_port_ranges = [ "10000-40000" ] + destination_port_ranges = [ "80", "443", "8080", "8190" ] + source_address_prefixes = [ "10.0.0.0/8", "192.168.0.0/16" ] + destination_address_prefixes = [ "172.16.0.0/20", "8.8.8.8" ] + resource_group_name = "${azurerm_resource_group.test1.name}" + network_security_group_name = "${azurerm_network_security_group.test1.name}" +} +`, rInt, location) +} diff --git a/website/docs/r/network_security_rule.html.markdown b/website/docs/r/network_security_rule.html.markdown index aaddb9930423..ca66264b5419 100644 --- a/website/docs/r/network_security_rule.html.markdown +++ b/website/docs/r/network_security_rule.html.markdown @@ -58,13 +58,21 @@ The following arguments are supported: * `protocol` - (Required) Network protocol this rule applies to. Possible values include `Tcp`, `Udp` or `*` (which matches both). -* `source_port_range` - (Required) Source Port or Range. Integer or range between `0` and `65535` or `*` to match any. +* `source_port_range` - (Optional) Source Port or Range. Integer or range between `0` and `65535` or `*` to match any. This is required if `source_port_ranges` is not specified. -* `destination_port_range` - (Required) Destination Port or Range. Integer or range between `0` and `65535` or `*` to match any. +* `source_port_ranges` - (Optional) List of source ports or port ranges. This is required if `source_port_range` is not specified. -* `source_address_prefix` - (Required) CIDR or source IP range or * to match any IP. Tags such as ‘VirtualNetwork’, ‘AzureLoadBalancer’ and ‘Internet’ can also be used. +* `destination_port_range` - (Optional) Destination Port or Range. Integer or range between `0` and `65535` or `*` to match any. This is required if `destination_port_ranges` is not specified. -* `destination_address_prefix` - (Required) CIDR or destination IP range or * to match any IP. Tags such as ‘VirtualNetwork’, ‘AzureLoadBalancer’ and ‘Internet’ can also be used. +* `destination_port_ranges` - (Optional) List of destination ports or port ranges. This is required if `destination_port_range` is not specified. + +* `source_address_prefix` - (Optional) CIDR or source IP range or * to match any IP. Tags such as ‘VirtualNetwork’, ‘AzureLoadBalancer’ and ‘Internet’ can also be used. This is required if `source_address_prefixes` is not specified. + +* `source_address_prefixes` - (Optional) List of source address prefixes. Tags may not be used. This is required if `source_address_prefix` is not specified. + +* `destination_address_prefix` - (Optional) CIDR or destination IP range or * to match any IP. Tags such as ‘VirtualNetwork’, ‘AzureLoadBalancer’ and ‘Internet’ can also be used. This is required if `destination_address_prefixes` is not specified. + +* `destination_address_prefixes` - (Optional) List of destination address prefixes. Tags may not be used. This is required if `destination_address_prefix` is not specified. * `access` - (Required) Specifies whether network traffic is allowed or denied. Possible values are `Allow` and `Deny`.