From ce5e5b467b607719456a3a9342e3094b4b9437b9 Mon Sep 17 00:00:00 2001 From: kt Date: Mon, 16 Sep 2019 13:58:47 -0700 Subject: [PATCH 1/7] eventhub namespace firewall initial commit --- azurerm/resource_arm_eventhub_namespace.go | 197 ++++++++++++++++++++- 1 file changed, 189 insertions(+), 8 deletions(-) diff --git a/azurerm/resource_arm_eventhub_namespace.go b/azurerm/resource_arm_eventhub_namespace.go index 667fca46d84d..a09c706d8b5a 100644 --- a/azurerm/resource_arm_eventhub_namespace.go +++ b/azurerm/resource_arm_eventhub_namespace.go @@ -83,6 +83,66 @@ func resourceArmEventHubNamespace() *schema.Resource { ValidateFunc: validation.IntBetween(0, 20), }, + "network_rulesets": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + + "default_action": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(eventhub.Allow), + string(eventhub.Deny), + }, false), + }, + + "virtual_network_rule": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "subnet_id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: azure.ValidateResourceID, + }, + + "ignore_missing_virtual_network_service_endpoint": { + Type: schema.TypeBool, + Optional: true, + }, + }, + }, + }, + + "ip_rule": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip_mask": { + Type: schema.TypeString, + Required: true, + }, + + "default_action": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + string(eventhub.NetworkRuleIPActionAllow), + }, false), + }, + }, + }, + }, + }, + }, + }, + "default_primary_connection_string": { Type: schema.TypeString, Computed: true, @@ -178,6 +238,13 @@ func resourceArmEventHubNamespaceCreateUpdate(d *schema.ResourceData, meta inter d.SetId(*read.ID) + rulesets := eventhub.NetworkRuleSet{ + NetworkRuleSetProperties: expandEventHubNamespaceNetworkRuleset(d.Get("network_rulesets").([]interface{})), + } + if _, err := client.CreateOrUpdateNetworkRuleSet(ctx, resGroup, name, rulesets); err != nil { + return fmt.Errorf("Error setting network ruleset properties for EventHub Namespace %q (resource group %q): %v", name, resGroup, err) + } + return resourceArmEventHubNamespaceRead(d, meta) } @@ -207,8 +274,25 @@ func resourceArmEventHubNamespaceRead(d *schema.ResourceData, meta interface{}) d.Set("location", azure.NormalizeLocation(*location)) } - d.Set("sku", string(resp.Sku.Name)) - d.Set("capacity", resp.Sku.Capacity) + if sku := resp.Sku; sku != nil { + d.Set("sku", string(sku.Name)) + d.Set("capacity", sku.Capacity) + } + + if props := resp.EHNamespaceProperties; props != nil { + d.Set("auto_inflate_enabled", props.IsAutoInflateEnabled) + d.Set("kafka_enabled", props.KafkaEnabled) + d.Set("maximum_throughput_units", int(*props.MaximumThroughputUnits)) + } + + ruleset, err := client.GetNetworkRuleSet(ctx, resGroup, name) + if err != nil { + return fmt.Errorf("Error making Read request on EventHub Namespace %q Network Ruleset: %+v", name, err) + } + + if err := d.Set("network_rulesets", flattenEventHubNamespaceNetworkRuleset(ruleset)); err != nil { + return fmt.Errorf("Error setting `network_ruleset` for Evenhub Namespace %s: %v", name, err) + } keys, err := client.ListKeys(ctx, resGroup, name, eventHubNamespaceDefaultAuthorizationRule) if err != nil { @@ -220,12 +304,6 @@ func resourceArmEventHubNamespaceRead(d *schema.ResourceData, meta interface{}) d.Set("default_secondary_key", keys.SecondaryKey) } - if props := resp.EHNamespaceProperties; props != nil { - d.Set("auto_inflate_enabled", props.IsAutoInflateEnabled) - d.Set("kafka_enabled", props.KafkaEnabled) - d.Set("maximum_throughput_units", int(*props.MaximumThroughputUnits)) - } - return tags.FlattenAndSet(d, resp.Tags) } @@ -283,3 +361,106 @@ func eventHubNamespaceStateStatusCodeRefreshFunc(ctx context.Context, client *ev return res, strconv.Itoa(res.StatusCode), nil } } + +func expandEventHubNamespaceNetworkRuleset(input []interface{}) *eventhub.NetworkRuleSetProperties { + if len(input) == 0 { + return nil + } + + block := input[0].(map[string]interface{}) + + ruleset := eventhub.NetworkRuleSetProperties{ + DefaultAction: eventhub.DefaultAction(block["default_action"].(string)), + } + + if v, ok := block["virtual_network_rule"].([]interface{}); ok { + if len(v) > 0 { + + var rules []eventhub.NWRuleSetVirtualNetworkRules + for _, r := range v { + rblock := r.(map[string]interface{}) + rules = append(rules, eventhub.NWRuleSetVirtualNetworkRules{ + Subnet: &eventhub.Subnet{ + ID: utils.String(rblock["subnet_id"].(string)), + }, + IgnoreMissingVnetServiceEndpoint: utils.Bool(rblock["ignore_missing_virtual_network_service_endpoint"].(bool)), + }) + } + + ruleset.VirtualNetworkRules = &rules + } + } + + if v, ok := block["ip_rule"].([]interface{}); ok { + if len(v) > 0 { + + var rules []eventhub.NWRuleSetIPRules + for _, r := range v { + rblock := r.(map[string]interface{}) + rules = append(rules, eventhub.NWRuleSetIPRules{ + IPMask: utils.String(rblock["subnet_id"].(string)), + Action: eventhub.NetworkRuleIPAction(rblock["action"].(bool)), + }) + } + + ruleset.IPRules = &rules + } + } + + return &ruleset +} + +func flattenEventHubNamespaceNetworkRuleset(ruleset eventhub.NetworkRuleSet) []interface{} { + if ruleset.NetworkRuleSetProperties == nil { + return nil + } + + results := make([]interface{}, 0) + if description != nil { + output := make(map[string]interface{}) + + if enabled := description.Enabled; enabled != nil { + output["enabled"] = *enabled + } + + if skipEmptyArchives := description.SkipEmptyArchives; skipEmptyArchives != nil { + output["skip_empty_archives"] = *skipEmptyArchives + } + + output["encoding"] = string(description.Encoding) + + if interval := description.IntervalInSeconds; interval != nil { + output["interval_in_seconds"] = *interval + } + + if size := description.SizeLimitInBytes; size != nil { + output["size_limit_in_bytes"] = *size + } + + if destination := description.Destination; destination != nil { + destinationOutput := make(map[string]interface{}) + + if name := destination.Name; name != nil { + destinationOutput["name"] = *name + } + + if props := destination.DestinationProperties; props != nil { + if archiveNameFormat := props.ArchiveNameFormat; archiveNameFormat != nil { + destinationOutput["archive_name_format"] = *archiveNameFormat + } + if blobContainerName := props.BlobContainer; blobContainerName != nil { + destinationOutput["blob_container_name"] = *blobContainerName + } + if storageAccountId := props.StorageAccountResourceID; storageAccountId != nil { + destinationOutput["storage_account_id"] = *storageAccountId + } + } + + output["destination"] = []interface{}{destinationOutput} + } + + results = append(results, output) + } + + return results +} From 16826cf0531822b5b753d2c4c39e98dc38efc02a Mon Sep 17 00:00:00 2001 From: kt Date: Mon, 23 Sep 2019 13:29:24 -0700 Subject: [PATCH 2/7] finish network_rulesets impl --- azurerm/resource_arm_eventhub_namespace.go | 85 +++++++------ .../resource_arm_eventhub_namespace_test.go | 112 ++++++++++++++++++ .../docs/r/eventhub_namespace.html.markdown | 32 ++++- 3 files changed, 182 insertions(+), 47 deletions(-) diff --git a/azurerm/resource_arm_eventhub_namespace.go b/azurerm/resource_arm_eventhub_namespace.go index a09c706d8b5a..f0866963bcfd 100644 --- a/azurerm/resource_arm_eventhub_namespace.go +++ b/azurerm/resource_arm_eventhub_namespace.go @@ -101,13 +101,17 @@ func resourceArmEventHubNamespace() *schema.Resource { "virtual_network_rule": { Type: schema.TypeList, - Required: true, + Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ + + // the API returns the subnet ID's resource group name in lowercase + // https://github.com/Azure/azure-sdk-for-go/issues/5855 "subnet_id": { - Type: schema.TypeString, - Required: true, - ValidateFunc: azure.ValidateResourceID, + Type: schema.TypeString, + Required: true, + ValidateFunc: azure.ValidateResourceID, + DiffSuppressFunc: suppress.CaseDifference, }, "ignore_missing_virtual_network_service_endpoint": { @@ -120,7 +124,7 @@ func resourceArmEventHubNamespace() *schema.Resource { "ip_rule": { Type: schema.TypeList, - Required: true, + Optional: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -129,9 +133,10 @@ func resourceArmEventHubNamespace() *schema.Resource { Required: true, }, - "default_action": { + "action": { Type: schema.TypeString, Optional: true, + Default: string(eventhub.NetworkRuleIPActionAllow), ValidateFunc: validation.StringInSlice([]string{ string(eventhub.NetworkRuleIPActionAllow), }, false), @@ -398,8 +403,8 @@ func expandEventHubNamespaceNetworkRuleset(input []interface{}) *eventhub.Networ for _, r := range v { rblock := r.(map[string]interface{}) rules = append(rules, eventhub.NWRuleSetIPRules{ - IPMask: utils.String(rblock["subnet_id"].(string)), - Action: eventhub.NetworkRuleIPAction(rblock["action"].(bool)), + IPMask: utils.String(rblock["ip_mask"].(string)), + Action: eventhub.NetworkRuleIPAction(rblock["action"].(string)), }) } @@ -415,52 +420,42 @@ func flattenEventHubNamespaceNetworkRuleset(ruleset eventhub.NetworkRuleSet) []i return nil } - results := make([]interface{}, 0) - if description != nil { - output := make(map[string]interface{}) - - if enabled := description.Enabled; enabled != nil { - output["enabled"] = *enabled - } + vnetBlocks := make([]interface{}, 0) + if vnetRules := ruleset.NetworkRuleSetProperties.VirtualNetworkRules; vnetRules != nil { + for _, vnetRule := range *vnetRules { + block := make(map[string]interface{}) - if skipEmptyArchives := description.SkipEmptyArchives; skipEmptyArchives != nil { - output["skip_empty_archives"] = *skipEmptyArchives - } - - output["encoding"] = string(description.Encoding) + if s := vnetRule.Subnet; s != nil { + if v := s.ID; v != nil { + block["subnet_id"] = *v + } + } - if interval := description.IntervalInSeconds; interval != nil { - output["interval_in_seconds"] = *interval - } + if v := vnetRule.IgnoreMissingVnetServiceEndpoint; v != nil { + block["ignore_missing_virtual_network_service_endpoint"] = *v + } - if size := description.SizeLimitInBytes; size != nil { - output["size_limit_in_bytes"] = *size + vnetBlocks = append(vnetBlocks, block) } + } + ipBlocks := make([]interface{}, 0) + if ipRules := ruleset.NetworkRuleSetProperties.IPRules; ipRules != nil { + for _, ipRule := range *ipRules { + block := make(map[string]interface{}) - if destination := description.Destination; destination != nil { - destinationOutput := make(map[string]interface{}) + block["action"] = string(ipRule.Action) - if name := destination.Name; name != nil { - destinationOutput["name"] = *name + if v := ipRule.IPMask; v != nil { + block["ip_mask"] = *v } - if props := destination.DestinationProperties; props != nil { - if archiveNameFormat := props.ArchiveNameFormat; archiveNameFormat != nil { - destinationOutput["archive_name_format"] = *archiveNameFormat - } - if blobContainerName := props.BlobContainer; blobContainerName != nil { - destinationOutput["blob_container_name"] = *blobContainerName - } - if storageAccountId := props.StorageAccountResourceID; storageAccountId != nil { - destinationOutput["storage_account_id"] = *storageAccountId - } - } - - output["destination"] = []interface{}{destinationOutput} + ipBlocks = append(ipBlocks, block) } - - results = append(results, output) } - return results + return []interface{}{map[string]interface{}{ + "default_action": string(ruleset.DefaultAction), + "virtual_network_rule": vnetBlocks, + "ip_rule": ipBlocks, + }} } diff --git a/azurerm/resource_arm_eventhub_namespace_test.go b/azurerm/resource_arm_eventhub_namespace_test.go index a730c9226f1c..6fe7465f7a3b 100644 --- a/azurerm/resource_arm_eventhub_namespace_test.go +++ b/azurerm/resource_arm_eventhub_namespace_test.go @@ -115,6 +115,54 @@ func TestAccAzureRMEventHubNamespace_standard(t *testing.T) { }) } +func TestAccAzureRMEventHubNamespace_networkrule_iprule(t *testing.T) { + resourceName := "azurerm_eventhub_namespace.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMEventHubNamespaceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMEventHubNamespace_networkrule_iprule(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMEventHubNamespaceExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMEventHubNamespace_networkrule_vnet(t *testing.T) { + resourceName := "azurerm_eventhub_namespace.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMEventHubNamespaceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMEventHubNamespace_networkrule_vnet(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMEventHubNamespaceExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAzureRMEventHubNamespace_readDefaultKeys(t *testing.T) { resourceName := "azurerm_eventhub_namespace.test" ri := tf.AccRandTimeInt() @@ -465,6 +513,70 @@ resource "azurerm_eventhub_namespace" "test" { `, rInt, location, rInt) } +func testAccAzureRMEventHubNamespace_networkrule_iprule(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_eventhub_namespace" "test" { + name = "acctesteventhubnamespace-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" + capacity = "2" + + network_rulesets { + default_action = "Deny" + ip_rule { + ip_mask = "10.0.0.0/16" + } + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMEventHubNamespace_networkrule_vnet(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%[1]d" + location = "%[2]s" +} + +resource "azurerm_virtual_network" "test" { + name = "acctvn-%[1]d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctsub-%[1]d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_eventhub_namespace" "test" { + name = "acctesteventhubnamespace-%[1]d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" + capacity = "2" + + network_rulesets { + default_action = "Deny" + virtual_network_rule { + subnet_id = "${azurerm_subnet.test.id}" + + ignore_missing_virtual_network_service_endpoint = true + } + } +} +`, rInt, location) +} + func testAccAzureRMEventHubNamespaceNonStandardCasing(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { diff --git a/website/docs/r/eventhub_namespace.html.markdown b/website/docs/r/eventhub_namespace.html.markdown index 5e43a695414d..e81a2810dbd8 100644 --- a/website/docs/r/eventhub_namespace.html.markdown +++ b/website/docs/r/eventhub_namespace.html.markdown @@ -43,16 +43,44 @@ The following arguments are supported: * `sku` - (Required) Defines which tier to use. Valid options are `Basic` and `Standard`. -* `capacity` - (Optional) Specifies the Capacity / Throughput Units for a `Standard` SKU namespace. Valid values range from 1 - 20. +* `capacity` - (Optional) Specifies the Capacity / Throughput Units for a `Standard` SKU namespace. Valid values range from `1` - `20`. * `auto_inflate_enabled` - (Optional) Is Auto Inflate enabled for the EventHub Namespace? -* `maximum_throughput_units` - (Optional) Specifies the maximum number of throughput units when Auto Inflate is Enabled. Valid values range from 1 - 20. +* `maximum_throughput_units` - (Optional) Specifies the maximum number of throughput units when Auto Inflate is Enabled. Valid values range from `1` - `20`. * `kafka_enabled` - (Optional) Is Kafka enabled for the EventHub Namespace? Defaults to `false`. Changing this forces a new resource to be created. * `tags` - (Optional) A mapping of tags to assign to the resource. +* `network_rulesets` - (Optional) A `network_rulesets` block as defined below. + +--- + +A `network_rulesets` block supports the following: + +* `default_action` - (Required) The default action to take when a rule is not matched. Possible values are `Allow` and `Deny`. + +* `virtual_network_rule` - (Optional) One or more `network_rulesets` blocks as defined below. + +* `ip_rule` - (Optional) One or more `network_rulesets` blocks as defined below. + +--- + +A `virtual_network_rule` block supports the following: + +* `subnet_id` - (Required) The id of the subnet to match on. + +* `ignore_missing_virtual_network_service_endpoint` - (Optional) Are missing virtual network service endpoints ignored? Defaults to `false`. + +--- + +A `ip_rule` block supports the following: + +* `ip_mask` - (Required) The ip mask to match on. + +* `action` - (Optional) The action to take when the rule is matched. Possible values are `Allow`. + ## Attributes Reference The following attributes are exported: From 48da0501345849a1d567e680cf88b5f5e8501ed4 Mon Sep 17 00:00:00 2001 From: kt Date: Mon, 23 Sep 2019 13:36:40 -0700 Subject: [PATCH 3/7] spacing --- website/docs/r/eventhub_namespace.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/eventhub_namespace.html.markdown b/website/docs/r/eventhub_namespace.html.markdown index e81a2810dbd8..cd8e90adbda6 100644 --- a/website/docs/r/eventhub_namespace.html.markdown +++ b/website/docs/r/eventhub_namespace.html.markdown @@ -66,7 +66,7 @@ A `network_rulesets` block supports the following: * `ip_rule` - (Optional) One or more `network_rulesets` blocks as defined below. --- - + A `virtual_network_rule` block supports the following: * `subnet_id` - (Required) The id of the subnet to match on. From 4e5a2fa20b44f7a63ad6a0d77d494e2f8ac18809 Mon Sep 17 00:00:00 2001 From: kt Date: Tue, 24 Sep 2019 16:47:41 -0700 Subject: [PATCH 4/7] only update rulesets if they have been set --- azurerm/resource_arm_eventhub_namespace.go | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/azurerm/resource_arm_eventhub_namespace.go b/azurerm/resource_arm_eventhub_namespace.go index f0866963bcfd..48269967d097 100644 --- a/azurerm/resource_arm_eventhub_namespace.go +++ b/azurerm/resource_arm_eventhub_namespace.go @@ -243,12 +243,15 @@ func resourceArmEventHubNamespaceCreateUpdate(d *schema.ResourceData, meta inter d.SetId(*read.ID) - rulesets := eventhub.NetworkRuleSet{ - NetworkRuleSetProperties: expandEventHubNamespaceNetworkRuleset(d.Get("network_rulesets").([]interface{})), - } - if _, err := client.CreateOrUpdateNetworkRuleSet(ctx, resGroup, name, rulesets); err != nil { - return fmt.Errorf("Error setting network ruleset properties for EventHub Namespace %q (resource group %q): %v", name, resGroup, err) - } + ruleSets, hasRuleSets := d.GetOk("network_rulesets") + if hasRuleSets { + rulesets := eventhub.NetworkRuleSet{ + NetworkRuleSetProperties: expandEventHubNamespaceNetworkRuleset(ruleSets.([]interface{})), + } + if _, err := client.CreateOrUpdateNetworkRuleSet(ctx, resGroup, name, rulesets); err != nil { + return fmt.Errorf("Error setting network ruleset properties for EventHub Namespace %q (resource group %q): %v", name, resGroup, err) + } + }{} return resourceArmEventHubNamespaceRead(d, meta) } From 13670f69ccdb6d7d1dadf83ace1c6f29aab43dc9 Mon Sep 17 00:00:00 2001 From: kt Date: Tue, 24 Sep 2019 16:47:57 -0700 Subject: [PATCH 5/7] fix typo --- azurerm/resource_arm_eventhub_namespace.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azurerm/resource_arm_eventhub_namespace.go b/azurerm/resource_arm_eventhub_namespace.go index 48269967d097..e5663b8972d4 100644 --- a/azurerm/resource_arm_eventhub_namespace.go +++ b/azurerm/resource_arm_eventhub_namespace.go @@ -251,7 +251,7 @@ func resourceArmEventHubNamespaceCreateUpdate(d *schema.ResourceData, meta inter if _, err := client.CreateOrUpdateNetworkRuleSet(ctx, resGroup, name, rulesets); err != nil { return fmt.Errorf("Error setting network ruleset properties for EventHub Namespace %q (resource group %q): %v", name, resGroup, err) } - }{} + } return resourceArmEventHubNamespaceRead(d, meta) } From 07a23fa7c3776bce0ea1dc856d39a314d09b27bd Mon Sep 17 00:00:00 2001 From: kt Date: Tue, 24 Sep 2019 18:44:51 -0700 Subject: [PATCH 6/7] make ruleset as computed --- azurerm/resource_arm_eventhub_namespace.go | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/azurerm/resource_arm_eventhub_namespace.go b/azurerm/resource_arm_eventhub_namespace.go index e5663b8972d4..5f28d49f0a37 100644 --- a/azurerm/resource_arm_eventhub_namespace.go +++ b/azurerm/resource_arm_eventhub_namespace.go @@ -84,9 +84,11 @@ func resourceArmEventHubNamespace() *schema.Resource { }, "network_rulesets": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Computed: true, + ConfigMode: schema.SchemaConfigModeAttr, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -100,8 +102,9 @@ func resourceArmEventHubNamespace() *schema.Resource { }, "virtual_network_rule": { - Type: schema.TypeList, - Optional: true, + Type: schema.TypeList, + Optional: true, + ConfigMode: schema.SchemaConfigModeAttr, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -123,9 +126,10 @@ func resourceArmEventHubNamespace() *schema.Resource { }, "ip_rule": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + ConfigMode: schema.SchemaConfigModeAttr, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "ip_mask": { From e030c41f8b8f065f89a009dfc023afd759e0a959 Mon Sep 17 00:00:00 2001 From: kt Date: Wed, 25 Sep 2019 09:30:53 -0700 Subject: [PATCH 7/7] don't update rulesets if sku is basic --- azurerm/resource_arm_eventhub_namespace.go | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/azurerm/resource_arm_eventhub_namespace.go b/azurerm/resource_arm_eventhub_namespace.go index 5f28d49f0a37..ae2892d6e781 100644 --- a/azurerm/resource_arm_eventhub_namespace.go +++ b/azurerm/resource_arm_eventhub_namespace.go @@ -252,8 +252,19 @@ func resourceArmEventHubNamespaceCreateUpdate(d *schema.ResourceData, meta inter rulesets := eventhub.NetworkRuleSet{ NetworkRuleSetProperties: expandEventHubNamespaceNetworkRuleset(ruleSets.([]interface{})), } - if _, err := client.CreateOrUpdateNetworkRuleSet(ctx, resGroup, name, rulesets); err != nil { - return fmt.Errorf("Error setting network ruleset properties for EventHub Namespace %q (resource group %q): %v", name, resGroup, err) + + // cannot use network rulesets with the basic SKU + if parameters.Sku.Name != eventhub.Basic { + if _, err := client.CreateOrUpdateNetworkRuleSet(ctx, resGroup, name, rulesets); err != nil { + return fmt.Errorf("Error setting network ruleset properties for EventHub Namespace %q (resource group %q): %v", name, resGroup, err) + } + } else { + // so if the user has specified the non default rule sets throw a validation error + if rulesets.DefaultAction != eventhub.Deny || + (rulesets.IPRules != nil && len(*rulesets.IPRules) > 0) || + (rulesets.VirtualNetworkRules != nil && len(*rulesets.VirtualNetworkRules) > 0) { + return fmt.Errorf("network_rulesets cannot be used when the SKU is basic") + } } }