From c7ca7738527f42f4ea2912d13be0950f121f17de Mon Sep 17 00:00:00 2001 From: Sean Nixon Date: Thu, 30 Jan 2020 20:12:25 -0600 Subject: [PATCH] azurerm_front_door - Add minimum_tls_version property (#5539) * r/front_door - Add minimum_tls_version property * r/frontdoor Make default min TLS version 1.0 until v2.0 * r/frontdoor: Make minimum_tls_version computed This updates the behavior to better fit with the Portal experience. Existing frontends will continue to use TLS 1.0 while new frontends will use TLS 1.2 as the minimum * Revert azurerm_frontdoor 2.0 upgrade note * r/frontdoor: Remove minimum_tls_version from docs That attribute is now calculated so it should not be set by the user * Added test case for custom https * Fixed test HCL formatting * Fixed test fmt lint issue * Fix test lint error * Added minimum tls to documentation Co-authored-by: WS <20408400+WodansSon@users.noreply.github.com> --- .../frontdoor/resource_arm_front_door.go | 43 ++--- .../tests/resource_arm_front_door_test.go | 157 ++++++++++++++++++ website/docs/r/front_door.html.markdown | 6 +- 3 files changed, 177 insertions(+), 29 deletions(-) diff --git a/azurerm/internal/services/frontdoor/resource_arm_front_door.go b/azurerm/internal/services/frontdoor/resource_arm_front_door.go index 899127785c60..2af4efdfb7df 100644 --- a/azurerm/internal/services/frontdoor/resource_arm_front_door.go +++ b/azurerm/internal/services/frontdoor/resource_arm_front_door.go @@ -408,6 +408,10 @@ func resourceArmFrontDoor() *schema.Resource { }, false), Default: string(frontdoor.CertificateSourceFrontDoor), }, + "minimum_tls_version": { + Type: schema.TypeString, + Computed: true, + }, "provisioning_state": { Type: schema.TypeString, Computed: true, @@ -549,9 +553,12 @@ func resourceArmFrontDoorCreateUpdate(d *schema.ResourceData, meta interface{}) // Build a custom Https configuration based off the config file to send to the enable call // NOTE: I do not need to check to see if this exists since I already do that in the validation code chc := frontendEndpoint["custom_https_configuration"].([]interface{}) - customHttpsConfiguration := chc[0].(map[string]interface{}) - customHTTPSConfigurationUpdate := makeCustomHttpsConfiguration(customHttpsConfiguration) - + customHTTPSConfiguration := chc[0].(map[string]interface{}) + minTLSVersion := frontdoor.OneFullStopTwo // Default to TLS 1.2 + if httpsConfig := properties.CustomHTTPSConfiguration; httpsConfig != nil { + minTLSVersion = httpsConfig.MinimumTLSVersion + } + customHTTPSConfigurationUpdate := makeCustomHttpsConfiguration(customHTTPSConfiguration, minTLSVersion) // Enable Custom Domain HTTPS for the Frontend Endpoint if err := resourceArmFrontDoorFrontendEndpointEnableHttpsProvisioning(d, true, name, frontendEndpointName, resourceGroup, customHTTPSConfigurationUpdate, meta); err != nil { return fmt.Errorf("Unable enable Custom Domain HTTPS for Frontend Endpoint %q (Resource Group %q): %+v", frontendEndpointName, resourceGroup, err) @@ -811,7 +818,6 @@ func expandArmFrontDoorFrontendEndpoint(input []interface{}, frontDoorPath strin hostName := frontendEndpoint["host_name"].(string) isSessionAffinityEnabled := frontendEndpoint["session_affinity_enabled"].(bool) sessionAffinityTtlSeconds := int32(frontendEndpoint["session_affinity_ttl_seconds"].(int)) - customHttpsConfiguration := frontendEndpoint["custom_https_configuration"].([]interface{}) waf := frontendEndpoint["web_application_firewall_policy_link_id"].(string) name := frontendEndpoint["name"].(string) id := utils.String(frontDoorPath + "/FrontendEndpoints/" + name) @@ -825,7 +831,6 @@ func expandArmFrontDoorFrontendEndpoint(input []interface{}, frontDoorPath strin ID: id, Name: utils.String(name), FrontendEndpointProperties: &frontdoor.FrontendEndpointProperties{ - CustomHTTPSConfiguration: expandArmFrontDoorCustomHTTPSConfiguration(customHttpsConfiguration), HostName: utils.String(hostName), SessionAffinityEnabledState: sessionAffinityEnabled, SessionAffinityTTLSeconds: utils.Int32(sessionAffinityTtlSeconds), @@ -844,27 +849,6 @@ func expandArmFrontDoorFrontendEndpoint(input []interface{}, frontDoorPath strin return &output } -func expandArmFrontDoorCustomHTTPSConfiguration(input []interface{}) *frontdoor.CustomHTTPSConfiguration { - if len(input) == 0 { - // https://github.com/Azure/azure-sdk-for-go/issues/6882 - defaultProtocolType := "ServerNameIndication" - - defaultHttpsConfiguration := frontdoor.CustomHTTPSConfiguration{ - ProtocolType: &defaultProtocolType, - CertificateSource: frontdoor.CertificateSourceFrontDoor, - CertificateSourceParameters: &frontdoor.CertificateSourceParameters{ - CertificateType: frontdoor.Dedicated, - }, - } - return &defaultHttpsConfiguration - } - - v := input[0].(map[string]interface{}) - customHttpsConfiguration := makeCustomHttpsConfiguration(v) - - return &customHttpsConfiguration -} - func expandArmFrontDoorHealthProbeSettingsModel(input []interface{}, frontDoorPath string) *[]frontdoor.HealthProbeSettingsModel { if len(input) == 0 { return &[]frontdoor.HealthProbeSettingsModel{} @@ -1265,6 +1249,8 @@ func flattenArmFrontDoorFrontendEndpoint(d *schema.ResourceData, input *[]frontd chc["certificate_source"] = string(frontdoor.CertificateSourceFrontDoor) } + chc["minimum_tls_version"] = string(customHTTPSConfiguration.MinimumTLSVersion) + if provisioningState := properties.CustomHTTPSProvisioningState; provisioningState != "" { chc["provisioning_state"] = provisioningState if provisioningState == frontdoor.CustomHTTPSProvisioningStateEnabled || provisioningState == frontdoor.CustomHTTPSProvisioningStateEnabling { @@ -1498,12 +1484,13 @@ func flattenArmFrontDoorFrontendEndpointsSubResources(input *[]frontdoor.SubReso return output } -func makeCustomHttpsConfiguration(customHttpsConfiguration map[string]interface{}) frontdoor.CustomHTTPSConfiguration { +func makeCustomHttpsConfiguration(customHttpsConfiguration map[string]interface{}, minTLSVersion frontdoor.MinimumTLSVersion) frontdoor.CustomHTTPSConfiguration { // https://github.com/Azure/azure-sdk-for-go/issues/6882 defaultProtocolType := "ServerNameIndication" customHTTPSConfigurationUpdate := frontdoor.CustomHTTPSConfiguration{ - ProtocolType: &defaultProtocolType, + ProtocolType: &defaultProtocolType, + MinimumTLSVersion: minTLSVersion, } if customHttpsConfiguration["certificate_source"].(string) == "AzureKeyVault" { diff --git a/azurerm/internal/services/frontdoor/tests/resource_arm_front_door_test.go b/azurerm/internal/services/frontdoor/tests/resource_arm_front_door_test.go index 693b739a83dc..f288ee6a6827 100644 --- a/azurerm/internal/services/frontdoor/tests/resource_arm_front_door_test.go +++ b/azurerm/internal/services/frontdoor/tests/resource_arm_front_door_test.go @@ -160,6 +160,36 @@ func TestAccAzureRMFrontDoor_EnableDisableCache(t *testing.T) { }) } +func TestAccAzureRMFrontDoor_CustomHttps(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_frontdoor", "test") + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMFrontDoorDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMFrontDoor_CustomHttpsEnabled(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMFrontDoorExists(data.ResourceName), + resource.TestCheckResourceAttr(data.ResourceName, "frontend_endpoint.0.custom_https_provisioning_enabled", "true"), + resource.TestCheckResourceAttr(data.ResourceName, "frontend_endpoint.0.custom_https_configuration.0.certificate_source", "FrontDoor"), + resource.TestCheckResourceAttr(data.ResourceName, "frontend_endpoint.0.custom_https_configuration.0.minimum_tls_version", "1.2"), + resource.TestCheckResourceAttr(data.ResourceName, "frontend_endpoint.0.custom_https_configuration.0.provisioning_state", "Enabled"), + resource.TestCheckResourceAttr(data.ResourceName, "frontend_endpoint.0.custom_https_configuration.0.provisioning_substate", "CertificateDeployed"), + ), + }, + { + Config: testAccAzureRMFrontDoor_CustomHttpsDisabled(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMFrontDoorExists(data.ResourceName), + resource.TestCheckResourceAttr(data.ResourceName, "frontend_endpoint.0.custom_https_provisioning_enabled", "false"), + ), + }, + data.ImportStep(), + }, + }) +} + func testCheckAzureRMFrontDoorExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { client := acceptance.AzureProvider.Meta().(*clients.Client).Frontdoor.FrontDoorsClient @@ -573,3 +603,130 @@ resource "azurerm_frontdoor" "test" { } `, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger) } + +func testAccAzureRMFrontDoor_CustomHttpsEnabled(data acceptance.TestData) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +locals { + backend_name = "backend-bing" + endpoint_name = "frontend-endpoint" + health_probe_name = "health-probe" + load_balancing_name = "load-balancing-setting" +} + +resource "azurerm_frontdoor" "test" { + name = "acctestfd-%d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + enforce_backend_pools_certificate_name_check = false + + routing_rule { + name = "routing-rule" + accepted_protocols = ["Http", "Https"] + patterns_to_match = ["/*"] + frontend_endpoints = [local.endpoint_name] + + forwarding_configuration { + forwarding_protocol = "MatchRequest" + backend_pool_name = local.backend_name + } + } + + backend_pool_load_balancing { + name = local.load_balancing_name + } + + backend_pool_health_probe { + name = local.health_probe_name + } + + backend_pool { + name = local.backend_name + backend { + host_header = "www.bing.com" + address = "www.bing.com" + http_port = 80 + https_port = 443 + } + + load_balancing_name = local.load_balancing_name + health_probe_name = local.health_probe_name + } + + frontend_endpoint { + name = local.endpoint_name + host_name = "acctestfd-%d.azurefd.net" + custom_https_provisioning_enabled = true + custom_https_configuration { + certificate_source = "FrontDoor" + } + } +} +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger) +} + +func testAccAzureRMFrontDoor_CustomHttpsDisabled(data acceptance.TestData) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +locals { + backend_name = "backend-bing" + endpoint_name = "frontend-endpoint" + health_probe_name = "health-probe" + load_balancing_name = "load-balancing-setting" +} + +resource "azurerm_frontdoor" "test" { + name = "acctestfd-%d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + enforce_backend_pools_certificate_name_check = false + + routing_rule { + name = "routing-rule" + accepted_protocols = ["Http", "Https"] + patterns_to_match = ["/*"] + frontend_endpoints = [local.endpoint_name] + + forwarding_configuration { + forwarding_protocol = "MatchRequest" + backend_pool_name = local.backend_name + } + } + + backend_pool_load_balancing { + name = local.load_balancing_name + } + + backend_pool_health_probe { + name = local.health_probe_name + } + + backend_pool { + name = local.backend_name + backend { + host_header = "www.bing.com" + address = "www.bing.com" + http_port = 80 + https_port = 443 + } + + load_balancing_name = local.load_balancing_name + health_probe_name = local.health_probe_name + } + + frontend_endpoint { + name = local.endpoint_name + host_name = "acctestfd-%d.azurefd.net" + custom_https_provisioning_enabled = false + } +} +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger) +} diff --git a/website/docs/r/front_door.html.markdown b/website/docs/r/front_door.html.markdown index 87136435d8bc..22de3c2302ee 100644 --- a/website/docs/r/front_door.html.markdown +++ b/website/docs/r/front_door.html.markdown @@ -274,10 +274,14 @@ The following attributes are only valid if `certificate_source` is set to `Azure * `id` - The Resource ID of the Azure Front Door Backend Load Balancer. -`routing_rule` exports the following: +`routing_rule` exports the following: * `id` - The Resource ID of the Azure Front Door Backend Routing Rule. +`custom_https_configuration` exports the following: + +* `minimum_tls_version` - Minimum client TLS version supported. + The following attributes are exported: