From a74004418fd740c8161a928e0e305327fe734fd0 Mon Sep 17 00:00:00 2001 From: "Till Markus (INST-CSS/BSV-OS)" Date: Sun, 5 May 2019 22:13:56 +0200 Subject: [PATCH] resource_arm_application_gateway: extend docs --- azurerm/resource_arm_application_gateway.go | 69 +++---- .../resource_arm_application_gateway_test.go | 176 ++++++++++++++---- .../docs/r/application_gateway.html.markdown | 24 ++- 3 files changed, 189 insertions(+), 80 deletions(-) diff --git a/azurerm/resource_arm_application_gateway.go b/azurerm/resource_arm_application_gateway.go index 6b334b3fed446..bf3a2f3df323c 100644 --- a/azurerm/resource_arm_application_gateway.go +++ b/azurerm/resource_arm_application_gateway.go @@ -624,7 +624,7 @@ func resourceArmApplicationGateway() *schema.Resource { }, }, - // TODO: @tombuildsstuff deprecate this in favour of a full `ssl_protocol` block in the future + // TODO: remove in 2.0 "disabled_ssl_protocols": { Type: schema.TypeList, Optional: true, @@ -644,6 +644,7 @@ func resourceArmApplicationGateway() *schema.Resource { "ssl_policy": { Type: schema.TypeList, Optional: true, + Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "disabled_protocols": { @@ -651,13 +652,12 @@ func resourceArmApplicationGateway() *schema.Resource { Optional: true, Computed: true, Elem: &schema.Schema{ - Type: schema.TypeString, - DiffSuppressFunc: suppress.CaseDifference, + Type: schema.TypeString, ValidateFunc: validation.StringInSlice([]string{ string(network.TLSv10), string(network.TLSv11), string(network.TLSv12), - }, true), + }, false), }, }, @@ -669,7 +669,7 @@ func resourceArmApplicationGateway() *schema.Resource { ValidateFunc: validation.StringInSlice([]string{ string(network.Custom), string(network.Predefined), - }, true), + }, false), }, }, @@ -682,21 +682,19 @@ func resourceArmApplicationGateway() *schema.Resource { Type: schema.TypeList, Optional: true, Elem: &schema.Schema{ - Type: schema.TypeString, - DiffSuppressFunc: suppress.CaseDifference, - ValidateFunc: validation.StringInSlice(possibleArmApplicationGatewaySslCipherSuiteValues(), true), + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice(possibleArmApplicationGatewaySslCipherSuiteValues(), false), }, }, "min_protocol_version": { - Type: schema.TypeString, - Optional: true, - DiffSuppressFunc: suppress.CaseDifference, + Type: schema.TypeString, + Optional: true, ValidateFunc: validation.StringInSlice([]string{ string(network.TLSv10), string(network.TLSv11), string(network.TLSv12), - }, true), + }, false), }, }, }, @@ -1637,40 +1635,39 @@ func flattenApplicationGatewayConnectionDraining(input *network.ApplicationGatew func expandApplicationGatewaySslPolicy(d *schema.ResourceData) *network.ApplicationGatewaySslPolicy { policy := network.ApplicationGatewaySslPolicy{} + disabledSSLPolicies := make([]network.ApplicationGatewaySslProtocol, 0) + vs := d.Get("ssl_policy").([]interface{}) - if len(vs) == 0 { - return &policy + vsdsp := d.Get("disabled_ssl_protocols").([]interface{}) + + if len(vsdsp) == 0 && len(vs) == 0 { + policy = network.ApplicationGatewaySslPolicy{ + DisabledSslProtocols: &disabledSSLPolicies, + } } - v := vs[0].(map[string]interface{}) - disabledSSLPolicies := make([]network.ApplicationGatewaySslProtocol, 0) - for _, policy := range v["disabled_protocols"].([]interface{}) { + for _, policy := range vsdsp { disabledSSLPolicies = append(disabledSSLPolicies, network.ApplicationGatewaySslProtocol(policy.(string))) } - if len(disabledSSLPolicies) == 0 { - for _, policy := range d.Get("disabled_ssl_protocols").([]interface{}) { - disabledSSLPolicies = append(disabledSSLPolicies, network.ApplicationGatewaySslProtocol(policy.(string))) - } - } - if len(disabledSSLPolicies) > 0 { - policy = network.ApplicationGatewaySslPolicy{ - DisabledSslProtocols: &disabledSSLPolicies, - } - } else { + if len(vs) > 0 { + v := vs[0].(map[string]interface{}) policyType := network.ApplicationGatewaySslPolicyType(v["policy_type"].(string)) + for _, policy := range v["disabled_protocols"].([]interface{}) { + disabledSSLPolicies = append(disabledSSLPolicies, network.ApplicationGatewaySslProtocol(policy.(string))) + } + if policyType == network.Predefined { policyName := network.ApplicationGatewaySslPolicyName(v["policy_name"].(string)) - policy = network.ApplicationGatewaySslPolicy{ PolicyType: policyType, PolicyName: policyName, } } else if policyType == network.Custom { minProtocolVersion := network.ApplicationGatewaySslProtocol(v["min_protocol_version"].(string)) - cipherSuites := make([]network.ApplicationGatewaySslCipherSuite, 0) + for _, cipherSuite := range v["cipher_suites"].([]interface{}) { cipherSuites = append(cipherSuites, network.ApplicationGatewaySslCipherSuite(cipherSuite.(string))) } @@ -1683,6 +1680,12 @@ func expandApplicationGatewaySslPolicy(d *schema.ResourceData) *network.Applicat } } + if len(disabledSSLPolicies) > 0 { + policy = network.ApplicationGatewaySslPolicy{ + DisabledSslProtocols: &disabledSSLPolicies, + } + } + return &policy } @@ -1698,21 +1701,21 @@ func flattenApplicationGatewaySslPolicy(input *network.ApplicationGatewaySslPoli output["policy_type"] = input.PolicyType output["min_protocol_version"] = input.MinProtocolVersion + cipherSuites := make([]interface{}, 0) if input.CipherSuites != nil { - cipherSuites := make([]interface{}, 0) for _, v := range *input.CipherSuites { cipherSuites = append(cipherSuites, string(v)) } - output["cipher_suites"] = cipherSuites } + output["cipher_suites"] = cipherSuites + disabledSslProtocols := make([]interface{}, 0) if input.DisabledSslProtocols != nil { - disabledSslProtocols := make([]interface{}, 0) for _, v := range *input.DisabledSslProtocols { disabledSslProtocols = append(disabledSslProtocols, string(v)) } - output["disabled_protocols"] = disabledSslProtocols } + output["disabled_protocols"] = disabledSslProtocols results = append(results, output) return results diff --git a/azurerm/resource_arm_application_gateway_test.go b/azurerm/resource_arm_application_gateway_test.go index 3beba169b2be1..74f4585662f9d 100644 --- a/azurerm/resource_arm_application_gateway_test.go +++ b/azurerm/resource_arm_application_gateway_test.go @@ -581,7 +581,7 @@ func TestAccAzureRMApplicationGateway_sslPolicy_policyType_custom(t *testing.T) }) } -func TestAccAzureRMApplicationGateway_sslPolicy_disabledSslProtocols(t *testing.T) { +func TestAccAzureRMApplicationGateway_sslPolicy_disabledProtocols(t *testing.T) { resourceName := "azurerm_application_gateway.test" ri := tf.AccRandTimeInt() @@ -591,7 +591,7 @@ func TestAccAzureRMApplicationGateway_sslPolicy_disabledSslProtocols(t *testing. CheckDestroy: testCheckAzureRMApplicationGatewayDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMApplicationGateway_sslPolicy_disabledSslProtocols(ri, testLocation()), + Config: testAccAzureRMApplicationGateway_sslPolicy_disabledProtocols(ri, testLocation()), Check: resource.ComposeTestCheckFunc( testCheckAzureRMApplicationGatewayExists(resourceName), resource.TestCheckResourceAttr(resourceName, "ssl_policy.0.disabled_protocols.0", "TLSv1_0"), @@ -602,6 +602,27 @@ func TestAccAzureRMApplicationGateway_sslPolicy_disabledSslProtocols(t *testing. }) } +func TestAccAzureRMApplicationGateway_disabledSslProtocols(t *testing.T) { + resourceName := "azurerm_application_gateway.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationGatewayDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApplicationGateway_disabledSslProtocols(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationGatewayExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "disabled_ssl_protocols.0", "TLSv1_0"), + resource.TestCheckResourceAttr(resourceName, "disabled_ssl_protocols.1", "TLSv1_1"), + ), + }, + }, + }) +} + func testCheckAzureRMApplicationGatewayExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[resourceName] @@ -2077,14 +2098,22 @@ locals { request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" } +resource "azurerm_public_ip" "test_standard" { + name = "acctest-pubip-%d-standard" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" + allocation_method = "Static" +} + resource "azurerm_application_gateway" "test" { name = "acctestag-%d" resource_group_name = "${azurerm_resource_group.test.name}" location = "${azurerm_resource_group.test.location}" sku { - name = "WAF_Medium" - tier = "WAF" + name = "Standard_v2" + tier = "Standard_v2" capacity = 1 } @@ -2093,13 +2122,6 @@ resource "azurerm_application_gateway" "test" { policy_type = "Predefined" } - waf_configuration { - enabled = true - firewall_mode = "Detection" - rule_set_type = "OWASP" - rule_set_version = "3.0" - } - gateway_ip_configuration { name = "my-gateway-ip-configuration" subnet_id = "${azurerm_subnet.test.id}" @@ -2112,7 +2134,7 @@ resource "azurerm_application_gateway" "test" { frontend_ip_configuration { name = "${local.frontend_ip_configuration_name}" - public_ip_address_id = "${azurerm_public_ip.test.id}" + public_ip_address_id = "${azurerm_public_ip.test_standard.id}" } backend_address_pool { @@ -2142,7 +2164,7 @@ resource "azurerm_application_gateway" "test" { backend_http_settings_name = "${local.http_setting_name}" } } -`, template, rInt) +`, template, rInt, rInt) } func testAccAzureRMApplicationGateway_sslPolicy_policyType_custom(rInt int, location string) string { @@ -2160,14 +2182,22 @@ locals { request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" } +resource "azurerm_public_ip" "test_standard" { + name = "acctest-pubip-%d-standard" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" + allocation_method = "Static" +} + resource "azurerm_application_gateway" "test" { name = "acctestag-%d" resource_group_name = "${azurerm_resource_group.test.name}" location = "${azurerm_resource_group.test.location}" sku { - name = "WAF_Medium" - tier = "WAF" + name = "Standard_v2" + tier = "Standard_v2" capacity = 1 } @@ -2177,13 +2207,6 @@ resource "azurerm_application_gateway" "test" { cipher_suites = ["TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_128_GCM_SHA256"] } - waf_configuration { - enabled = true - firewall_mode = "Detection" - rule_set_type = "OWASP" - rule_set_version = "3.0" - } - gateway_ip_configuration { name = "my-gateway-ip-configuration" subnet_id = "${azurerm_subnet.test.id}" @@ -2196,7 +2219,7 @@ resource "azurerm_application_gateway" "test" { frontend_ip_configuration { name = "${local.frontend_ip_configuration_name}" - public_ip_address_id = "${azurerm_public_ip.test.id}" + public_ip_address_id = "${azurerm_public_ip.test_standard.id}" } backend_address_pool { @@ -2226,10 +2249,10 @@ resource "azurerm_application_gateway" "test" { backend_http_settings_name = "${local.http_setting_name}" } } -`, template, rInt) +`, template, rInt, rInt) } -func testAccAzureRMApplicationGateway_sslPolicy_disabledSslProtocols(rInt int, location string) string { +func testAccAzureRMApplicationGateway_sslPolicy_disabledProtocols(rInt int, location string) string { template := testAccAzureRMApplicationGateway_template(rInt, location) return fmt.Sprintf(` %s @@ -2244,14 +2267,22 @@ locals { request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" } +resource "azurerm_public_ip" "test_standard" { + name = "acctest-pubip-%d-standard" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" + allocation_method = "Static" +} + resource "azurerm_application_gateway" "test" { name = "acctestag-%d" resource_group_name = "${azurerm_resource_group.test.name}" location = "${azurerm_resource_group.test.location}" sku { - name = "WAF_Medium" - tier = "WAF" + name = "Standard_v2" + tier = "Standard_v2" capacity = 1 } @@ -2259,16 +2290,87 @@ resource "azurerm_application_gateway" "test" { disabled_protocols = ["TLSv1_0", "TLSv1_1"] } - waf_configuration { - enabled = true - firewall_mode = "Detection" - rule_set_type = "OWASP" - rule_set_version = "3.0" - file_upload_limit_mb = 100 - request_body_check = true - max_request_body_size_kb = 100 + 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.test_standard.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" + } + + 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, rInt, rInt) +} + +func testAccAzureRMApplicationGateway_disabledSslProtocols(rInt int, location string) string { + template := testAccAzureRMApplicationGateway_template(rInt, location) + return fmt.Sprintf(` +%s + +# 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_public_ip" "test_standard" { + name = "acctest-pubip-%d-standard" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" + allocation_method = "Static" +} + +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 = 1 } + disabled_ssl_protocols = ["TLSv1_0", "TLSv1_1"] + gateway_ip_configuration { name = "my-gateway-ip-configuration" subnet_id = "${azurerm_subnet.test.id}" @@ -2281,7 +2383,7 @@ resource "azurerm_application_gateway" "test" { frontend_ip_configuration { name = "${local.frontend_ip_configuration_name}" - public_ip_address_id = "${azurerm_public_ip.test.id}" + public_ip_address_id = "${azurerm_public_ip.test_standard.id}" } backend_address_pool { @@ -2311,7 +2413,7 @@ resource "azurerm_application_gateway" "test" { backend_http_settings_name = "${local.http_setting_name}" } } -`, template, rInt) +`, template, rInt, rInt) } func testAccAzureRMApplicationGateway_connectionDraining(rInt int, location string) string { diff --git a/website/docs/r/application_gateway.html.markdown b/website/docs/r/application_gateway.html.markdown index 62e83bddc216d..897fbba6ed04c 100644 --- a/website/docs/r/application_gateway.html.markdown +++ b/website/docs/r/application_gateway.html.markdown @@ -147,9 +147,10 @@ The following arguments are supported: * `authentication_certificate` - (Optional) One or more `authentication_certificate` blocks as defined below. -* `disabled_ssl_protocols` - Deprecated: replaced by `ssl_policy`. (Optional) A list of SSL Protocols which should be disabled on this Application Gateway. Possible values are `TLSv1_0`, `TLSv1_1` and `TLSv1_2`. Not compatible with `ssl_policy` +* `disabled_ssl_protocols` - (Optional / **Deprecated**) A list of SSL Protocols which should be disabled on this Application Gateway. Possible values are `TLSv1_0`, `TLSv1_1` and `TLSv1_2`. +~> **NOTE:** `disabled_ssl_protocols ` has been deprecated in favour of `disabled_protocols` in the `ssl_policy` block. -* `ssl_policy` (Optional) ssl policys block as defined below. +* `ssl_policy` (Optional) a `ssl policy` block as defined below. * `enable_http2` - (Optional) Is HTTP2 enabled on the application gateway resource? Defaults to `false`. @@ -385,22 +386,25 @@ A `url_path_map` block supports the following: A `ssl_policy` block supports the following: -* `policy_type` - (Optional) The Type of the Policy. Required if `policy_name` is set. Possible values are `Predefined` and `Custom`. Not compatible with `disabled_protocols`. +* `disabled_protocols` - (Optional) A list of SSL Protocols which should be disabled on this Application Gateway. Possible values are `TLSv1_0`, `TLSv1_1` and `TLSv1_2`. -For `policy_type`=`Predefined`: +~> **NOTE:** `disabled_protocols` cannot be set when `policy_name` or `policy_type` are set. + +* `policy_type` - (Optional) The Type of the Policy. Possible values are `Predefined` and `Custom`. + +~> **NOTE:** `policy_type` is Required when `policy_name` is set - cannot be set if `disabled_protocols` is set. + +When using a `policy_type` of `Predefined` the following fields are supported: * `policy_name` - (Optional) The Name of the Policy e.g AppGwSslPolicy20170401S. Required if `policy_type` is set to `Predefined`. Possible values can change over time and are published here https://docs.microsoft.com/en-us/azure/application-gateway/application-gateway-ssl-policy-overview. Not compatible with `disabled_protocols`. -For `policy_type`=`Custom`: - -* `min_protocol_version` - (Optional) The minimal TLS version Required if `policy_type` is set to `Custom`. Possible values can change over time and are published here https://docs.microsoft.com/en-us/azure/application-gateway/application-gateway-ssl-policy-overview. Not compatible with `disabled_protocols` +When using a `policy_type` of `Custom` the following fields are supported: -* `cipher_suites` - (Optional) A List of accepted cipher suites Required if `policy_type` is set to `Custom`. Example ["TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_128_GCM_SHA256"]. Possible values can change over time and are published here https://docs.microsoft.com/en-us/azure/application-gateway/application-gateway-ssl-policy-overview. Not compatible with `disabled_protocols` +* `cipher_suites` - (Required) A List of accepted cipher suites. Possible values are: `TLS_DHE_DSS_WITH_AES_128_CBC_SHA`, `TLS_DHE_DSS_WITH_AES_128_CBC_SHA256`, `TLS_DHE_DSS_WITH_AES_256_CBC_SHA`, `TLS_DHE_DSS_WITH_AES_256_CBC_SHA256`, `TLS_DHE_RSA_WITH_AES_128_CBC_SHA`, `TLS_DHE_RSA_WITH_AES_128_GCM_SHA256`, `TLS_DHE_RSA_WITH_AES_256_CBC_SHA`, `TLS_DHE_RSA_WITH_AES_256_GCM_SHA384`, `TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA`, `TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256`, `TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256`, `TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA`, `TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384`, `TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384`, `TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA`, `TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256`, `TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA`, `TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384`, `TLS_RSA_WITH_3DES_EDE_CBC_SHA`, `TLS_RSA_WITH_AES_128_CBC_SHA`, `TLS_RSA_WITH_AES_128_CBC_SHA256`, `TLS_RSA_WITH_AES_128_GCM_SHA256`, `TLS_RSA_WITH_AES_256_CBC_SHA`, `TLS_RSA_WITH_AES_256_CBC_SHA256` and `TLS_RSA_WITH_AES_256_GCM_SHA384`. -For `disabled_protocols`: +* `min_protocol_version` - (Required) The minimal TLS version. Possible values are `TLSv1_0`, `TLSv1_1` and `TLSv1_2`. -* `disabled_protocols` - (Optional) A list of SSL Protocols which should be disabled on this Application Gateway. Possible values are `TLSv1_0`, `TLSv1_1` and `TLSv1_2`. Not compatible with `policy_name` / `policy_type` ---