diff --git a/azurerm/helpers/azure/app_service.go b/azurerm/helpers/azure/app_service.go index bb9f6f13be00..c8a5ff6d3de3 100644 --- a/azurerm/helpers/azure/app_service.go +++ b/azurerm/helpers/azure/app_service.go @@ -468,26 +468,7 @@ func SchemaAppServiceSiteConfig() *schema.Schema { Optional: true, }, - "cors": { - Type: schema.TypeList, - Optional: true, - Computed: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "allowed_origins": { - Type: schema.TypeSet, - Required: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "support_credentials": { - Type: schema.TypeBool, - Optional: true, - Default: false, - }, - }, - }, - }, + "cors": SchemaWebCorsSettings(), }, }, } @@ -751,57 +732,6 @@ func SchemaAppServiceDataSourceSiteConfig() *schema.Schema { } } -func ExpandAppServiceCorsSettings(input interface{}) web.CorsSettings { - settings := input.([]interface{}) - corsSettings := web.CorsSettings{} - - if len(settings) == 0 { - return corsSettings - } - - setting := settings[0].(map[string]interface{}) - - if v, ok := setting["allowed_origins"]; ok { - input := v.(*schema.Set).List() - - allowedOrigins := make([]string, 0) - for _, param := range input { - allowedOrigins = append(allowedOrigins, param.(string)) - } - - corsSettings.AllowedOrigins = &allowedOrigins - } - - if v, ok := setting["support_credentials"]; ok { - corsSettings.SupportCredentials = utils.Bool(v.(bool)) - } - - return corsSettings -} - -func FlattenAppServiceCorsSettings(input *web.CorsSettings) []interface{} { - results := make([]interface{}, 0) - if input == nil { - return results - } - - result := make(map[string]interface{}) - - allowedOrigins := make([]interface{}, 0) - if s := input.AllowedOrigins; s != nil { - for _, v := range *s { - allowedOrigins = append(allowedOrigins, v) - } - } - result["allowed_origins"] = schema.NewSet(schema.HashString, allowedOrigins) - - if input.SupportCredentials != nil { - result["support_credentials"] = *input.SupportCredentials - } - - return append(results, result) -} - func ExpandAppServiceAuthSettings(input []interface{}) web.SiteAuthSettingsProperties { siteAuthSettingsProperties := web.SiteAuthSettingsProperties{} @@ -1418,7 +1348,7 @@ func ExpandAppServiceSiteConfig(input interface{}) web.SiteConfig { if v, ok := config["cors"]; ok { corsSettings := v.(interface{}) - expand := ExpandAppServiceCorsSettings(corsSettings) + expand := ExpandWebCorsSettings(corsSettings) siteConfig.Cors = &expand } @@ -1537,7 +1467,7 @@ func FlattenAppServiceSiteConfig(input *web.SiteConfig) []interface{} { result["ftps_state"] = string(input.FtpsState) result["min_tls_version"] = string(input.MinTLSVersion) - result["cors"] = FlattenAppServiceCorsSettings(input.Cors) + result["cors"] = FlattenWebCorsSettings(input.Cors) return append(results, result) } diff --git a/azurerm/helpers/azure/web.go b/azurerm/helpers/azure/web.go new file mode 100644 index 000000000000..beeeb2298c6b --- /dev/null +++ b/azurerm/helpers/azure/web.go @@ -0,0 +1,81 @@ +package azure + +import ( + "github.com/Azure/azure-sdk-for-go/services/web/mgmt/2018-02-01/web" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func SchemaWebCorsSettings() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "allowed_origins": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "support_credentials": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + }, + }, + } +} + +func ExpandWebCorsSettings(input interface{}) web.CorsSettings { + settings := input.([]interface{}) + corsSettings := web.CorsSettings{} + + if len(settings) == 0 { + return corsSettings + } + + setting := settings[0].(map[string]interface{}) + + if v, ok := setting["allowed_origins"]; ok { + input := v.(*schema.Set).List() + + allowedOrigins := make([]string, 0) + for _, param := range input { + allowedOrigins = append(allowedOrigins, param.(string)) + } + + corsSettings.AllowedOrigins = &allowedOrigins + } + + if v, ok := setting["support_credentials"]; ok { + corsSettings.SupportCredentials = utils.Bool(v.(bool)) + } + + return corsSettings +} + +func FlattenWebCorsSettings(input *web.CorsSettings) []interface{} { + results := make([]interface{}, 0) + if input == nil { + return results + } + + result := make(map[string]interface{}) + + allowedOrigins := make([]interface{}, 0) + if s := input.AllowedOrigins; s != nil { + for _, v := range *s { + allowedOrigins = append(allowedOrigins, v) + } + } + result["allowed_origins"] = schema.NewSet(schema.HashString, allowedOrigins) + + if input.SupportCredentials != nil { + result["support_credentials"] = *input.SupportCredentials + } + + return append(results, result) +} diff --git a/azurerm/resource_arm_function_app.go b/azurerm/resource_arm_function_app.go index 13873c62a473..4dd570369f26 100644 --- a/azurerm/resource_arm_function_app.go +++ b/azurerm/resource_arm_function_app.go @@ -199,6 +199,7 @@ func resourceArmFunctionApp() *schema.Resource { Optional: true, Computed: true, }, + "cors": azure.SchemaWebCorsSettings(), }, }, }, @@ -681,6 +682,12 @@ func expandFunctionAppSiteConfig(d *schema.ResourceData) web.SiteConfig { siteConfig.LinuxFxVersion = utils.String(v.(string)) } + if v, ok := config["cors"]; ok { + corsSettings := v.(interface{}) + expand := azure.ExpandWebCorsSettings(corsSettings) + siteConfig.Cors = &expand + } + return siteConfig } @@ -709,6 +716,8 @@ func flattenFunctionAppSiteConfig(input *web.SiteConfig) []interface{} { result["linux_fx_version"] = *input.LinuxFxVersion } + result["cors"] = azure.FlattenWebCorsSettings(input.Cors) + results = append(results, result) return results } diff --git a/azurerm/resource_arm_function_app_test.go b/azurerm/resource_arm_function_app_test.go index 586e5c748efd..c0728f14de09 100644 --- a/azurerm/resource_arm_function_app_test.go +++ b/azurerm/resource_arm_function_app_test.go @@ -636,6 +636,35 @@ func TestAccAzureRMFunctionApp_authSettings(t *testing.T) { }) } +func TestAccAzureRMFunctionApp_corsSettings(t *testing.T) { + resourceName := "azurerm_function_app.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + config := testAccAzureRMFunctionApp_corsSettings(ri, rs, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMFunctionAppDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMFunctionAppExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.cors.#", "1"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.cors.0.support_credentials", "true"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.cors.0.allowed_origins.#", "4"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testCheckAzureRMFunctionAppDestroy(s *terraform.State) error { client := testAccProvider.Meta().(*ArmClient).appServicesClient @@ -1527,3 +1556,52 @@ resource "azurerm_function_app" "test" { } `, rInt, location, storage, tenantID) } + +func testAccAzureRMFunctionApp_corsSettings(rInt int, storage string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%[1]d" + location = "%[2]s" +} + +resource "azurerm_storage_account" "test" { + name = "acctestsa%[3]s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%[1]d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_function_app" "test" { + name = "acctest-%[1]d-func" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + storage_connection_string = "${azurerm_storage_account.test.primary_connection_string}" + + site_config { + cors { + allowed_origins = [ + "http://www.contoso.com", + "www.contoso.com", + "contoso.com", + "http://localhost:4201", + ] + + support_credentials = true + } + } +} +`, rInt, location, storage) +} diff --git a/website/docs/r/function_app.html.markdown b/website/docs/r/function_app.html.markdown index 829fedfcb14a..76579ac43d88 100644 --- a/website/docs/r/function_app.html.markdown +++ b/website/docs/r/function_app.html.markdown @@ -140,6 +140,16 @@ The following arguments are supported: * `linux_fx_version` - (Optional) Linux App Framework and version for the AppService, e.g. `DOCKER|(golang:latest)`. +* `cors` - (Optional) A `cors` block as defined below. + +--- + +A `cors` block supports the following: + +* `allowed_origins` - (Optional) A list of origins which should be able to make cross-origin calls. `*` can be used to allow all calls. + +* `support_credentials` - (Optional) Are credentials supported? + --- `identity` supports the following: @@ -148,7 +158,7 @@ The following arguments are supported: --- -A `auth_settings` block supports the following: +An `auth_settings` block supports the following: * `enabled` - (Required) Is Authentication enabled? @@ -182,7 +192,7 @@ A `auth_settings` block supports the following: --- -A `active_directory` block supports the following: +An `active_directory` block supports the following: * `client_id` - (Required) The Client ID of this relying party application. Enables OpenIDConnection authentication with Azure Active Directory.