From ac8565b20c99db9d5fb7258b0c19b04548fe9932 Mon Sep 17 00:00:00 2001 From: neil-yechenwei Date: Thu, 23 Apr 2020 15:43:37 +0800 Subject: [PATCH 1/7] Add support for hostnames of application gateway --- .../resource_arm_application_gateway.go | 17 +++ .../resource_arm_application_gateway_test.go | 100 ++++++++++++++++++ .../docs/r/application_gateway.html.markdown | 2 + 3 files changed, 119 insertions(+) diff --git a/azurerm/internal/services/network/resource_arm_application_gateway.go b/azurerm/internal/services/network/resource_arm_application_gateway.go index 341126d93371..e586d99eaf7f 100644 --- a/azurerm/internal/services/network/resource_arm_application_gateway.go +++ b/azurerm/internal/services/network/resource_arm_application_gateway.go @@ -401,6 +401,15 @@ func resourceArmApplicationGateway() *schema.Resource { Optional: true, }, + "host_names": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringIsNotEmpty, + }, + }, + "ssl_certificate_name": { Type: schema.TypeString, Optional: true, @@ -2233,6 +2242,10 @@ func expandApplicationGatewayHTTPListeners(d *schema.ResourceData, gatewayID str listener.ApplicationGatewayHTTPListenerPropertiesFormat.HostName = &host } + if hosts, ok := v["host_names"]; ok { + listener.ApplicationGatewayHTTPListenerPropertiesFormat.Hostnames = utils.ExpandStringSlice(hosts.(*schema.Set).List()) + } + if sslCertName := v["ssl_certificate_name"].(string); sslCertName != "" { certID := fmt.Sprintf("%s/sslCertificates/%s", gatewayID, sslCertName) listener.ApplicationGatewayHTTPListenerPropertiesFormat.SslCertificate = &network.SubResource{ @@ -2292,6 +2305,10 @@ func flattenApplicationGatewayHTTPListeners(input *[]network.ApplicationGatewayH output["host_name"] = *hostname } + if hostnames := props.Hostnames; hostnames != nil { + output["host_names"] = utils.FlattenStringSlice(hostnames) + } + output["protocol"] = string(props.Protocol) if cert := props.SslCertificate; cert != nil { diff --git a/azurerm/internal/services/network/tests/resource_arm_application_gateway_test.go b/azurerm/internal/services/network/tests/resource_arm_application_gateway_test.go index 6214bb86039b..8cae01c709f4 100644 --- a/azurerm/internal/services/network/tests/resource_arm_application_gateway_test.go +++ b/azurerm/internal/services/network/tests/resource_arm_application_gateway_test.go @@ -503,6 +503,25 @@ func TestAccAzureRMApplicationGateway_backendHttpSettingsHostName(t *testing.T) }) } +func TestAccAzureRMApplicationGateway_withHttpListenerHostNames(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_application_gateway", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMApplicationGatewayDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApplicationGateway_withHttpListenerHostNames(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationGatewayExists(data.ResourceName), + ), + }, + data.ImportStep(), + }, + }) +} + func TestAccAzureRMApplicationGateway_backendHttpSettingsHostNameAndPick(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_application_gateway", "test") hostName := "example.com" @@ -2886,6 +2905,87 @@ resource "azurerm_application_gateway" "test" { `, template, data.RandomInteger, hostName, pick) } +func testAccAzureRMApplicationGateway_withHttpListenerHostNames(data acceptance.TestData) string { + template := testAccAzureRMApplicationGateway_template(data) + return fmt.Sprintf(` +%s + +resource "azurerm_public_ip" "test2" { + name = "acctest-pubip2-%d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + allocation_method = "Static" + sku = "Standard" + domain_name_label = "testdns-123" +} + +# since these variables are re-used - a locals block makes this more maintainable +locals { + backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" + frontend_port_name = "${azurerm_virtual_network.test.name}-feport" + frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" + http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" + listener_name = "${azurerm_virtual_network.test.name}-httplstn" + request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" +} + +resource "azurerm_application_gateway" "test" { + name = "acctestag-%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + + sku { + name = "Standard_v2" + tier = "Standard_v2" + capacity = 2 + } + + gateway_ip_configuration { + name = "my-gateway-ip-configuration" + subnet_id = azurerm_subnet.test.id + } + + frontend_port { + name = local.frontend_port_name + port = 80 + } + + frontend_ip_configuration { + name = local.frontend_ip_configuration_name + public_ip_address_id = azurerm_public_ip.test2.id + } + + backend_address_pool { + name = local.backend_address_pool_name + } + + backend_http_settings { + name = local.http_setting_name + cookie_based_affinity = "Disabled" + port = 80 + protocol = "Http" + request_timeout = 1 + } + + http_listener { + name = local.listener_name + frontend_ip_configuration_name = local.frontend_ip_configuration_name + frontend_port_name = local.frontend_port_name + protocol = "Http" + host_names = ["testdns-123"] + } + + request_routing_rule { + name = local.request_routing_rule_name + rule_type = "Basic" + http_listener_name = local.listener_name + backend_address_pool_name = local.backend_address_pool_name + backend_http_settings_name = local.http_setting_name + } +} +`, template, data.RandomInteger, data.RandomInteger) +} + func testAccAzureRMApplicationGateway_settingsPickHostNameFromBackendAddress(data acceptance.TestData) string { template := testAccAzureRMApplicationGateway_template(data) return fmt.Sprintf(` diff --git a/website/docs/r/application_gateway.html.markdown b/website/docs/r/application_gateway.html.markdown index 2c0b894f5754..8da607935b29 100644 --- a/website/docs/r/application_gateway.html.markdown +++ b/website/docs/r/application_gateway.html.markdown @@ -288,6 +288,8 @@ A `http_listener` block supports the following: * `host_name` - (Optional) The Hostname which should be used for this HTTP Listener. +* `host_names` - (Optional) A set of host names which allow special wildcard characters for this HTTP Listener. + * `protocol` - (Required) The Protocol to use for this HTTP Listener. Possible values are `Http` and `Https`. * `require_sni` - (Optional) Should Server Name Indication be Required? Defaults to `false`. From b0884c0999059824e55ade77603e0b35546e9760 Mon Sep 17 00:00:00 2001 From: neil-yechenwei Date: Thu, 23 Apr 2020 18:00:15 +0800 Subject: [PATCH 2/7] Update code --- website/docs/r/application_gateway.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/application_gateway.html.markdown b/website/docs/r/application_gateway.html.markdown index 8da607935b29..a9607217a15c 100644 --- a/website/docs/r/application_gateway.html.markdown +++ b/website/docs/r/application_gateway.html.markdown @@ -288,7 +288,7 @@ A `http_listener` block supports the following: * `host_name` - (Optional) The Hostname which should be used for this HTTP Listener. -* `host_names` - (Optional) A set of host names which allow special wildcard characters for this HTTP Listener. +* `host_names` - (Optional) A list of Hostname(s) should be used for this HTTP Listener. It allows special wildcard characters. * `protocol` - (Required) The Protocol to use for this HTTP Listener. Possible values are `Http` and `Https`. From 30790dc8f672d13eb0d880dc3ba9fff0209ae518 Mon Sep 17 00:00:00 2001 From: neil-yechenwei Date: Fri, 24 Apr 2020 15:34:25 +0800 Subject: [PATCH 3/7] ... --- a | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 a diff --git a/a b/a new file mode 100644 index 000000000000..e69de29bb2d1 From 50a986bdf9c3047d101f94cd14289577970606a3 Mon Sep 17 00:00:00 2001 From: neil-yechenwei Date: Fri, 24 Apr 2020 15:34:45 +0800 Subject: [PATCH 4/7] ... --- a | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 a diff --git a/a b/a deleted file mode 100644 index e69de29bb2d1..000000000000 From fb9467c7282e3dd319a3455cdf6f1b1f2a0f91ac Mon Sep 17 00:00:00 2001 From: neil-yechenwei Date: Fri, 24 Apr 2020 16:22:51 +0800 Subject: [PATCH 5/7] Update code --- .../resource_arm_application_gateway.go | 24 ++++++++++++++----- .../docs/r/application_gateway.html.markdown | 2 +- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/azurerm/internal/services/network/resource_arm_application_gateway.go b/azurerm/internal/services/network/resource_arm_application_gateway.go index e586d99eaf7f..8ac686bb718b 100644 --- a/azurerm/internal/services/network/resource_arm_application_gateway.go +++ b/azurerm/internal/services/network/resource_arm_application_gateway.go @@ -1382,6 +1382,11 @@ func resourceArmApplicationGatewayCreateUpdate(d *schema.ResourceData, meta inte gatewayIPConfigurations, stopApplicationGateway := expandApplicationGatewayIPConfigurations(d) + httpListeners, err := expandApplicationGatewayHTTPListeners(d, gatewayID) + if err != nil { + return fmt.Errorf("fail to expand `http_listener`: %+v", err) + } + gateway := network.ApplicationGateway{ Location: utils.String(location), Zones: azure.ExpandZones(d.Get("zones").([]interface{})), @@ -1398,7 +1403,7 @@ func resourceArmApplicationGatewayCreateUpdate(d *schema.ResourceData, meta inte FrontendIPConfigurations: expandApplicationGatewayFrontendIPConfigurations(d), FrontendPorts: expandApplicationGatewayFrontendPorts(d), GatewayIPConfigurations: gatewayIPConfigurations, - HTTPListeners: expandApplicationGatewayHTTPListeners(d, gatewayID), + HTTPListeners: httpListeners, Probes: expandApplicationGatewayProbes(d), RequestRoutingRules: requestRoutingRules, RedirectConfigurations: redirectConfigurations, @@ -2205,7 +2210,7 @@ func flattenApplicationGatewaySslPolicy(input *network.ApplicationGatewaySslPoli return results } -func expandApplicationGatewayHTTPListeners(d *schema.ResourceData, gatewayID string) *[]network.ApplicationGatewayHTTPListener { +func expandApplicationGatewayHTTPListeners(d *schema.ResourceData, gatewayID string) (*[]network.ApplicationGatewayHTTPListener, error) { vs := d.Get("http_listener").([]interface{}) results := make([]network.ApplicationGatewayHTTPListener, 0) @@ -2238,12 +2243,19 @@ func expandApplicationGatewayHTTPListeners(d *schema.ResourceData, gatewayID str }, } - if host := v["host_name"].(string); host != "" { + host := v["host_name"].(string) + hosts := v["host_names"].(*schema.Set).List() + + if host != "" && len(hosts) > 0 { + return nil, fmt.Errorf("`host_name` and `host_names` cannot be specified together") + } + + if host != "" { listener.ApplicationGatewayHTTPListenerPropertiesFormat.HostName = &host } - if hosts, ok := v["host_names"]; ok { - listener.ApplicationGatewayHTTPListenerPropertiesFormat.Hostnames = utils.ExpandStringSlice(hosts.(*schema.Set).List()) + if len(hosts) > 0 { + listener.ApplicationGatewayHTTPListenerPropertiesFormat.Hostnames = utils.ExpandStringSlice(hosts) } if sslCertName := v["ssl_certificate_name"].(string); sslCertName != "" { @@ -2256,7 +2268,7 @@ func expandApplicationGatewayHTTPListeners(d *schema.ResourceData, gatewayID str results = append(results, listener) } - return &results + return &results, nil } func flattenApplicationGatewayHTTPListeners(input *[]network.ApplicationGatewayHTTPListener) ([]interface{}, error) { diff --git a/website/docs/r/application_gateway.html.markdown b/website/docs/r/application_gateway.html.markdown index a9607217a15c..b075c74c52fc 100644 --- a/website/docs/r/application_gateway.html.markdown +++ b/website/docs/r/application_gateway.html.markdown @@ -288,7 +288,7 @@ A `http_listener` block supports the following: * `host_name` - (Optional) The Hostname which should be used for this HTTP Listener. -* `host_names` - (Optional) A list of Hostname(s) should be used for this HTTP Listener. It allows special wildcard characters. +* `host_names` - (Optional) A list of Hostname(s) should be used for this HTTP Listener and cannot be specified with `host_name` together. It allows special wildcard characters. * `protocol` - (Required) The Protocol to use for this HTTP Listener. Possible values are `Http` and `Https`. From 85daf639142f02b48222f7bc61a0ea9721658535 Mon Sep 17 00:00:00 2001 From: neil-yechenwei Date: Sun, 26 Apr 2020 11:28:44 +0800 Subject: [PATCH 6/7] update code --- website/docs/r/application_gateway.html.markdown | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/website/docs/r/application_gateway.html.markdown b/website/docs/r/application_gateway.html.markdown index b075c74c52fc..e5ad7e2a42a0 100644 --- a/website/docs/r/application_gateway.html.markdown +++ b/website/docs/r/application_gateway.html.markdown @@ -288,7 +288,9 @@ A `http_listener` block supports the following: * `host_name` - (Optional) The Hostname which should be used for this HTTP Listener. -* `host_names` - (Optional) A list of Hostname(s) should be used for this HTTP Listener and cannot be specified with `host_name` together. It allows special wildcard characters. +* `host_names` - (Optional) A list of Hostname(s) should be used for this HTTP Listener. It allows special wildcard characters. + +-> **NOTE** `host_names` and `host_name` is mutually exclusive. * `protocol` - (Required) The Protocol to use for this HTTP Listener. Possible values are `Http` and `Https`. From dd92acc87877ec575b8156aea865dba4b56056b4 Mon Sep 17 00:00:00 2001 From: kt Date: Sun, 26 Apr 2020 09:14:35 -0700 Subject: [PATCH 7/7] Update application_gateway.html.markdown --- website/docs/r/application_gateway.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/application_gateway.html.markdown b/website/docs/r/application_gateway.html.markdown index e5ad7e2a42a0..5c6f4b5904a6 100644 --- a/website/docs/r/application_gateway.html.markdown +++ b/website/docs/r/application_gateway.html.markdown @@ -290,7 +290,7 @@ A `http_listener` block supports the following: * `host_names` - (Optional) A list of Hostname(s) should be used for this HTTP Listener. It allows special wildcard characters. --> **NOTE** `host_names` and `host_name` is mutually exclusive. +-> **NOTE** The `host_names` and `host_name` are mutually exclusive and cannot both be set. * `protocol` - (Required) The Protocol to use for this HTTP Listener. Possible values are `Http` and `Https`.