From 477facbf2b841af4dbeeafa28d3751dce11e03e4 Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Wed, 30 Jan 2019 12:36:00 +0100 Subject: [PATCH 01/38] Add initial implementation for Authentication Settings in read & update --- azurerm/resource_arm_app_service.go | 33 +++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/azurerm/resource_arm_app_service.go b/azurerm/resource_arm_app_service.go index 7f9839ce9746..c7d7db070d34 100644 --- a/azurerm/resource_arm_app_service.go +++ b/azurerm/resource_arm_app_service.go @@ -69,6 +69,8 @@ func resourceArmAppService() *schema.Resource { "site_config": azure.SchemaAppServiceSiteConfig(), + "auth_settings": azure.SchemaAppServiceAuthSettings(), + "client_affinity_enabled": { Type: schema.TypeBool, Optional: true, @@ -279,6 +281,14 @@ func resourceArmAppServiceCreate(d *schema.ResourceData, meta interface{}) error d.SetId(*read.ID) + authSettings := azure.ExpandAppServiceAuthSettings(d.Get("auth_settings")) + + auth := web.SiteAuthSettings{ + ID: read.ID, + SiteAuthSettingsProperties: &authSettings} + + client.UpdateAuthSettings(ctx, resGroup, name, auth) + return resourceArmAppServiceUpdate(d, meta) } @@ -338,6 +348,19 @@ func resourceArmAppServiceUpdate(d *schema.ResourceData, meta interface{}) error } } + if d.HasChange("auth_settings") { + authSettingsProperties := azure.ExpandAppServiceAuthSettings(d.Get("auth_settings")) + id := d.Id() + authSettings := web.SiteAuthSettings{ + ID: &id, + SiteAuthSettingsProperties: &authSettingsProperties, + } + + if _, err := client.UpdateAuthSettings(ctx, resGroup, name, authSettings); err != nil { + return fmt.Errorf("Error updating Authentication Settings for App Service %q: %+v", name, err) + } + } + if d.HasChange("client_affinity_enabled") { affinity := d.Get("client_affinity_enabled").(bool) @@ -433,6 +456,11 @@ func resourceArmAppServiceRead(d *schema.ResourceData, meta interface{}) error { return fmt.Errorf("Error making Read request on AzureRM App Service Configuration %q: %+v", name, err) } + authResp, err := client.GetAuthSettings(ctx, resGroup, name) + if err != nil { + return fmt.Errorf("Error making Read request on AzureRM App Service AuthSettings %q: %+v", name, err) + } + appSettingsResp, err := client.ListApplicationSettings(ctx, resGroup, name) if err != nil { if utils.ResponseWasNotFound(appSettingsResp.Response) { @@ -496,6 +524,11 @@ func resourceArmAppServiceRead(d *schema.ResourceData, meta interface{}) error { return err } + authSettings := azure.FlattenAppServiceAuthSettings(authResp.SiteAuthSettingsProperties) + if err := d.Set("auth_settings", authSettings); err != nil { + return err + } + scm := flattenAppServiceSourceControl(scmResp.SiteSourceControlProperties) if err := d.Set("source_control", scm); err != nil { return err From 10cd657ed059fa40eacb922deaf0391c46f88e5d Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 10:55:14 +0100 Subject: [PATCH 02/38] Add initial active directory section --- azurerm/helpers/azure/app_service.go | 128 +++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/azurerm/helpers/azure/app_service.go b/azurerm/helpers/azure/app_service.go index 847bca5ea6eb..061fb5d097a3 100644 --- a/azurerm/helpers/azure/app_service.go +++ b/azurerm/helpers/azure/app_service.go @@ -12,6 +12,61 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) +func SchemaAppServiceAadAuthSettings() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "client_id": { + Type: schema.TypeString, + Required: true, + }, + "client_secret": { + Type: schema.TypeString, + Optional: true, + }, + "allowed_audiences": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + } +} + +func SchemaAppServiceAuthSettings() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Required: true, + Sensitive: false, + }, + "additional_login_params": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "allowed_external_redirect_urls": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "active_directory": SchemaAppServiceAadAuthSettings(), + }, + }, + } +} + func SchemaAppServiceSiteConfig() *schema.Schema { return &schema.Schema{ Type: schema.TypeList, @@ -452,6 +507,79 @@ func FlattenAppServiceCorsSettings(input *web.CorsSettings) []interface{} { return append(results, result) } +func ExpandAppServiceAuthSettings(input interface{}) web.SiteAuthSettingsProperties { + settings := input.([]interface{}) + siteAuthSettingsProperties := web.SiteAuthSettingsProperties{} + + if len(settings) == 0 { + return siteAuthSettingsProperties + } + + setting := settings[0].(map[string]interface{}) + + if v, ok := setting["enabled"]; ok { + siteAuthSettingsProperties.Enabled = utils.Bool(v.(bool)) + } + + if v, ok := setting["additional_login_params"]; ok { + input := v.([]interface{}) + + additionalLoginParams := make([]string, 0) + for _, param := range input { + additionalLoginParams = append(additionalLoginParams, param.(string)) + } + + siteAuthSettingsProperties.AdditionalLoginParams = &additionalLoginParams + } + + if v, ok := setting["active_directory"]; ok { + + activeDirectorySettings := v.([]interface{}) + activeDirectorySetting := activeDirectorySettings[0].(map[string]interface{}) + + if v, ok := activeDirectorySetting["client_id"]; ok { + siteAuthSettingsProperties.ClientID = utils.String(v.(string)) + } + + if v, ok := activeDirectorySetting["client_secret"]; ok { + siteAuthSettingsProperties.ClientSecret = utils.String(v.(string)) + } + } + + return siteAuthSettingsProperties +} + +func FlattenAppServiceAuthSettings(input *web.SiteAuthSettingsProperties) []interface{} { + results := make([]interface{}, 0) + result := make(map[string]interface{}) + + if input == nil { + log.Printf("[DEBUG] AuthSettings is nil") + return results + } + + if input.Enabled != nil { + result["enabled"] = *input.Enabled + } + + additionalLoginParams := make([]string, 0) + if s := input.AdditionalLoginParams; s != nil { + additionalLoginParams = *s + } + result["additional_login_params"] = additionalLoginParams + + activeDirectorySettings := make([]interface{}, 0) + activeDirectorySetting := make(map[string]interface{}) + + if input.ClientID != nil { + activeDirectorySetting["client_id"] = input.ClientID + } + + result["active_directory"] = append(activeDirectorySettings, activeDirectorySetting) + + return append(results, result) +} + func ExpandAppServiceSiteConfig(input interface{}) web.SiteConfig { configs := input.([]interface{}) siteConfig := web.SiteConfig{} From f2270063e5da4b83fdac98b2d429a46c6b404d1a Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 11:02:37 +0100 Subject: [PATCH 03/38] Add allowedAudiences to schema, flatten and expand --- azurerm/helpers/azure/app_service.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/azurerm/helpers/azure/app_service.go b/azurerm/helpers/azure/app_service.go index 061fb5d097a3..b9a6b7b33c45 100644 --- a/azurerm/helpers/azure/app_service.go +++ b/azurerm/helpers/azure/app_service.go @@ -544,6 +544,17 @@ func ExpandAppServiceAuthSettings(input interface{}) web.SiteAuthSettingsPropert if v, ok := activeDirectorySetting["client_secret"]; ok { siteAuthSettingsProperties.ClientSecret = utils.String(v.(string)) } + + if v, ok := activeDirectorySetting["allowed_audiences"]; ok { + input := v.([]interface{}) + + allowedAudiences := make([]string, 0) + for _, param := range input { + allowedAudiences = append(allowedAudiences, param.(string)) + } + + siteAuthSettingsProperties.AllowedAudiences = &allowedAudiences + } } return siteAuthSettingsProperties @@ -575,6 +586,14 @@ func FlattenAppServiceAuthSettings(input *web.SiteAuthSettingsProperties) []inte activeDirectorySetting["client_id"] = input.ClientID } + if input.ClientSecret != nil { + activeDirectorySetting["client_secret"] = input.ClientSecret + } + + if s := input.AllowedAudiences; s != nil { + activeDirectorySetting["allowed_audiences"] = *s + } + result["active_directory"] = append(activeDirectorySettings, activeDirectorySetting) return append(results, result) From 69c6707192196b3722dc268f2f627f8699e91553 Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 11:04:56 +0100 Subject: [PATCH 04/38] Add facebook auth settings schema --- azurerm/helpers/azure/app_service.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/azurerm/helpers/azure/app_service.go b/azurerm/helpers/azure/app_service.go index b9a6b7b33c45..d0f3821cc652 100644 --- a/azurerm/helpers/azure/app_service.go +++ b/azurerm/helpers/azure/app_service.go @@ -38,6 +38,32 @@ func SchemaAppServiceAadAuthSettings() *schema.Schema { } } +func SchemaAppServiceFacebookSettings() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "app_id": { + Type: schema.TypeString, + Required: true, + }, + "app_secret": { + Type: schema.TypeString, + Optional: true, + }, + "oauth_scopes": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + } +} + func SchemaAppServiceAuthSettings() *schema.Schema { return &schema.Schema{ Type: schema.TypeList, From 627d41a096aee0ed6c3fda6d971a8a92706a630f Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 11:05:31 +0100 Subject: [PATCH 05/38] Add 'auth' to facebook schema function name --- azurerm/helpers/azure/app_service.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azurerm/helpers/azure/app_service.go b/azurerm/helpers/azure/app_service.go index d0f3821cc652..9303283a30ac 100644 --- a/azurerm/helpers/azure/app_service.go +++ b/azurerm/helpers/azure/app_service.go @@ -38,7 +38,7 @@ func SchemaAppServiceAadAuthSettings() *schema.Schema { } } -func SchemaAppServiceFacebookSettings() *schema.Schema { +func SchemaAppServiceFacebookAuthSettings() *schema.Schema { return &schema.Schema{ Type: schema.TypeList, Optional: true, From 54205f2bedde09da79b1b8c668124f37195eb131 Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 11:14:22 +0100 Subject: [PATCH 06/38] Add google auth settings schema --- azurerm/helpers/azure/app_service.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/azurerm/helpers/azure/app_service.go b/azurerm/helpers/azure/app_service.go index 9303283a30ac..4890268f8e8d 100644 --- a/azurerm/helpers/azure/app_service.go +++ b/azurerm/helpers/azure/app_service.go @@ -64,6 +64,32 @@ func SchemaAppServiceFacebookAuthSettings() *schema.Schema { } } +func SchemaAppServiceGoogleAuthSettings() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "client_id": { + Type: schema.TypeString, + Required: true, + }, + "client_secret": { + Type: schema.TypeString, + Required: true, + }, + "oauth_scopes": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + } +} + func SchemaAppServiceAuthSettings() *schema.Schema { return &schema.Schema{ Type: schema.TypeList, From 7a46c0eca3cef74a2f10c05d13ae401eee5d0c1c Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 11:14:49 +0100 Subject: [PATCH 07/38] Make sure facebook app secret is required --- azurerm/helpers/azure/app_service.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azurerm/helpers/azure/app_service.go b/azurerm/helpers/azure/app_service.go index 4890268f8e8d..a22da78a8c7e 100644 --- a/azurerm/helpers/azure/app_service.go +++ b/azurerm/helpers/azure/app_service.go @@ -52,7 +52,7 @@ func SchemaAppServiceFacebookAuthSettings() *schema.Schema { }, "app_secret": { Type: schema.TypeString, - Optional: true, + Required: true, }, "oauth_scopes": { Type: schema.TypeList, From a7cf8454fd30ba26e10645f830ecb72aec4f5d41 Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 11:16:43 +0100 Subject: [PATCH 08/38] Add microsoft auth settings schema --- azurerm/helpers/azure/app_service.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/azurerm/helpers/azure/app_service.go b/azurerm/helpers/azure/app_service.go index a22da78a8c7e..90c923cc862d 100644 --- a/azurerm/helpers/azure/app_service.go +++ b/azurerm/helpers/azure/app_service.go @@ -90,6 +90,32 @@ func SchemaAppServiceGoogleAuthSettings() *schema.Schema { } } +func SchemaAppServiceMicrosoftAuthSettings() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "client_id": { + Type: schema.TypeString, + Required: true, + }, + "client_secret": { + Type: schema.TypeString, + Required: true, + }, + "oauth_scopes": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + } +} + func SchemaAppServiceAuthSettings() *schema.Schema { return &schema.Schema{ Type: schema.TypeList, From c0333254d1926a77ce97c8d762303a8e75aef89d Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 11:17:54 +0100 Subject: [PATCH 09/38] Add providers to main auth schema --- azurerm/helpers/azure/app_service.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/azurerm/helpers/azure/app_service.go b/azurerm/helpers/azure/app_service.go index 90c923cc862d..fe6bd93002c4 100644 --- a/azurerm/helpers/azure/app_service.go +++ b/azurerm/helpers/azure/app_service.go @@ -140,6 +140,9 @@ func SchemaAppServiceAuthSettings() *schema.Schema { Elem: &schema.Schema{Type: schema.TypeString}, }, "active_directory": SchemaAppServiceAadAuthSettings(), + "facebook": SchemaAppServiceFacebookAuthSettings(), + "google": SchemaAppServiceGoogleAuthSettings(), + "microsoft": SchemaAppServiceMicrosoftAuthSettings(), }, }, } From 6c183e2e0fdc9e264c5c69637aa0ee1b9cd24977 Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 11:29:26 +0100 Subject: [PATCH 10/38] Add twitter auth settings schema --- azurerm/helpers/azure/app_service.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/azurerm/helpers/azure/app_service.go b/azurerm/helpers/azure/app_service.go index fe6bd93002c4..20b3ce8d6b8e 100644 --- a/azurerm/helpers/azure/app_service.go +++ b/azurerm/helpers/azure/app_service.go @@ -116,6 +116,27 @@ func SchemaAppServiceMicrosoftAuthSettings() *schema.Schema { } } +func SchemaAppServiceTwitterAuthSettings() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "consumer_key": { + Type: schema.TypeString, + Required: true, + }, + "consumer_secret": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + } +} + func SchemaAppServiceAuthSettings() *schema.Schema { return &schema.Schema{ Type: schema.TypeList, @@ -143,6 +164,7 @@ func SchemaAppServiceAuthSettings() *schema.Schema { "facebook": SchemaAppServiceFacebookAuthSettings(), "google": SchemaAppServiceGoogleAuthSettings(), "microsoft": SchemaAppServiceMicrosoftAuthSettings(), + "twitter": SchemaAppServiceTwitterAuthSettings(), }, }, } From 902dea65f7929822d361bfae78c9d266a1872d80 Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 11:32:01 +0100 Subject: [PATCH 11/38] Add remaining properties for main schema --- azurerm/helpers/azure/app_service.go | 34 ++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/azurerm/helpers/azure/app_service.go b/azurerm/helpers/azure/app_service.go index 20b3ce8d6b8e..e57ae1ac0ffd 100644 --- a/azurerm/helpers/azure/app_service.go +++ b/azurerm/helpers/azure/app_service.go @@ -160,6 +160,40 @@ func SchemaAppServiceAuthSettings() *schema.Schema { Optional: true, Elem: &schema.Schema{Type: schema.TypeString}, }, + "default_provider": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + "AzureActiveDirectory", + "Facebook", + "Google", + "MicrosoftAccount", + "Twitter", + }, true), + DiffSuppressFunc: suppress.CaseDifference, + }, + "issuer": { + Type: schema.TypeString, + Optional: true, + }, + "runtime_version": { + Type: schema.TypeString, + Optional: true, + }, + "token_refresh_extension_hours": { + Type: schema.TypeInt, + Optional: true, + Default: 72, + }, + "unauthenticated_client_action": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + "AllowAnonymous", + "RedirectToLoginPage", + }, true), + DiffSuppressFunc: suppress.CaseDifference, + }, "active_directory": SchemaAppServiceAadAuthSettings(), "facebook": SchemaAppServiceFacebookAuthSettings(), "google": SchemaAppServiceGoogleAuthSettings(), From 04df693b69d164c6065652e817daa12cfc8b15e3 Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 11:48:29 +0100 Subject: [PATCH 12/38] Add facebook, google, microsoft and twitter to expand --- azurerm/helpers/azure/app_service.go | 86 +++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/azurerm/helpers/azure/app_service.go b/azurerm/helpers/azure/app_service.go index e57ae1ac0ffd..8132561e80ec 100644 --- a/azurerm/helpers/azure/app_service.go +++ b/azurerm/helpers/azure/app_service.go @@ -670,7 +670,6 @@ func ExpandAppServiceAuthSettings(input interface{}) web.SiteAuthSettingsPropert } if v, ok := setting["active_directory"]; ok { - activeDirectorySettings := v.([]interface{}) activeDirectorySetting := activeDirectorySettings[0].(map[string]interface{}) @@ -694,6 +693,91 @@ func ExpandAppServiceAuthSettings(input interface{}) web.SiteAuthSettingsPropert } } + if v, ok := setting["facebook"]; ok { + facebookSettings := v.([]interface{}) + facebookSetting := facebookSettings[0].(map[string]interface{}) + + if v, ok := facebookSetting["app_id"]; ok { + siteAuthSettingsProperties.FacebookAppID = utils.String(v.(string)) + } + + if v, ok := facebookSetting["app_secret"]; ok { + siteAuthSettingsProperties.FacebookAppSecret = utils.String(v.(string)) + } + + if v, ok := facebookSetting["oauth_scopes"]; ok { + input := v.([]interface{}) + + oauthScopes := make([]string, 0) + for _, param := range input { + oauthScopes = append(oauthScopes, param.(string)) + } + + siteAuthSettingsProperties.FacebookOAuthScopes = &oauthScopes + } + } + + if v, ok := setting["google"]; ok { + googleSettings := v.([]interface{}) + googleSetting := googleSettings[0].(map[string]interface{}) + + if v, ok := googleSetting["client_id"]; ok { + siteAuthSettingsProperties.GoogleClientID = utils.String(v.(string)) + } + + if v, ok := googleSetting["client_secret"]; ok { + siteAuthSettingsProperties.GoogleClientSecret = utils.String(v.(string)) + } + + if v, ok := googleSetting["oauth_scopes"]; ok { + input := v.([]interface{}) + + oauthScopes := make([]string, 0) + for _, param := range input { + oauthScopes = append(oauthScopes, param.(string)) + } + + siteAuthSettingsProperties.GoogleOAuthScopes = &oauthScopes + } + } + + if v, ok := setting["microsoft"]; ok { + microsoftSettings := v.([]interface{}) + microsoftSetting := microsoftSettings[0].(map[string]interface{}) + + if v, ok := microsoftSetting["client_id"]; ok { + siteAuthSettingsProperties.MicrosoftAccountClientID = utils.String(v.(string)) + } + + if v, ok := microsoftSetting["client_secret"]; ok { + siteAuthSettingsProperties.MicrosoftAccountClientSecret = utils.String(v.(string)) + } + + if v, ok := microsoftSetting["oauth_scopes"]; ok { + input := v.([]interface{}) + + oauthScopes := make([]string, 0) + for _, param := range input { + oauthScopes = append(oauthScopes, param.(string)) + } + + siteAuthSettingsProperties.MicrosoftAccountOAuthScopes = &oauthScopes + } + } + + if v, ok := setting["twitter"]; ok { + twitterSettings := v.([]interface{}) + twitterSetting := twitterSettings[0].(map[string]interface{}) + + if v, ok := twitterSetting["consumer_key"]; ok { + siteAuthSettingsProperties.TwitterConsumerKey = utils.String(v.(string)) + } + + if v, ok := twitterSetting["consumer_secret"]; ok { + siteAuthSettingsProperties.TwitterConsumerSecret = utils.String(v.(string)) + } + } + return siteAuthSettingsProperties } From 8b93fc8167588c351ff32a517480f36c29194fd9 Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 11:58:44 +0100 Subject: [PATCH 13/38] Add facebook, google, microsoft and twitter to flatten --- azurerm/helpers/azure/app_service.go | 68 +++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/azurerm/helpers/azure/app_service.go b/azurerm/helpers/azure/app_service.go index 8132561e80ec..6364d3573a09 100644 --- a/azurerm/helpers/azure/app_service.go +++ b/azurerm/helpers/azure/app_service.go @@ -804,11 +804,11 @@ func FlattenAppServiceAuthSettings(input *web.SiteAuthSettingsProperties) []inte activeDirectorySetting := make(map[string]interface{}) if input.ClientID != nil { - activeDirectorySetting["client_id"] = input.ClientID + activeDirectorySetting["client_id"] = *input.ClientID } if input.ClientSecret != nil { - activeDirectorySetting["client_secret"] = input.ClientSecret + activeDirectorySetting["client_secret"] = *input.ClientSecret } if s := input.AllowedAudiences; s != nil { @@ -817,6 +817,70 @@ func FlattenAppServiceAuthSettings(input *web.SiteAuthSettingsProperties) []inte result["active_directory"] = append(activeDirectorySettings, activeDirectorySetting) + facebookSettings := make([]interface{}, 0) + facebookSetting := make(map[string]interface{}) + + if input.FacebookAppID != nil { + facebookSetting["app_id"] = *input.FacebookAppID + } + + if input.FacebookAppSecret != nil { + facebookSetting["app_secret"] = *input.FacebookAppSecret + } + + if s := input.FacebookOAuthScopes; s != nil { + facebookSetting["oauth_scopes"] = *s + } + + result["facebook"] = append(facebookSettings, facebookSetting) + + googleSettings := make([]interface{}, 0) + googleSetting := make(map[string]interface{}) + + if input.GoogleClientID != nil { + googleSetting["client_id"] = *input.GoogleClientID + } + + if input.GoogleClientSecret != nil { + googleSetting["client_secret"] = *input.GoogleClientSecret + } + + if s := input.GoogleOAuthScopes; s != nil { + googleSetting["oauth_scopes"] = *s + } + + result["google"] = append(googleSettings, googleSetting) + + microsoftSettings := make([]interface{}, 0) + microsoftSetting := make(map[string]interface{}) + + if input.MicrosoftAccountClientID != nil { + microsoftSetting["client_id"] = *input.MicrosoftAccountClientID + } + + if input.MicrosoftAccountClientSecret != nil { + microsoftSetting["client_secret"] = *input.MicrosoftAccountClientSecret + } + + if s := input.MicrosoftAccountOAuthScopes; s != nil { + microsoftSetting["oauth_scopes"] = *s + } + + result["microsoft"] = append(microsoftSettings, microsoftSetting) + + twitterSettings := make([]interface{}, 0) + twitterSetting := make(map[string]interface{}) + + if input.TwitterConsumerKey != nil { + twitterSetting["consumer_key"] = *input.TwitterConsumerKey + } + + if input.TwitterConsumerSecret != nil { + twitterSetting["consumer_secret"] = *input.TwitterConsumerSecret + } + + result["twitter"] = append(twitterSettings, twitterSetting) + return append(results, result) } From 92ed8b0703983312e9f7cfa59ccf4d8a6e11f72b Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 13:05:39 +0100 Subject: [PATCH 14/38] Add remaining main auth properties --- azurerm/helpers/azure/app_service.go | 47 +++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/azurerm/helpers/azure/app_service.go b/azurerm/helpers/azure/app_service.go index 6364d3573a09..60b607a7da96 100644 --- a/azurerm/helpers/azure/app_service.go +++ b/azurerm/helpers/azure/app_service.go @@ -164,11 +164,11 @@ func SchemaAppServiceAuthSettings() *schema.Schema { Type: schema.TypeString, Optional: true, ValidateFunc: validation.StringInSlice([]string{ - "AzureActiveDirectory", - "Facebook", - "Google", - "MicrosoftAccount", - "Twitter", + string(web.AzureActiveDirectory), + string(web.Facebook), + string(web.Google), + string(web.MicrosoftAccount), + string(web.Twitter), }, true), DiffSuppressFunc: suppress.CaseDifference, }, @@ -181,7 +181,7 @@ func SchemaAppServiceAuthSettings() *schema.Schema { Optional: true, }, "token_refresh_extension_hours": { - Type: schema.TypeInt, + Type: schema.TypeFloat, Optional: true, Default: 72, }, @@ -189,8 +189,8 @@ func SchemaAppServiceAuthSettings() *schema.Schema { Type: schema.TypeString, Optional: true, ValidateFunc: validation.StringInSlice([]string{ - "AllowAnonymous", - "RedirectToLoginPage", + string(web.AllowAnonymous), + string(web.RedirectToLoginPage), }, true), DiffSuppressFunc: suppress.CaseDifference, }, @@ -669,6 +669,37 @@ func ExpandAppServiceAuthSettings(input interface{}) web.SiteAuthSettingsPropert siteAuthSettingsProperties.AdditionalLoginParams = &additionalLoginParams } + if v, ok := setting["allowed_external_redirect_urls"]; ok { + input := v.([]interface{}) + + allowedExternalRedirectUrls := make([]string, 0) + for _, param := range input { + allowedExternalRedirectUrls = append(allowedExternalRedirectUrls, param.(string)) + } + + siteAuthSettingsProperties.AllowedExternalRedirectUrls = &allowedExternalRedirectUrls + } + + if v, ok := setting["default_provider"]; ok { + siteAuthSettingsProperties.DefaultProvider = web.BuiltInAuthenticationProvider(v.(string)) + } + + if v, ok := setting["issuer"]; ok { + siteAuthSettingsProperties.Issuer = utils.String(v.(string)) + } + + if v, ok := setting["runtime_version"]; ok { + siteAuthSettingsProperties.RuntimeVersion = utils.String(v.(string)) + } + + if v, ok := setting["token_refresh_extension_hours"]; ok { + siteAuthSettingsProperties.TokenRefreshExtensionHours = utils.Float(v.(float64)) + } + + if v, ok := setting["unauthenticated_client_action"]; ok { + siteAuthSettingsProperties.UnauthenticatedClientAction = web.UnauthenticatedClientAction(v.(string)) + } + if v, ok := setting["active_directory"]; ok { activeDirectorySettings := v.([]interface{}) activeDirectorySetting := activeDirectorySettings[0].(map[string]interface{}) From 018ea100e414161f4e708246874327df688465f0 Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 13:28:57 +0100 Subject: [PATCH 15/38] Add remaining auth settings to flatten function --- azurerm/helpers/azure/app_service.go | 32 ++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/azurerm/helpers/azure/app_service.go b/azurerm/helpers/azure/app_service.go index 60b607a7da96..0cb83ef43756 100644 --- a/azurerm/helpers/azure/app_service.go +++ b/azurerm/helpers/azure/app_service.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -173,8 +174,9 @@ func SchemaAppServiceAuthSettings() *schema.Schema { DiffSuppressFunc: suppress.CaseDifference, }, "issuer": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.URLIsHTTPOrHTTPS, }, "runtime_version": { Type: schema.TypeString, @@ -831,6 +833,32 @@ func FlattenAppServiceAuthSettings(input *web.SiteAuthSettingsProperties) []inte } result["additional_login_params"] = additionalLoginParams + allowedExternalRedirectUrls := make([]string, 0) + if s := input.AllowedExternalRedirectUrls; s != nil { + allowedExternalRedirectUrls = *s + } + result["allowed_external_redirect_urls"] = allowedExternalRedirectUrls + + if input.DefaultProvider != "" { + result["default_provider"] = input.DefaultProvider + } + + if input.Issuer != nil { + result["issuer"] = *input.Issuer + } + + if input.RuntimeVersion != nil { + result["runtime_version"] = *input.RuntimeVersion + } + + if input.TokenRefreshExtensionHours != nil { + result["token_refresh_extension_hours"] = *input.TokenRefreshExtensionHours + } + + if input.UnauthenticatedClientAction != "" { + result["unauthenticated_client_action"] = input.UnauthenticatedClientAction + } + activeDirectorySettings := make([]interface{}, 0) activeDirectorySetting := make(map[string]interface{}) From eb7a1042493248c872c247d3772081245d84f94f Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 15:18:17 +0100 Subject: [PATCH 16/38] Add check for providers --- azurerm/helpers/azure/app_service.go | 108 +++++++++++++++------------ 1 file changed, 60 insertions(+), 48 deletions(-) diff --git a/azurerm/helpers/azure/app_service.go b/azurerm/helpers/azure/app_service.go index 0cb83ef43756..c18c94b394e3 100644 --- a/azurerm/helpers/azure/app_service.go +++ b/azurerm/helpers/azure/app_service.go @@ -728,86 +728,98 @@ func ExpandAppServiceAuthSettings(input interface{}) web.SiteAuthSettingsPropert if v, ok := setting["facebook"]; ok { facebookSettings := v.([]interface{}) - facebookSetting := facebookSettings[0].(map[string]interface{}) - if v, ok := facebookSetting["app_id"]; ok { - siteAuthSettingsProperties.FacebookAppID = utils.String(v.(string)) - } - - if v, ok := facebookSetting["app_secret"]; ok { - siteAuthSettingsProperties.FacebookAppSecret = utils.String(v.(string)) - } + if len(facebookSettings) > 0 { + facebookSetting := facebookSettings[0].(map[string]interface{}) - if v, ok := facebookSetting["oauth_scopes"]; ok { - input := v.([]interface{}) + if v, ok := facebookSetting["app_id"]; ok { + siteAuthSettingsProperties.FacebookAppID = utils.String(v.(string)) + } - oauthScopes := make([]string, 0) - for _, param := range input { - oauthScopes = append(oauthScopes, param.(string)) + if v, ok := facebookSetting["app_secret"]; ok { + siteAuthSettingsProperties.FacebookAppSecret = utils.String(v.(string)) } - siteAuthSettingsProperties.FacebookOAuthScopes = &oauthScopes + if v, ok := facebookSetting["oauth_scopes"]; ok { + input := v.([]interface{}) + + oauthScopes := make([]string, 0) + for _, param := range input { + oauthScopes = append(oauthScopes, param.(string)) + } + + siteAuthSettingsProperties.FacebookOAuthScopes = &oauthScopes + } } } if v, ok := setting["google"]; ok { googleSettings := v.([]interface{}) - googleSetting := googleSettings[0].(map[string]interface{}) - - if v, ok := googleSetting["client_id"]; ok { - siteAuthSettingsProperties.GoogleClientID = utils.String(v.(string)) - } - if v, ok := googleSetting["client_secret"]; ok { - siteAuthSettingsProperties.GoogleClientSecret = utils.String(v.(string)) - } + if len(googleSettings) > 0 { + googleSetting := googleSettings[0].(map[string]interface{}) - if v, ok := googleSetting["oauth_scopes"]; ok { - input := v.([]interface{}) + if v, ok := googleSetting["client_id"]; ok { + siteAuthSettingsProperties.GoogleClientID = utils.String(v.(string)) + } - oauthScopes := make([]string, 0) - for _, param := range input { - oauthScopes = append(oauthScopes, param.(string)) + if v, ok := googleSetting["client_secret"]; ok { + siteAuthSettingsProperties.GoogleClientSecret = utils.String(v.(string)) } - siteAuthSettingsProperties.GoogleOAuthScopes = &oauthScopes + if v, ok := googleSetting["oauth_scopes"]; ok { + input := v.([]interface{}) + + oauthScopes := make([]string, 0) + for _, param := range input { + oauthScopes = append(oauthScopes, param.(string)) + } + + siteAuthSettingsProperties.GoogleOAuthScopes = &oauthScopes + } } } if v, ok := setting["microsoft"]; ok { microsoftSettings := v.([]interface{}) - microsoftSetting := microsoftSettings[0].(map[string]interface{}) - if v, ok := microsoftSetting["client_id"]; ok { - siteAuthSettingsProperties.MicrosoftAccountClientID = utils.String(v.(string)) - } + if len(microsoftSettings) > 0 { + microsoftSetting := microsoftSettings[0].(map[string]interface{}) - if v, ok := microsoftSetting["client_secret"]; ok { - siteAuthSettingsProperties.MicrosoftAccountClientSecret = utils.String(v.(string)) - } - - if v, ok := microsoftSetting["oauth_scopes"]; ok { - input := v.([]interface{}) + if v, ok := microsoftSetting["client_id"]; ok { + siteAuthSettingsProperties.MicrosoftAccountClientID = utils.String(v.(string)) + } - oauthScopes := make([]string, 0) - for _, param := range input { - oauthScopes = append(oauthScopes, param.(string)) + if v, ok := microsoftSetting["client_secret"]; ok { + siteAuthSettingsProperties.MicrosoftAccountClientSecret = utils.String(v.(string)) } - siteAuthSettingsProperties.MicrosoftAccountOAuthScopes = &oauthScopes + if v, ok := microsoftSetting["oauth_scopes"]; ok { + input := v.([]interface{}) + + oauthScopes := make([]string, 0) + for _, param := range input { + oauthScopes = append(oauthScopes, param.(string)) + } + + siteAuthSettingsProperties.MicrosoftAccountOAuthScopes = &oauthScopes + } } } if v, ok := setting["twitter"]; ok { twitterSettings := v.([]interface{}) - twitterSetting := twitterSettings[0].(map[string]interface{}) - if v, ok := twitterSetting["consumer_key"]; ok { - siteAuthSettingsProperties.TwitterConsumerKey = utils.String(v.(string)) - } + if len(twitterSettings) > 0 { + twitterSetting := twitterSettings[0].(map[string]interface{}) + + if v, ok := twitterSetting["consumer_key"]; ok { + siteAuthSettingsProperties.TwitterConsumerKey = utils.String(v.(string)) + } - if v, ok := twitterSetting["consumer_secret"]; ok { - siteAuthSettingsProperties.TwitterConsumerSecret = utils.String(v.(string)) + if v, ok := twitterSetting["consumer_secret"]; ok { + siteAuthSettingsProperties.TwitterConsumerSecret = utils.String(v.(string)) + } } } From 3e117c89d1d685b60ef35c122aad43d3b463539d Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 15:18:37 +0100 Subject: [PATCH 17/38] Add acctest for Active Directory authentication --- azurerm/resource_arm_app_service_test.go | 84 ++++++++++++++++++++++-- 1 file changed, 78 insertions(+), 6 deletions(-) diff --git a/azurerm/resource_arm_app_service_test.go b/azurerm/resource_arm_app_service_test.go index 000892b41011..7189fa1ba614 100644 --- a/azurerm/resource_arm_app_service_test.go +++ b/azurerm/resource_arm_app_service_test.go @@ -2,13 +2,14 @@ package azurerm import ( "fmt" + "os" "testing" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" - + "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -1329,6 +1330,37 @@ func TestAccAzureRMAppService_corsSettings(t *testing.T) { }) } +func TestAccAzureRMAppService_aadAuthSettings(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := acctest.RandInt() + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppService_aadAuthSettings(ri, testLocation(), tenantID) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testCheckAzureRMAppServiceDestroy(s *terraform.State) error { client := testAccProvider.Meta().(*ArmClient).appServicesClient @@ -2635,24 +2667,20 @@ resource "azurerm_resource_group" "test" { name = "acctestRG-%d" location = "%s" } - resource "azurerm_app_service_plan" "test" { name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" - sku { tier = "Standard" size = "S1" } } - resource "azurerm_app_service" "test" { name = "acctestAS-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" - site_config { cors { allowed_origins = [ @@ -2666,3 +2694,47 @@ resource "azurerm_app_service" "test" { } `, rInt, location, rInt, rInt) } + +func testAccAzureRMAppService_aadAuthSettings(rInt int, location string, tenantID string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + + sku { + tier = "Standard" + size = "S1" + } +} +resource "azurerm_app_service" "test" { + name = "acctestRG-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + site_config { + always_on = true + } + + auth_settings { + enabled = true + issuer = "https://sts.windows.net/%s" + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "activedirectorytokenaudiences", + ] + } + } +} +`, rInt, location, rInt, rInt, tenantID) +} From 9e042e60e981f0fdae523a26f7ad3239a955e4ed Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 15:27:22 +0100 Subject: [PATCH 18/38] Add missing check for Active Directory authentication --- azurerm/helpers/azure/app_service.go | 31 +++++++++++++++------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/azurerm/helpers/azure/app_service.go b/azurerm/helpers/azure/app_service.go index c18c94b394e3..675f74fd3bf7 100644 --- a/azurerm/helpers/azure/app_service.go +++ b/azurerm/helpers/azure/app_service.go @@ -704,25 +704,28 @@ func ExpandAppServiceAuthSettings(input interface{}) web.SiteAuthSettingsPropert if v, ok := setting["active_directory"]; ok { activeDirectorySettings := v.([]interface{}) - activeDirectorySetting := activeDirectorySettings[0].(map[string]interface{}) - if v, ok := activeDirectorySetting["client_id"]; ok { - siteAuthSettingsProperties.ClientID = utils.String(v.(string)) - } - - if v, ok := activeDirectorySetting["client_secret"]; ok { - siteAuthSettingsProperties.ClientSecret = utils.String(v.(string)) - } + if len(activeDirectorySettings) > 0 { + activeDirectorySetting := activeDirectorySettings[0].(map[string]interface{}) - if v, ok := activeDirectorySetting["allowed_audiences"]; ok { - input := v.([]interface{}) + if v, ok := activeDirectorySetting["client_id"]; ok { + siteAuthSettingsProperties.ClientID = utils.String(v.(string)) + } - allowedAudiences := make([]string, 0) - for _, param := range input { - allowedAudiences = append(allowedAudiences, param.(string)) + if v, ok := activeDirectorySetting["client_secret"]; ok { + siteAuthSettingsProperties.ClientSecret = utils.String(v.(string)) } - siteAuthSettingsProperties.AllowedAudiences = &allowedAudiences + if v, ok := activeDirectorySetting["allowed_audiences"]; ok { + input := v.([]interface{}) + + allowedAudiences := make([]string, 0) + for _, param := range input { + allowedAudiences = append(allowedAudiences, param.(string)) + } + + siteAuthSettingsProperties.AllowedAudiences = &allowedAudiences + } } } From 8c799b9fbf37ed3669c0ec332afc3a71aaf12b05 Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 15:28:30 +0100 Subject: [PATCH 19/38] Add acctest for Facebook authentication --- azurerm/resource_arm_app_service_test.go | 72 ++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/azurerm/resource_arm_app_service_test.go b/azurerm/resource_arm_app_service_test.go index 7189fa1ba614..916c60ff06d8 100644 --- a/azurerm/resource_arm_app_service_test.go +++ b/azurerm/resource_arm_app_service_test.go @@ -1361,6 +1361,35 @@ func TestAccAzureRMAppService_aadAuthSettings(t *testing.T) { }) } +func TestAccAzureRMAppService_facebookAuthSettings(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := acctest.RandInt() + config := testAccAzureRMAppService_facebookAuthSettings(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.facebook.0.app_id", "facebookappid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.facebook.0.app_secret", "facebookappsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.facebook.0.oauth_scopes.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testCheckAzureRMAppServiceDestroy(s *terraform.State) error { client := testAccProvider.Meta().(*ArmClient).appServicesClient @@ -2738,3 +2767,46 @@ resource "azurerm_app_service" "test" { } `, rInt, location, rInt, rInt, tenantID) } + +func testAccAzureRMAppService_facebookAuthSettings(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + + sku { + tier = "Standard" + size = "S1" + } +} +resource "azurerm_app_service" "test" { + name = "acctestRG-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + site_config { + always_on = true + } + + auth_settings { + enabled = true + facebook { + app_id = "facebookappid" + app_secret = "facebookappsecret" + + oauth_scopes = [ + "facebookscope", + ] + } + } +} +`, rInt, location, rInt, rInt) +} From ac3ffc528e0aa8ce65cb7fd78193043a0032d1e4 Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 15:43:52 +0100 Subject: [PATCH 20/38] Add acctest for Google authentication --- azurerm/resource_arm_app_service_test.go | 72 ++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/azurerm/resource_arm_app_service_test.go b/azurerm/resource_arm_app_service_test.go index 916c60ff06d8..fe15a8fedd67 100644 --- a/azurerm/resource_arm_app_service_test.go +++ b/azurerm/resource_arm_app_service_test.go @@ -1390,6 +1390,35 @@ func TestAccAzureRMAppService_facebookAuthSettings(t *testing.T) { }) } +func TestAccAzureRMAppService_googleAuthSettings(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := acctest.RandInt() + config := testAccAzureRMAppService_googleAuthSettings(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.google.0.client_id", "googleclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.google.0.client_secret", "googleclientsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.google.0.oauth_scopes.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testCheckAzureRMAppServiceDestroy(s *terraform.State) error { client := testAccProvider.Meta().(*ArmClient).appServicesClient @@ -2810,3 +2839,46 @@ resource "azurerm_app_service" "test" { } `, rInt, location, rInt, rInt) } + +func testAccAzureRMAppService_googleAuthSettings(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + + sku { + tier = "Standard" + size = "S1" + } +} +resource "azurerm_app_service" "test" { + name = "acctestRG-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + site_config { + always_on = true + } + + auth_settings { + enabled = true + google { + client_id = "googleclientid" + client_secret = "googleclientsecret" + + oauth_scopes = [ + "googlescope", + ] + } + } +} +`, rInt, location, rInt, rInt) +} From e0912fc144457a864bd0e3a00894b69e126e2f4b Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 15:49:08 +0100 Subject: [PATCH 21/38] Add acctest for Microsoft authentication --- azurerm/resource_arm_app_service_test.go | 72 ++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/azurerm/resource_arm_app_service_test.go b/azurerm/resource_arm_app_service_test.go index fe15a8fedd67..d1d7db9c7a95 100644 --- a/azurerm/resource_arm_app_service_test.go +++ b/azurerm/resource_arm_app_service_test.go @@ -1419,6 +1419,35 @@ func TestAccAzureRMAppService_googleAuthSettings(t *testing.T) { }) } +func TestAccAzureRMAppService_microsoftAuthSettings(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := acctest.RandInt() + config := testAccAzureRMAppService_microsoftAuthSettings(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.microsoft.0.client_id", "microsoftclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.microsoft.0.client_secret", "microsoftclientsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.microsoft.0.oauth_scopes.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testCheckAzureRMAppServiceDestroy(s *terraform.State) error { client := testAccProvider.Meta().(*ArmClient).appServicesClient @@ -2882,3 +2911,46 @@ resource "azurerm_app_service" "test" { } `, rInt, location, rInt, rInt) } + +func testAccAzureRMAppService_microsoftAuthSettings(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + + sku { + tier = "Standard" + size = "S1" + } +} +resource "azurerm_app_service" "test" { + name = "acctestRG-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + site_config { + always_on = true + } + + auth_settings { + enabled = true + microsoft { + client_id = "microsoftclientid" + client_secret = "microsoftclientsecret" + + oauth_scopes = [ + "microsoftscope", + ] + } + } +} +`, rInt, location, rInt, rInt) +} From 6c32a36cb6ac068f960898604811c106d76813cd Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 15:53:57 +0100 Subject: [PATCH 22/38] Add acctest for Twitter authentication --- azurerm/resource_arm_app_service_test.go | 67 ++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/azurerm/resource_arm_app_service_test.go b/azurerm/resource_arm_app_service_test.go index d1d7db9c7a95..e78795d43989 100644 --- a/azurerm/resource_arm_app_service_test.go +++ b/azurerm/resource_arm_app_service_test.go @@ -1448,6 +1448,34 @@ func TestAccAzureRMAppService_microsoftAuthSettings(t *testing.T) { }) } +func TestAccAzureRMAppService_twitterAuthSettings(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := acctest.RandInt() + config := testAccAzureRMAppService_twitterAuthSettings(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.twitter.0.consumer_key", "twitterconsumerkey"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.twitter.0.consumer_secret", "twitterconsumersecret"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testCheckAzureRMAppServiceDestroy(s *terraform.State) error { client := testAccProvider.Meta().(*ArmClient).appServicesClient @@ -2954,3 +2982,42 @@ resource "azurerm_app_service" "test" { } `, rInt, location, rInt, rInt) } + +func testAccAzureRMAppService_twitterAuthSettings(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + + sku { + tier = "Standard" + size = "S1" + } +} +resource "azurerm_app_service" "test" { + name = "acctestRG-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + site_config { + always_on = true + } + + auth_settings { + enabled = true + twitter { + consumer_key = "twitterconsumerkey" + consumer_secret = "twitterconsumersecret" + } + } +} +`, rInt, location, rInt, rInt) +} From 64f9c9859ef7dcd4e67f3f697a8ad3b5ba39a831 Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 16:34:40 +0100 Subject: [PATCH 23/38] RandInt -> AccRandTimeInt --- azurerm/resource_arm_app_service_test.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/azurerm/resource_arm_app_service_test.go b/azurerm/resource_arm_app_service_test.go index e78795d43989..214328b5201f 100644 --- a/azurerm/resource_arm_app_service_test.go +++ b/azurerm/resource_arm_app_service_test.go @@ -5,7 +5,6 @@ import ( "os" "testing" - "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" @@ -1332,7 +1331,7 @@ func TestAccAzureRMAppService_corsSettings(t *testing.T) { func TestAccAzureRMAppService_aadAuthSettings(t *testing.T) { resourceName := "azurerm_app_service.test" - ri := acctest.RandInt() + ri := tf.AccRandTimeInt() tenantID := os.Getenv("ARM_TENANT_ID") config := testAccAzureRMAppService_aadAuthSettings(ri, testLocation(), tenantID) @@ -1363,7 +1362,7 @@ func TestAccAzureRMAppService_aadAuthSettings(t *testing.T) { func TestAccAzureRMAppService_facebookAuthSettings(t *testing.T) { resourceName := "azurerm_app_service.test" - ri := acctest.RandInt() + ri := tf.AccRandTimeInt() config := testAccAzureRMAppService_facebookAuthSettings(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ @@ -1392,7 +1391,7 @@ func TestAccAzureRMAppService_facebookAuthSettings(t *testing.T) { func TestAccAzureRMAppService_googleAuthSettings(t *testing.T) { resourceName := "azurerm_app_service.test" - ri := acctest.RandInt() + ri := tf.AccRandTimeInt() config := testAccAzureRMAppService_googleAuthSettings(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ @@ -1421,7 +1420,7 @@ func TestAccAzureRMAppService_googleAuthSettings(t *testing.T) { func TestAccAzureRMAppService_microsoftAuthSettings(t *testing.T) { resourceName := "azurerm_app_service.test" - ri := acctest.RandInt() + ri := tf.AccRandTimeInt() config := testAccAzureRMAppService_microsoftAuthSettings(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ @@ -1450,7 +1449,7 @@ func TestAccAzureRMAppService_microsoftAuthSettings(t *testing.T) { func TestAccAzureRMAppService_twitterAuthSettings(t *testing.T) { resourceName := "azurerm_app_service.test" - ri := acctest.RandInt() + ri := tf.AccRandTimeInt() config := testAccAzureRMAppService_twitterAuthSettings(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ From 806d98b8da9d11290b6f019d0bd8e08c15aeb26a Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 17:37:15 +0100 Subject: [PATCH 24/38] Check for nil interfaces in different auth settings --- azurerm/helpers/azure/app_service.go | 40 +++++++++++++++++++++------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/azurerm/helpers/azure/app_service.go b/azurerm/helpers/azure/app_service.go index 675f74fd3bf7..b658759d0dab 100644 --- a/azurerm/helpers/azure/app_service.go +++ b/azurerm/helpers/azure/app_service.go @@ -705,8 +705,12 @@ func ExpandAppServiceAuthSettings(input interface{}) web.SiteAuthSettingsPropert if v, ok := setting["active_directory"]; ok { activeDirectorySettings := v.([]interface{}) - if len(activeDirectorySettings) > 0 { - activeDirectorySetting := activeDirectorySettings[0].(map[string]interface{}) + for _, setting := range activeDirectorySettings { + if setting == nil { + continue + } + + activeDirectorySetting := setting.(map[string]interface{}) if v, ok := activeDirectorySetting["client_id"]; ok { siteAuthSettingsProperties.ClientID = utils.String(v.(string)) @@ -732,8 +736,12 @@ func ExpandAppServiceAuthSettings(input interface{}) web.SiteAuthSettingsPropert if v, ok := setting["facebook"]; ok { facebookSettings := v.([]interface{}) - if len(facebookSettings) > 0 { - facebookSetting := facebookSettings[0].(map[string]interface{}) + for _, setting := range facebookSettings { + if setting == nil { + continue + } + + facebookSetting := setting.(map[string]interface{}) if v, ok := facebookSetting["app_id"]; ok { siteAuthSettingsProperties.FacebookAppID = utils.String(v.(string)) @@ -759,8 +767,12 @@ func ExpandAppServiceAuthSettings(input interface{}) web.SiteAuthSettingsPropert if v, ok := setting["google"]; ok { googleSettings := v.([]interface{}) - if len(googleSettings) > 0 { - googleSetting := googleSettings[0].(map[string]interface{}) + for _, setting := range googleSettings { + if setting == nil { + continue + } + + googleSetting := setting.(map[string]interface{}) if v, ok := googleSetting["client_id"]; ok { siteAuthSettingsProperties.GoogleClientID = utils.String(v.(string)) @@ -786,8 +798,12 @@ func ExpandAppServiceAuthSettings(input interface{}) web.SiteAuthSettingsPropert if v, ok := setting["microsoft"]; ok { microsoftSettings := v.([]interface{}) - if len(microsoftSettings) > 0 { - microsoftSetting := microsoftSettings[0].(map[string]interface{}) + for _, setting := range microsoftSettings { + if setting == nil { + continue + } + + microsoftSetting := setting.(map[string]interface{}) if v, ok := microsoftSetting["client_id"]; ok { siteAuthSettingsProperties.MicrosoftAccountClientID = utils.String(v.(string)) @@ -813,8 +829,12 @@ func ExpandAppServiceAuthSettings(input interface{}) web.SiteAuthSettingsPropert if v, ok := setting["twitter"]; ok { twitterSettings := v.([]interface{}) - if len(twitterSettings) > 0 { - twitterSetting := twitterSettings[0].(map[string]interface{}) + for _, setting := range twitterSettings { + if setting == nil { + continue + } + + twitterSetting := setting.(map[string]interface{}) if v, ok := twitterSetting["consumer_key"]; ok { siteAuthSettingsProperties.TwitterConsumerKey = utils.String(v.(string)) From 0889395e0dc22889c4913ec3c24785f2469d851b Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 17:37:55 +0100 Subject: [PATCH 25/38] Add acc test for multiple authentication providers --- azurerm/resource_arm_app_service_test.go | 108 +++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/azurerm/resource_arm_app_service_test.go b/azurerm/resource_arm_app_service_test.go index 214328b5201f..9b702b23cf94 100644 --- a/azurerm/resource_arm_app_service_test.go +++ b/azurerm/resource_arm_app_service_test.go @@ -5,6 +5,8 @@ import ( "os" "testing" + "github.com/Azure/azure-sdk-for-go/services/web/mgmt/2018-02-01/web" + "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" @@ -1475,6 +1477,57 @@ func TestAccAzureRMAppService_twitterAuthSettings(t *testing.T) { }) } +func TestAccAzureRMAppService_multiAuthSettings(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + tenantID := os.Getenv("ARM_TENANT_ID") + config1 := testAccAzureRMAppService_aadAuthSettings(ri, testLocation(), tenantID) + config2 := testAccAzureRMAppService_aadMicrosoftAuthSettings(ri, testLocation(), tenantID) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config1, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: config2, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.microsoft.0.client_id", "microsoftclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.microsoft.0.client_secret", "microsoftclientsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.microsoft.0.oauth_scopes.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testCheckAzureRMAppServiceDestroy(s *terraform.State) error { client := testAccProvider.Meta().(*ArmClient).appServicesClient @@ -3020,3 +3073,58 @@ resource "azurerm_app_service" "test" { } `, rInt, location, rInt, rInt) } + +func testAccAzureRMAppService_aadMicrosoftAuthSettings(rInt int, location string, tenantID string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + + sku { + tier = "Standard" + size = "S1" + } +} +resource "azurerm_app_service" "test" { + name = "acctestRG-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + site_config { + always_on = true + } + + auth_settings { + enabled = true + issuer = "https://sts.windows.net/%s" + default_provider = "%s" + + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "activedirectorytokenaudiences", + ] + } + + microsoft { + client_id = "microsoftclientid" + client_secret = "microsoftclientsecret" + + oauth_scopes = [ + "microsoftscope", + ] + } + } +} +`, rInt, location, rInt, rInt, tenantID, web.AzureActiveDirectory) +} From 651917150d6507363947aa722d04327f71f004e3 Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 18:42:01 +0100 Subject: [PATCH 26/38] Add acctests for remaining main auth settings --- azurerm/resource_arm_app_service_test.go | 366 +++++++++++++++++++++++ 1 file changed, 366 insertions(+) diff --git a/azurerm/resource_arm_app_service_test.go b/azurerm/resource_arm_app_service_test.go index 9b702b23cf94..166ae6aebfda 100644 --- a/azurerm/resource_arm_app_service_test.go +++ b/azurerm/resource_arm_app_service_test.go @@ -1331,6 +1331,136 @@ func TestAccAzureRMAppService_corsSettings(t *testing.T) { }) } +func TestAccAzureRMAppService_authSettingsAdditionalLoginParams(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppService_authSettingsAdditionalLoginParams(ri, testLocation(), tenantID) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.additional_login_params.#", "1"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.additional_login_params.0", "someloginparam"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAppService_authSettingsAdditionalAllowedExternalRedirectUrls(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppService_authSettingsAdditionalAllowedExternalRedirectUrls(ri, testLocation(), tenantID) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.allowed_external_redirect_urls.#", "1"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.allowed_external_redirect_urls.0", "https://terra.form"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAppService_authSettingsTokenRefreshExtensionHours(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppService_authSettingsTokenRefreshExtensionHours(ri, testLocation(), tenantID) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.token_refresh_extension_hours", "75"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAppService_authSettingsUnauthenticatedClientAction(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppService_authSettingsUnauthenticatedClientAction(ri, testLocation(), tenantID) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.unauthenticated_client_action", "RedirectToLoginPage"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAzureRMAppService_aadAuthSettings(t *testing.T) { resourceName := "azurerm_app_service.test" ri := tf.AccRandTimeInt() @@ -2862,6 +2992,242 @@ resource "azurerm_app_service" "test" { `, rInt, location, rInt, rInt) } +func testAccAzureRMAppService_authSettingsAdditionalLoginParams(rInt int, location string, tenantID string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + + sku { + tier = "Standard" + size = "S1" + } +} +resource "azurerm_app_service" "test" { + name = "acctestRG-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + site_config { + always_on = true + } + + auth_settings { + enabled = true + issuer = "https://sts.windows.net/%s" + + additional_login_params = [ + "someloginparam" + ] + + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "activedirectorytokenaudiences", + ] + } + } +} +`, rInt, location, rInt, rInt, tenantID) +} + +func testAccAzureRMAppService_authSettingsAdditionalAllowedExternalRedirectUrls(rInt int, location string, tenantID string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + + sku { + tier = "Standard" + size = "S1" + } +} +resource "azurerm_app_service" "test" { + name = "acctestRG-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + site_config { + always_on = true + } + + auth_settings { + enabled = true + issuer = "https://sts.windows.net/%s" + + allowed_external_redirect_urls = [ + "https://terra.form" + ] + + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "activedirectorytokenaudiences", + ] + } + } +} +`, rInt, location, rInt, rInt, tenantID) +} + +func testAccAzureRMAppService_authSettingsRuntimeVersion(rInt int, location string, tenantID string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + + sku { + tier = "Standard" + size = "S1" + } +} +resource "azurerm_app_service" "test" { + name = "acctestRG-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + site_config { + always_on = true + } + + auth_settings { + enabled = true + issuer = "https://sts.windows.net/%s" + runtime_version = "1.0" + + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "activedirectorytokenaudiences", + ] + } + } +} +`, rInt, location, rInt, rInt, tenantID) +} + +func testAccAzureRMAppService_authSettingsTokenRefreshExtensionHours(rInt int, location string, tenantID string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + + sku { + tier = "Standard" + size = "S1" + } +} +resource "azurerm_app_service" "test" { + name = "acctestRG-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + site_config { + always_on = true + } + + auth_settings { + enabled = true + issuer = "https://sts.windows.net/%s" + token_refresh_extension_hours = 75 + + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "activedirectorytokenaudiences", + ] + } + } +} +`, rInt, location, rInt, rInt, tenantID) +} + +func testAccAzureRMAppService_authSettingsUnauthenticatedClientAction(rInt int, location string, tenantID string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + + sku { + tier = "Standard" + size = "S1" + } +} +resource "azurerm_app_service" "test" { + name = "acctestRG-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + site_config { + always_on = true + } + + auth_settings { + enabled = true + issuer = "https://sts.windows.net/%s" + unauthenticated_client_action = "RedirectToLoginPage" + + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "activedirectorytokenaudiences", + ] + } + } +} +`, rInt, location, rInt, rInt, tenantID) +} + func testAccAzureRMAppService_aadAuthSettings(rInt int, location string, tenantID string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { From 818881161a1e4de42bc58c101de13cd28267b95d Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 21:00:50 +0100 Subject: [PATCH 27/38] Add Authentication documentation --- website/docs/r/app_service.html.markdown | 178 +++++++++++++++++++++++ 1 file changed, 178 insertions(+) diff --git a/website/docs/r/app_service.html.markdown b/website/docs/r/app_service.html.markdown index 57d0e0584e61..a4b9c6b23163 100644 --- a/website/docs/r/app_service.html.markdown +++ b/website/docs/r/app_service.html.markdown @@ -57,6 +57,111 @@ resource "azurerm_app_service" "test" { } ``` +## Example Usage (Java 1.8) + +```hcl +resource "random_id" "server" { + keepers = { + azi_id = 1 + } + + byte_length = 8 +} + +resource "azurerm_resource_group" "test" { + name = "some-resource-group" + location = "West Europe" +} + +resource "azurerm_app_service_plan" "test" { + name = "some-app-service-plan" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "${random_id.server.hex}" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + site_config { + java_version = "1.8" + java_container = "JETTY" + java_container_version = "9.3" + scm_type = "LocalGit" + } +} +``` + +## Example Usage (Authentication) + +```hcl +resource "random_id" "server" { + keepers = { + azi_id = 1 + } + + byte_length = 8 +} + +resource "azurerm_resource_group" "test" { + name = "some-resource-group" + location = "West Europe" +} + +resource "azurerm_app_service_plan" "test" { + name = "some-app-service-plan" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "${random_id.server.hex}" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + site_config { + always_on = true + } + + auth_settings { + enabled = true + issuer = "https://sts.windows.net/d13958f6-b541-4dad-97b9-5a39c6b01297" + default_provider = "AzureActiveDirectory" + unauthenticated_client_action = "RedirectToLoginPage" + + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "someallowedaudience", + ] + } + + microsoft { + client_id = "microsoftclientid" + client_secret = "microsoftclientsecret" + + oauth_scopes = [ + "somescope", + ] + } +} +``` + ## Argument Reference The following arguments are supported: @@ -172,6 +277,79 @@ A `cors` block supports the following: --- Elements of `ip_restriction` support: +`auth_settings` supports the following: + +* `enabled` - (Required) Is Authentication enabled? + +* `additional_login_params` - (Optional) Login parameters to send to the OpenID Connect authorization endpoint when a user logs in. Each parameter must be in the form "key=value". + +* `allowed_external_redirect_urls` - (Optional) External URLs that can be redirected to as part of logging in or logging out of the app. + +~> **NOTE:** When providing multiple providers, the default provider must be set for settings like `unauthenticated_client_action` to work. + +* `default_provider` - (Optional) The default provider to use when multiple providers have been set up. Possible values are `AzureActiveDirectory`, `Facebook`, `Google`, `MicrosoftAccount` and `Twitter`. + +* `issuer` - (Optional) Issuer URI. When using Azure Active Directory, this value is the URI of the directory tenant, e.g. https://sts.windows.net/{tenant-guid}/. + +* `runtime_version` - (Optional) The runtime version of the Authentication/Authorization module. + +* `token_refresh_extension_hours` - (Optional) The number of hours after session token expiration that a session token can be used to call the token refresh API. Defaults to 72. + +* `unauthenticated_client_action` - (Optional) The action to take when an unauthenticated client attempts to access the app. Possible values are `AllowAnonymous` and `RedirectToLoginPage`. + +* `active_directory` - (Optional) Active directory Authentication configuration. + +* `facebook` - (Optional) Facebook Authentication configuration. + +* `google` - (Optional) Google Authentication configuration. + +* `microsoft` - (Optional) Microsoft Account Authentication configuration. + +* `twitter` - (Optional) Twitter Authentication configuration. + +--- + +`active_directory` supports the following: + +* `client_id` - (Required) The Client ID of this relying party application. Enables OpenIDConnection authentication with Azure Active Directory. + +* `client_secret` - (Optional) The Client Secret of this relying party application. If no secret is provided, implicit flow will be used. + +* `allowed_audiences` (Optional) Allowed audience values to consider when validating JWTs issued by Azure Active Directory. + +--- + +`facebook` supports the following: + +* `app_id` - (Required) The App ID of the Facebook app used for login + +* `app_secret` - (Required) The App Secret of the Facebook app used for Facebook Login. + +* `oauth_scopes` (Optional) The OAuth 2.0 scopes that will be requested as part of Facebook Login authentication. https://developers.facebook.com/docs/facebook-login + +--- + +`google` supports the following: + +* `client_id` - (Required) The OpenID Connect Client ID for the Google web application. + +* `client_secret` - (Required) The client secret associated with the Google web application. + +* `oauth_scopes` (Optional) The OAuth 2.0 scopes that will be requested as part of Google Sign-In authentication. https://developers.google.com/identity/sign-in/web/ + +--- + +`microsoft` supports the following: + +* `client_id` - (Required) The OAuth 2.0 client ID that was created for the app used for authentication. + +* `client_secret` - (Required) The OAuth 2.0 client secret that was created for the app used for authentication. + +* `oauth_scopes` (Optional) The OAuth 2.0 scopes that will be requested as part of Microsoft Account authentication. https://msdn.microsoft.com/en-us/library/dn631845.aspx + +--- + +`ip_restriction` supports the following: * `ip_address` - (Required) The IP Address used for this IP Restriction. From 380c63ce1f790223b22be2210d6fa8e43e38c06f Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 21:12:16 +0100 Subject: [PATCH 28/38] Add token_store_enabled setting --- azurerm/helpers/azure/app_service.go | 13 ++++ azurerm/resource_arm_app_service_test.go | 78 ++++++++++++++++++++++++ website/docs/r/app_service.html.markdown | 2 + 3 files changed, 93 insertions(+) diff --git a/azurerm/helpers/azure/app_service.go b/azurerm/helpers/azure/app_service.go index b658759d0dab..f402f01542d8 100644 --- a/azurerm/helpers/azure/app_service.go +++ b/azurerm/helpers/azure/app_service.go @@ -187,6 +187,11 @@ func SchemaAppServiceAuthSettings() *schema.Schema { Optional: true, Default: 72, }, + "token_store_enabled": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, "unauthenticated_client_action": { Type: schema.TypeString, Optional: true, @@ -698,6 +703,10 @@ func ExpandAppServiceAuthSettings(input interface{}) web.SiteAuthSettingsPropert siteAuthSettingsProperties.TokenRefreshExtensionHours = utils.Float(v.(float64)) } + if v, ok := setting["token_store_enabled"]; ok { + siteAuthSettingsProperties.TokenStoreEnabled = utils.Bool(v.(bool)) + } + if v, ok := setting["unauthenticated_client_action"]; ok { siteAuthSettingsProperties.UnauthenticatedClientAction = web.UnauthenticatedClientAction(v.(string)) } @@ -890,6 +899,10 @@ func FlattenAppServiceAuthSettings(input *web.SiteAuthSettingsProperties) []inte result["token_refresh_extension_hours"] = *input.TokenRefreshExtensionHours } + if input.TokenStoreEnabled != nil { + result["token_store_enabled"] = *input.TokenStoreEnabled + } + if input.UnauthenticatedClientAction != "" { result["unauthenticated_client_action"] = input.UnauthenticatedClientAction } diff --git a/azurerm/resource_arm_app_service_test.go b/azurerm/resource_arm_app_service_test.go index 166ae6aebfda..0959a5e84952 100644 --- a/azurerm/resource_arm_app_service_test.go +++ b/azurerm/resource_arm_app_service_test.go @@ -1461,6 +1461,38 @@ func TestAccAzureRMAppService_authSettingsUnauthenticatedClientAction(t *testing }) } +func TestAccAzureRMAppService_authSettingsTokenStoreEnabled(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppService_authSettingsTokenStoreEnabled(ri, testLocation(), tenantID) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.token_store_enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAzureRMAppService_aadAuthSettings(t *testing.T) { resourceName := "azurerm_app_service.test" ri := tf.AccRandTimeInt() @@ -3182,6 +3214,52 @@ resource "azurerm_app_service" "test" { `, rInt, location, rInt, rInt, tenantID) } +func testAccAzureRMAppService_authSettingsTokenStoreEnabled(rInt int, location string, tenantID string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + + sku { + tier = "Standard" + size = "S1" + } +} +resource "azurerm_app_service" "test" { + name = "acctestRG-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + site_config { + always_on = true + } + + auth_settings { + enabled = true + issuer = "https://sts.windows.net/%s" + token_store_enabled = true + + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "activedirectorytokenaudiences", + ] + } + } +} +`, rInt, location, rInt, rInt, tenantID) +} + func testAccAzureRMAppService_authSettingsUnauthenticatedClientAction(rInt int, location string, tenantID string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { diff --git a/website/docs/r/app_service.html.markdown b/website/docs/r/app_service.html.markdown index a4b9c6b23163..7f1f2e128b3a 100644 --- a/website/docs/r/app_service.html.markdown +++ b/website/docs/r/app_service.html.markdown @@ -295,6 +295,8 @@ Elements of `ip_restriction` support: * `token_refresh_extension_hours` - (Optional) The number of hours after session token expiration that a session token can be used to call the token refresh API. Defaults to 72. +* `token_store_enabled` - (Optional) If enabled the module will durably store platform-specific security tokens that are obtained during login flows. Defaults to false. + * `unauthenticated_client_action` - (Optional) The action to take when an unauthenticated client attempts to access the app. Possible values are `AllowAnonymous` and `RedirectToLoginPage`. * `active_directory` - (Optional) Active directory Authentication configuration. From aebad28b4392c17e6b5c2cd36e6f2ca6c88c387e Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 21:52:17 +0100 Subject: [PATCH 29/38] Fix linting error when updating auth settings in read --- azurerm/resource_arm_app_service.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/azurerm/resource_arm_app_service.go b/azurerm/resource_arm_app_service.go index c7d7db070d34..b9a2bec87b0f 100644 --- a/azurerm/resource_arm_app_service.go +++ b/azurerm/resource_arm_app_service.go @@ -287,7 +287,9 @@ func resourceArmAppServiceCreate(d *schema.ResourceData, meta interface{}) error ID: read.ID, SiteAuthSettingsProperties: &authSettings} - client.UpdateAuthSettings(ctx, resGroup, name, auth) + if _, err := client.UpdateAuthSettings(ctx, resGroup, name, auth); err != nil { + return err + } return resourceArmAppServiceUpdate(d, meta) } From cc54d0990c9eb6fb4bacda7d6f6f82283e544742 Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Fri, 1 Feb 2019 22:08:47 +0100 Subject: [PATCH 30/38] Add missing acceptance test for runtime version --- azurerm/resource_arm_app_service_test.go | 32 ++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/azurerm/resource_arm_app_service_test.go b/azurerm/resource_arm_app_service_test.go index 0959a5e84952..6fa70c56e926 100644 --- a/azurerm/resource_arm_app_service_test.go +++ b/azurerm/resource_arm_app_service_test.go @@ -1397,6 +1397,38 @@ func TestAccAzureRMAppService_authSettingsAdditionalAllowedExternalRedirectUrls( }) } +func TestAccAzureRMAppService_authSettingsRuntimeVersion(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppService_authSettingsRuntimeVersion(ri, testLocation(), tenantID) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.runtime_version", "1.0"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAzureRMAppService_authSettingsTokenRefreshExtensionHours(t *testing.T) { resourceName := "azurerm_app_service.test" ri := tf.AccRandTimeInt() From 85a61bdff20e3d667df72d01fedc55625835b18c Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Tue, 23 Apr 2019 14:09:01 +0200 Subject: [PATCH 31/38] Update head and resolve comment about TypeMap for additional_login_params --- azurerm/helpers/azure/app_service.go | 30 ++++++++++++++++-------- azurerm/resource_arm_app_service_test.go | 9 ++++--- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/azurerm/helpers/azure/app_service.go b/azurerm/helpers/azure/app_service.go index f402f01542d8..d3b8bc660aad 100644 --- a/azurerm/helpers/azure/app_service.go +++ b/azurerm/helpers/azure/app_service.go @@ -1,6 +1,7 @@ package azure import ( + "fmt" "log" "net" "strings" @@ -152,9 +153,8 @@ func SchemaAppServiceAuthSettings() *schema.Schema { Sensitive: false, }, "additional_login_params": { - Type: schema.TypeList, + Type: schema.TypeMap, Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, }, "allowed_external_redirect_urls": { Type: schema.TypeList, @@ -666,11 +666,11 @@ func ExpandAppServiceAuthSettings(input interface{}) web.SiteAuthSettingsPropert } if v, ok := setting["additional_login_params"]; ok { - input := v.([]interface{}) + input := v.(map[string]interface{}) additionalLoginParams := make([]string, 0) - for _, param := range input { - additionalLoginParams = append(additionalLoginParams, param.(string)) + for k, v := range input { + additionalLoginParams = append(additionalLoginParams, fmt.Sprintf("%s=%s", k, v.(string))) } siteAuthSettingsProperties.AdditionalLoginParams = &additionalLoginParams @@ -858,6 +858,20 @@ func ExpandAppServiceAuthSettings(input interface{}) web.SiteAuthSettingsPropert return siteAuthSettingsProperties } +func FlattenAdditionalLoginParams(input *[]string) map[string]interface{} { + result := make(map[string]interface{}, len(*input)) + + for _, k := range *input { + parts := strings.Split(k, "=") + key := parts[0] + value := parts[1] + + result[key] = value + } + + return result +} + func FlattenAppServiceAuthSettings(input *web.SiteAuthSettingsProperties) []interface{} { results := make([]interface{}, 0) result := make(map[string]interface{}) @@ -871,11 +885,7 @@ func FlattenAppServiceAuthSettings(input *web.SiteAuthSettingsProperties) []inte result["enabled"] = *input.Enabled } - additionalLoginParams := make([]string, 0) - if s := input.AdditionalLoginParams; s != nil { - additionalLoginParams = *s - } - result["additional_login_params"] = additionalLoginParams + result["additional_login_params"] = FlattenAdditionalLoginParams(input.AdditionalLoginParams) allowedExternalRedirectUrls := make([]string, 0) if s := input.AllowedExternalRedirectUrls; s != nil { diff --git a/azurerm/resource_arm_app_service_test.go b/azurerm/resource_arm_app_service_test.go index 6fa70c56e926..4b0323156423 100644 --- a/azurerm/resource_arm_app_service_test.go +++ b/azurerm/resource_arm_app_service_test.go @@ -1347,8 +1347,7 @@ func TestAccAzureRMAppService_authSettingsAdditionalLoginParams(t *testing.T) { Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceExists(resourceName), resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), - resource.TestCheckResourceAttr(resourceName, "auth_settings.0.additional_login_params.#", "1"), - resource.TestCheckResourceAttr(resourceName, "auth_settings.0.additional_login_params.0", "someloginparam"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.additional_login_params.test_key", "test_value"), resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), @@ -3088,9 +3087,9 @@ resource "azurerm_app_service" "test" { enabled = true issuer = "https://sts.windows.net/%s" - additional_login_params = [ - "someloginparam" - ] + additional_login_params = { + test_key = "test_value" + } active_directory { client_id = "aadclientid" From 545b6bec176cda7e4dd7a18bc1fab21fababa46c Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Tue, 23 Apr 2019 15:49:20 +0200 Subject: [PATCH 32/38] Resolve comments from review for app_service.go --- azurerm/helpers/azure/app_service.go | 148 +++++++++++++-------------- 1 file changed, 71 insertions(+), 77 deletions(-) diff --git a/azurerm/helpers/azure/app_service.go b/azurerm/helpers/azure/app_service.go index d3b8bc660aad..f89f3fd08e1f 100644 --- a/azurerm/helpers/azure/app_service.go +++ b/azurerm/helpers/azure/app_service.go @@ -18,7 +18,6 @@ func SchemaAppServiceAadAuthSettings() *schema.Schema { return &schema.Schema{ Type: schema.TypeList, Optional: true, - Computed: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -27,8 +26,9 @@ func SchemaAppServiceAadAuthSettings() *schema.Schema { Required: true, }, "client_secret": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + Sensitive: true, }, "allowed_audiences": { Type: schema.TypeList, @@ -44,7 +44,6 @@ func SchemaAppServiceFacebookAuthSettings() *schema.Schema { return &schema.Schema{ Type: schema.TypeList, Optional: true, - Computed: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -53,8 +52,9 @@ func SchemaAppServiceFacebookAuthSettings() *schema.Schema { Required: true, }, "app_secret": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + Sensitive: true, }, "oauth_scopes": { Type: schema.TypeList, @@ -70,7 +70,6 @@ func SchemaAppServiceGoogleAuthSettings() *schema.Schema { return &schema.Schema{ Type: schema.TypeList, Optional: true, - Computed: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -79,8 +78,9 @@ func SchemaAppServiceGoogleAuthSettings() *schema.Schema { Required: true, }, "client_secret": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + Sensitive: true, }, "oauth_scopes": { Type: schema.TypeList, @@ -96,7 +96,6 @@ func SchemaAppServiceMicrosoftAuthSettings() *schema.Schema { return &schema.Schema{ Type: schema.TypeList, Optional: true, - Computed: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -105,8 +104,9 @@ func SchemaAppServiceMicrosoftAuthSettings() *schema.Schema { Required: true, }, "client_secret": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + Sensitive: true, }, "oauth_scopes": { Type: schema.TypeList, @@ -122,7 +122,6 @@ func SchemaAppServiceTwitterAuthSettings() *schema.Schema { return &schema.Schema{ Type: schema.TypeList, Optional: true, - Computed: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -131,8 +130,9 @@ func SchemaAppServiceTwitterAuthSettings() *schema.Schema { Required: true, }, "consumer_secret": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + Sensitive: true, }, }, }, @@ -143,14 +143,12 @@ func SchemaAppServiceAuthSettings() *schema.Schema { return &schema.Schema{ Type: schema.TypeList, Optional: true, - Computed: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "enabled": { - Type: schema.TypeBool, - Required: true, - Sensitive: false, + Type: schema.TypeBool, + Required: true, }, "additional_login_params": { Type: schema.TypeMap, @@ -170,8 +168,7 @@ func SchemaAppServiceAuthSettings() *schema.Schema { string(web.Google), string(web.MicrosoftAccount), string(web.Twitter), - }, true), - DiffSuppressFunc: suppress.CaseDifference, + }, false), }, "issuer": { Type: schema.TypeString, @@ -198,8 +195,7 @@ func SchemaAppServiceAuthSettings() *schema.Schema { ValidateFunc: validation.StringInSlice([]string{ string(web.AllowAnonymous), string(web.RedirectToLoginPage), - }, true), - DiffSuppressFunc: suppress.CaseDifference, + }, false), }, "active_directory": SchemaAppServiceAadAuthSettings(), "facebook": SchemaAppServiceFacebookAuthSettings(), @@ -746,10 +742,6 @@ func ExpandAppServiceAuthSettings(input interface{}) web.SiteAuthSettingsPropert facebookSettings := v.([]interface{}) for _, setting := range facebookSettings { - if setting == nil { - continue - } - facebookSetting := setting.(map[string]interface{}) if v, ok := facebookSetting["app_id"]; ok { @@ -777,10 +769,6 @@ func ExpandAppServiceAuthSettings(input interface{}) web.SiteAuthSettingsPropert googleSettings := v.([]interface{}) for _, setting := range googleSettings { - if setting == nil { - continue - } - googleSetting := setting.(map[string]interface{}) if v, ok := googleSetting["client_id"]; ok { @@ -808,10 +796,6 @@ func ExpandAppServiceAuthSettings(input interface{}) web.SiteAuthSettingsPropert microsoftSettings := v.([]interface{}) for _, setting := range microsoftSettings { - if setting == nil { - continue - } - microsoftSetting := setting.(map[string]interface{}) if v, ok := microsoftSetting["client_id"]; ok { @@ -839,10 +823,6 @@ func ExpandAppServiceAuthSettings(input interface{}) web.SiteAuthSettingsPropert twitterSettings := v.([]interface{}) for _, setting := range twitterSettings { - if setting == nil { - continue - } - twitterSetting := setting.(map[string]interface{}) if v, ok := twitterSetting["consumer_key"]; ok { @@ -877,7 +857,6 @@ func FlattenAppServiceAuthSettings(input *web.SiteAuthSettingsProperties) []inte result := make(map[string]interface{}) if input == nil { - log.Printf("[DEBUG] AuthSettings is nil") return results } @@ -918,85 +897,100 @@ func FlattenAppServiceAuthSettings(input *web.SiteAuthSettingsProperties) []inte } activeDirectorySettings := make([]interface{}, 0) - activeDirectorySetting := make(map[string]interface{}) if input.ClientID != nil { + activeDirectorySetting := make(map[string]interface{}) + activeDirectorySetting["client_id"] = *input.ClientID - } - if input.ClientSecret != nil { - activeDirectorySetting["client_secret"] = *input.ClientSecret - } + if input.ClientSecret != nil { + activeDirectorySetting["client_secret"] = *input.ClientSecret + } + + if input.AllowedAudiences != nil { + activeDirectorySetting["allowed_audiences"] = *input.AllowedAudiences + } - if s := input.AllowedAudiences; s != nil { - activeDirectorySetting["allowed_audiences"] = *s + activeDirectorySettings = append(activeDirectorySettings, activeDirectorySetting) } - result["active_directory"] = append(activeDirectorySettings, activeDirectorySetting) + result["active_directory"] = activeDirectorySettings facebookSettings := make([]interface{}, 0) - facebookSetting := make(map[string]interface{}) if input.FacebookAppID != nil { + facebookSetting := make(map[string]interface{}) + facebookSetting["app_id"] = *input.FacebookAppID - } - if input.FacebookAppSecret != nil { - facebookSetting["app_secret"] = *input.FacebookAppSecret - } + if input.FacebookAppSecret != nil { + facebookSetting["app_secret"] = *input.FacebookAppSecret + } - if s := input.FacebookOAuthScopes; s != nil { - facebookSetting["oauth_scopes"] = *s + if input.FacebookOAuthScopes != nil { + facebookSetting["oauth_scopes"] = *input.FacebookOAuthScopes + } + + facebookSettings = append(facebookSettings, facebookSetting) } - result["facebook"] = append(facebookSettings, facebookSetting) + result["facebook"] = facebookSettings googleSettings := make([]interface{}, 0) - googleSetting := make(map[string]interface{}) if input.GoogleClientID != nil { + googleSetting := make(map[string]interface{}) + googleSetting["client_id"] = *input.GoogleClientID - } - if input.GoogleClientSecret != nil { - googleSetting["client_secret"] = *input.GoogleClientSecret - } + if input.GoogleClientSecret != nil { + googleSetting["client_secret"] = *input.GoogleClientSecret + } + + if input.GoogleOAuthScopes != nil { + googleSetting["oauth_scopes"] = *input.GoogleOAuthScopes + } - if s := input.GoogleOAuthScopes; s != nil { - googleSetting["oauth_scopes"] = *s + googleSettings = append(googleSettings, googleSetting) } - result["google"] = append(googleSettings, googleSetting) + result["google"] = googleSettings microsoftSettings := make([]interface{}, 0) - microsoftSetting := make(map[string]interface{}) if input.MicrosoftAccountClientID != nil { + microsoftSetting := make(map[string]interface{}) + microsoftSetting["client_id"] = *input.MicrosoftAccountClientID - } - if input.MicrosoftAccountClientSecret != nil { - microsoftSetting["client_secret"] = *input.MicrosoftAccountClientSecret - } + if input.MicrosoftAccountClientSecret != nil { + microsoftSetting["client_secret"] = *input.MicrosoftAccountClientSecret + } + + if input.MicrosoftAccountOAuthScopes != nil { + microsoftSetting["oauth_scopes"] = *input.MicrosoftAccountOAuthScopes + } - if s := input.MicrosoftAccountOAuthScopes; s != nil { - microsoftSetting["oauth_scopes"] = *s + microsoftSettings = append(microsoftSettings, microsoftSetting) } - result["microsoft"] = append(microsoftSettings, microsoftSetting) + result["microsoft"] = microsoftSettings twitterSettings := make([]interface{}, 0) - twitterSetting := make(map[string]interface{}) if input.TwitterConsumerKey != nil { + twitterSetting := make(map[string]interface{}) + twitterSetting["consumer_key"] = *input.TwitterConsumerKey - } - if input.TwitterConsumerSecret != nil { - twitterSetting["consumer_secret"] = *input.TwitterConsumerSecret + if input.TwitterConsumerSecret != nil { + twitterSetting["consumer_secret"] = *input.TwitterConsumerSecret + } + + twitterSettings = append(twitterSettings, twitterSetting) } - result["twitter"] = append(twitterSettings, twitterSetting) + result["twitter"] = twitterSettings return append(results, result) } From 9b18c1e590241372df90d052b4201fad87dc34d0 Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Sun, 19 May 2019 19:21:22 +0200 Subject: [PATCH 33/38] Explicitly cast before using expander function --- azurerm/helpers/azure/app_service.go | 7 +++---- azurerm/resource_arm_app_service.go | 6 ++++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/azurerm/helpers/azure/app_service.go b/azurerm/helpers/azure/app_service.go index f89f3fd08e1f..c03a9be574b5 100644 --- a/azurerm/helpers/azure/app_service.go +++ b/azurerm/helpers/azure/app_service.go @@ -647,15 +647,14 @@ func FlattenAppServiceCorsSettings(input *web.CorsSettings) []interface{} { return append(results, result) } -func ExpandAppServiceAuthSettings(input interface{}) web.SiteAuthSettingsProperties { - settings := input.([]interface{}) +func ExpandAppServiceAuthSettings(input []interface{}) web.SiteAuthSettingsProperties { siteAuthSettingsProperties := web.SiteAuthSettingsProperties{} - if len(settings) == 0 { + if len(input) == 0 { return siteAuthSettingsProperties } - setting := settings[0].(map[string]interface{}) + setting := input[0].(map[string]interface{}) if v, ok := setting["enabled"]; ok { siteAuthSettingsProperties.Enabled = utils.Bool(v.(bool)) diff --git a/azurerm/resource_arm_app_service.go b/azurerm/resource_arm_app_service.go index b9a2bec87b0f..f8533b23414c 100644 --- a/azurerm/resource_arm_app_service.go +++ b/azurerm/resource_arm_app_service.go @@ -281,7 +281,8 @@ func resourceArmAppServiceCreate(d *schema.ResourceData, meta interface{}) error d.SetId(*read.ID) - authSettings := azure.ExpandAppServiceAuthSettings(d.Get("auth_settings")) + authSettingsRaw := d.Get("auth_settings").([]interface{}) + authSettings := azure.ExpandAppServiceAuthSettings(authSettingsRaw) auth := web.SiteAuthSettings{ ID: read.ID, @@ -351,7 +352,8 @@ func resourceArmAppServiceUpdate(d *schema.ResourceData, meta interface{}) error } if d.HasChange("auth_settings") { - authSettingsProperties := azure.ExpandAppServiceAuthSettings(d.Get("auth_settings")) + authSettingsRaw := d.Get("auth_settings").([]interface{}) + authSettingsProperties := azure.ExpandAppServiceAuthSettings(authSettingsRaw) id := d.Id() authSettings := web.SiteAuthSettings{ ID: &id, From 92da8f8e1e30832d9ac13e92a3fa1087e8a32938 Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Sun, 19 May 2019 19:31:28 +0200 Subject: [PATCH 34/38] Add authentication examples to examples/app-service --- .../docker-authentication/README.md | 25 ++++++++ .../app-service/docker-authentication/main.tf | 59 +++++++++++++++++ .../docker-authentication/outputs.tf | 7 +++ .../docker-authentication/variables.tf | 7 +++ .../linux-authentication/README.md | 3 + .../app-service/linux-authentication/main.tf | 55 ++++++++++++++++ .../linux-authentication/outputs.tf | 7 +++ .../linux-authentication/variables.tf | 7 +++ .../windows-authentication/README.md | 3 + .../windows-authentication/main.tf | 53 ++++++++++++++++ .../windows-authentication/outputs.tf | 7 +++ .../windows-authentication/variables.tf | 7 +++ website/docs/r/app_service.html.markdown | 63 ------------------- 13 files changed, 240 insertions(+), 63 deletions(-) create mode 100644 examples/app-service/docker-authentication/README.md create mode 100644 examples/app-service/docker-authentication/main.tf create mode 100644 examples/app-service/docker-authentication/outputs.tf create mode 100644 examples/app-service/docker-authentication/variables.tf create mode 100644 examples/app-service/linux-authentication/README.md create mode 100644 examples/app-service/linux-authentication/main.tf create mode 100644 examples/app-service/linux-authentication/outputs.tf create mode 100644 examples/app-service/linux-authentication/variables.tf create mode 100644 examples/app-service/windows-authentication/README.md create mode 100644 examples/app-service/windows-authentication/main.tf create mode 100644 examples/app-service/windows-authentication/outputs.tf create mode 100644 examples/app-service/windows-authentication/variables.tf diff --git a/examples/app-service/docker-authentication/README.md b/examples/app-service/docker-authentication/README.md new file mode 100644 index 000000000000..9ccf89317f6e --- /dev/null +++ b/examples/app-service/docker-authentication/README.md @@ -0,0 +1,25 @@ +# Example: a Linux App Service running a Docker container with AD and Microsoft authentication enabled. + +This example provisions a Linux App Service which runs a single Docker container with AD and Microsoft authentication enabled. + +### Notes + +* The Container is launched on the first HTTP Request, which can take a while. +* Continuous Deployment of a single Docker Container can be achieved using the App Setting `DOCKER_ENABLE_CI` to `true`. +* If you're not using App Service Slots and Deployments are handled outside of Terraform - [it's possible to ignore changes to specific fields in the configuration using `ignore_changes` within Terraform's `lifecycle` block](https://www.terraform.io/docs/configuration/resources.html#lifecycle), for example: + +```hcl +resource "azurerm_app_service" "test" { + # ... + site_config = { + # ... + linux_fx_version = "DOCKER|appsvcsample/python-helloworld:0.1.2" + } + + lifecycle { + ignore_changes = [ + "site_config.0.linux_fx_version", # deployments are made outside of Terraform + ] + } +} +``` diff --git a/examples/app-service/docker-authentication/main.tf b/examples/app-service/docker-authentication/main.tf new file mode 100644 index 000000000000..f61b5f12c02f --- /dev/null +++ b/examples/app-service/docker-authentication/main.tf @@ -0,0 +1,59 @@ +resource "azurerm_resource_group" "main" { + name = "${var.prefix}-resources" + location = "${var.location}" +} + +resource "azurerm_app_service_plan" "main" { + name = "${var.prefix}-asp" + location = "${azurerm_resource_group.main.location}" + resource_group_name = "${azurerm_resource_group.main.name}" + kind = "Linux" + reserved = true + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "main" { + name = "${var.prefix}-appservice" + location = "${azurerm_resource_group.main.location}" + resource_group_name = "${azurerm_resource_group.main.name}" + app_service_plan_id = "${azurerm_app_service_plan.main.id}" + + site_config { + app_command_line = "" + linux_fx_version = "DOCKER|appsvcsample/python-helloworld:latest" + } + + app_settings = { + "WEBSITES_ENABLE_APP_SERVICE_STORAGE" = "false" + "DOCKER_REGISTRY_SERVER_URL" = "https://index.docker.io" + } + + auth_settings { + enabled = true + issuer = "https://sts.windows.net/d13958f6-b541-4dad-97b9-5a39c6b01297" + default_provider = "AzureActiveDirectory" + unauthenticated_client_action = "RedirectToLoginPage" + + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "someallowedaudience", + ] + } + + microsoft { + client_id = "microsoftclientid" + client_secret = "microsoftclientsecret" + + oauth_scopes = [ + "somescope", + ] + } + } +} diff --git a/examples/app-service/docker-authentication/outputs.tf b/examples/app-service/docker-authentication/outputs.tf new file mode 100644 index 000000000000..0167f4194ecd --- /dev/null +++ b/examples/app-service/docker-authentication/outputs.tf @@ -0,0 +1,7 @@ +output "app_service_name" { + value = "${azurerm_app_service.main.name}" +} + +output "app_service_default_hostname" { + value = "https://${azurerm_app_service.main.default_site_hostname}" +} diff --git a/examples/app-service/docker-authentication/variables.tf b/examples/app-service/docker-authentication/variables.tf new file mode 100644 index 000000000000..fcd1745ba3e7 --- /dev/null +++ b/examples/app-service/docker-authentication/variables.tf @@ -0,0 +1,7 @@ +variable "prefix" { + description = "The prefix used for all resources in this example" +} + +variable "location" { + description = "The Azure location where all resources in this example should be created" +} diff --git a/examples/app-service/linux-authentication/README.md b/examples/app-service/linux-authentication/README.md new file mode 100644 index 000000000000..4bcd31c41b3f --- /dev/null +++ b/examples/app-service/linux-authentication/README.md @@ -0,0 +1,3 @@ +# Example: a Basic Linux App Service with AD and Microsoft authentication enabled. + +This example provisions a basic Linux App Service with AD and Microsoft authentication enabled. diff --git a/examples/app-service/linux-authentication/main.tf b/examples/app-service/linux-authentication/main.tf new file mode 100644 index 000000000000..2b16e8f2ff31 --- /dev/null +++ b/examples/app-service/linux-authentication/main.tf @@ -0,0 +1,55 @@ +resource "azurerm_resource_group" "main" { + name = "${var.prefix}-resources" + location = "${var.location}" +} + +resource "azurerm_app_service_plan" "main" { + name = "${var.prefix}-asp" + location = "${azurerm_resource_group.main.location}" + resource_group_name = "${azurerm_resource_group.main.name}" + kind = "Linux" + reserved = true + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "main" { + name = "${var.prefix}-appservice" + location = "${azurerm_resource_group.main.location}" + resource_group_name = "${azurerm_resource_group.main.name}" + app_service_plan_id = "${azurerm_app_service_plan.main.id}" + + site_config { + dotnet_framework_version = "v4.0" + remote_debugging_enabled = true + remote_debugging_version = "VS2015" + } + + auth_settings { + enabled = true + issuer = "https://sts.windows.net/d13958f6-b541-4dad-97b9-5a39c6b01297" + default_provider = "AzureActiveDirectory" + unauthenticated_client_action = "RedirectToLoginPage" + + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "someallowedaudience", + ] + } + + microsoft { + client_id = "microsoftclientid" + client_secret = "microsoftclientsecret" + + oauth_scopes = [ + "somescope", + ] + } + } +} diff --git a/examples/app-service/linux-authentication/outputs.tf b/examples/app-service/linux-authentication/outputs.tf new file mode 100644 index 000000000000..0167f4194ecd --- /dev/null +++ b/examples/app-service/linux-authentication/outputs.tf @@ -0,0 +1,7 @@ +output "app_service_name" { + value = "${azurerm_app_service.main.name}" +} + +output "app_service_default_hostname" { + value = "https://${azurerm_app_service.main.default_site_hostname}" +} diff --git a/examples/app-service/linux-authentication/variables.tf b/examples/app-service/linux-authentication/variables.tf new file mode 100644 index 000000000000..fcd1745ba3e7 --- /dev/null +++ b/examples/app-service/linux-authentication/variables.tf @@ -0,0 +1,7 @@ +variable "prefix" { + description = "The prefix used for all resources in this example" +} + +variable "location" { + description = "The Azure location where all resources in this example should be created" +} diff --git a/examples/app-service/windows-authentication/README.md b/examples/app-service/windows-authentication/README.md new file mode 100644 index 000000000000..9eb63d019712 --- /dev/null +++ b/examples/app-service/windows-authentication/README.md @@ -0,0 +1,3 @@ +# Example: a Basic (Windows) App Service with AD and Microsoft authentication enabled. + +This example provisions a basic Windows App Service with AD and Microsoft authentication enabled. diff --git a/examples/app-service/windows-authentication/main.tf b/examples/app-service/windows-authentication/main.tf new file mode 100644 index 000000000000..15d14744ecd5 --- /dev/null +++ b/examples/app-service/windows-authentication/main.tf @@ -0,0 +1,53 @@ +resource "azurerm_resource_group" "main" { + name = "${var.prefix}-resources" + location = "${var.location}" +} + +resource "azurerm_app_service_plan" "main" { + name = "${var.prefix}-asp" + location = "${azurerm_resource_group.main.location}" + resource_group_name = "${azurerm_resource_group.main.name}" + + sku { + tier = "Basic" + size = "B1" + } +} + +resource "azurerm_app_service" "main" { + name = "${var.prefix}-appservice" + location = "${azurerm_resource_group.main.location}" + resource_group_name = "${azurerm_resource_group.main.name}" + app_service_plan_id = "${azurerm_app_service_plan.main.id}" + + site_config { + dotnet_framework_version = "v4.0" + remote_debugging_enabled = true + remote_debugging_version = "VS2015" + } + + auth_settings { + enabled = true + issuer = "https://sts.windows.net/d13958f6-b541-4dad-97b9-5a39c6b01297" + default_provider = "AzureActiveDirectory" + unauthenticated_client_action = "RedirectToLoginPage" + + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "someallowedaudience", + ] + } + + microsoft { + client_id = "microsoftclientid" + client_secret = "microsoftclientsecret" + + oauth_scopes = [ + "somescope", + ] + } + } +} diff --git a/examples/app-service/windows-authentication/outputs.tf b/examples/app-service/windows-authentication/outputs.tf new file mode 100644 index 000000000000..0167f4194ecd --- /dev/null +++ b/examples/app-service/windows-authentication/outputs.tf @@ -0,0 +1,7 @@ +output "app_service_name" { + value = "${azurerm_app_service.main.name}" +} + +output "app_service_default_hostname" { + value = "https://${azurerm_app_service.main.default_site_hostname}" +} diff --git a/examples/app-service/windows-authentication/variables.tf b/examples/app-service/windows-authentication/variables.tf new file mode 100644 index 000000000000..fcd1745ba3e7 --- /dev/null +++ b/examples/app-service/windows-authentication/variables.tf @@ -0,0 +1,7 @@ +variable "prefix" { + description = "The prefix used for all resources in this example" +} + +variable "location" { + description = "The Azure location where all resources in this example should be created" +} diff --git a/website/docs/r/app_service.html.markdown b/website/docs/r/app_service.html.markdown index 7f1f2e128b3a..9c94f42e8e64 100644 --- a/website/docs/r/app_service.html.markdown +++ b/website/docs/r/app_service.html.markdown @@ -99,69 +99,6 @@ resource "azurerm_app_service" "test" { } ``` -## Example Usage (Authentication) - -```hcl -resource "random_id" "server" { - keepers = { - azi_id = 1 - } - - byte_length = 8 -} - -resource "azurerm_resource_group" "test" { - name = "some-resource-group" - location = "West Europe" -} - -resource "azurerm_app_service_plan" "test" { - name = "some-app-service-plan" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - - sku { - tier = "Standard" - size = "S1" - } -} - -resource "azurerm_app_service" "test" { - name = "${random_id.server.hex}" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - app_service_plan_id = "${azurerm_app_service_plan.test.id}" - - site_config { - always_on = true - } - - auth_settings { - enabled = true - issuer = "https://sts.windows.net/d13958f6-b541-4dad-97b9-5a39c6b01297" - default_provider = "AzureActiveDirectory" - unauthenticated_client_action = "RedirectToLoginPage" - - active_directory { - client_id = "aadclientid" - client_secret = "aadsecret" - - allowed_audiences = [ - "someallowedaudience", - ] - } - - microsoft { - client_id = "microsoftclientid" - client_secret = "microsoftclientsecret" - - oauth_scopes = [ - "somescope", - ] - } -} -``` - ## Argument Reference The following arguments are supported: From 517b906ef7a17a9e21d405ed357efe769cb202ff Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Sun, 19 May 2019 20:00:51 +0200 Subject: [PATCH 35/38] Resolve last comments from review --- azurerm/helpers/azure/app_service.go | 9 ++++++++- azurerm/resource_arm_app_service.go | 6 +++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/azurerm/helpers/azure/app_service.go b/azurerm/helpers/azure/app_service.go index c03a9be574b5..c2c0fc371d0e 100644 --- a/azurerm/helpers/azure/app_service.go +++ b/azurerm/helpers/azure/app_service.go @@ -838,10 +838,17 @@ func ExpandAppServiceAuthSettings(input []interface{}) web.SiteAuthSettingsPrope } func FlattenAdditionalLoginParams(input *[]string) map[string]interface{} { - result := make(map[string]interface{}, len(*input)) + result := make(map[string]interface{}, 0) + + if input == nil { + return result + } for _, k := range *input { parts := strings.Split(k, "=") + if len(parts) != 2 { + continue // Params not following the format `key=value` is considered malformed and will be ignored. + } key := parts[0] value := parts[1] diff --git a/azurerm/resource_arm_app_service.go b/azurerm/resource_arm_app_service.go index f8533b23414c..5d243dbc1548 100644 --- a/azurerm/resource_arm_app_service.go +++ b/azurerm/resource_arm_app_service.go @@ -289,7 +289,7 @@ func resourceArmAppServiceCreate(d *schema.ResourceData, meta interface{}) error SiteAuthSettingsProperties: &authSettings} if _, err := client.UpdateAuthSettings(ctx, resGroup, name, auth); err != nil { - return err + return fmt.Errorf("Error updating auth settings for App Service %q (Resource Group %q): %+s", name, resGroup, err) } return resourceArmAppServiceUpdate(d, meta) @@ -462,7 +462,7 @@ func resourceArmAppServiceRead(d *schema.ResourceData, meta interface{}) error { authResp, err := client.GetAuthSettings(ctx, resGroup, name) if err != nil { - return fmt.Errorf("Error making Read request on AzureRM App Service AuthSettings %q: %+v", name, err) + return fmt.Errorf("Error retrieving the AuthSettings for App Service %q (Resource Group %q): %+v", name, resGroup, err) } appSettingsResp, err := client.ListApplicationSettings(ctx, resGroup, name) @@ -530,7 +530,7 @@ func resourceArmAppServiceRead(d *schema.ResourceData, meta interface{}) error { authSettings := azure.FlattenAppServiceAuthSettings(authResp.SiteAuthSettingsProperties) if err := d.Set("auth_settings", authSettings); err != nil { - return err + return fmt.Errorf("Error setting `auth_settings`: %+s", err) } scm := flattenAppServiceSourceControl(scmResp.SiteSourceControlProperties) From 447ffad632e720e3fedb33b15a66870f4c96a84b Mon Sep 17 00:00:00 2001 From: Joakim Hansson Date: Sun, 19 May 2019 22:40:27 +0200 Subject: [PATCH 36/38] Fix linter error --- azurerm/helpers/azure/app_service.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azurerm/helpers/azure/app_service.go b/azurerm/helpers/azure/app_service.go index c2c0fc371d0e..2d9116c87513 100644 --- a/azurerm/helpers/azure/app_service.go +++ b/azurerm/helpers/azure/app_service.go @@ -838,7 +838,7 @@ func ExpandAppServiceAuthSettings(input []interface{}) web.SiteAuthSettingsPrope } func FlattenAdditionalLoginParams(input *[]string) map[string]interface{} { - result := make(map[string]interface{}, 0) + result := make(map[string]interface{}) if input == nil { return result From b2e0bbc98b31d8f777f1d4fd759f8ac132ccf057 Mon Sep 17 00:00:00 2001 From: tombuildsstuff Date: Wed, 22 May 2019 12:56:44 +0200 Subject: [PATCH 37/38] r/app_service: updating the docs per the PR comments --- website/docs/r/app_service.html.markdown | 97 +++++++----------------- 1 file changed, 27 insertions(+), 70 deletions(-) diff --git a/website/docs/r/app_service.html.markdown b/website/docs/r/app_service.html.markdown index 9c94f42e8e64..2aed327dbcb1 100644 --- a/website/docs/r/app_service.html.markdown +++ b/website/docs/r/app_service.html.markdown @@ -57,48 +57,6 @@ resource "azurerm_app_service" "test" { } ``` -## Example Usage (Java 1.8) - -```hcl -resource "random_id" "server" { - keepers = { - azi_id = 1 - } - - byte_length = 8 -} - -resource "azurerm_resource_group" "test" { - name = "some-resource-group" - location = "West Europe" -} - -resource "azurerm_app_service_plan" "test" { - name = "some-app-service-plan" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - - sku { - tier = "Standard" - size = "S1" - } -} - -resource "azurerm_app_service" "test" { - name = "${random_id.server.hex}" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - app_service_plan_id = "${azurerm_app_service_plan.test.id}" - - site_config { - java_version = "1.8" - java_container = "JETTY" - java_container_version = "9.3" - scm_type = "LocalGit" - } -} -``` - ## Argument Reference The following arguments are supported: @@ -213,42 +171,41 @@ A `cors` block supports the following: --- -Elements of `ip_restriction` support: -`auth_settings` supports the following: +A `auth_settings` block supports the following: * `enabled` - (Required) Is Authentication enabled? +* `active_directory` - (Optional) A `active_directory` block as defined below. + * `additional_login_params` - (Optional) Login parameters to send to the OpenID Connect authorization endpoint when a user logs in. Each parameter must be in the form "key=value". * `allowed_external_redirect_urls` - (Optional) External URLs that can be redirected to as part of logging in or logging out of the app. -~> **NOTE:** When providing multiple providers, the default provider must be set for settings like `unauthenticated_client_action` to work. - * `default_provider` - (Optional) The default provider to use when multiple providers have been set up. Possible values are `AzureActiveDirectory`, `Facebook`, `Google`, `MicrosoftAccount` and `Twitter`. -* `issuer` - (Optional) Issuer URI. When using Azure Active Directory, this value is the URI of the directory tenant, e.g. https://sts.windows.net/{tenant-guid}/. +~> **NOTE:** When using multiple providers, the default provider must be set for settings like `unauthenticated_client_action` to work. -* `runtime_version` - (Optional) The runtime version of the Authentication/Authorization module. +* `facebook` - (Optional) A `facebook` block as defined below. -* `token_refresh_extension_hours` - (Optional) The number of hours after session token expiration that a session token can be used to call the token refresh API. Defaults to 72. +* `google` - (Optional) A `google` block as defined below. -* `token_store_enabled` - (Optional) If enabled the module will durably store platform-specific security tokens that are obtained during login flows. Defaults to false. +* `issuer` - (Optional) Issuer URI. When using Azure Active Directory, this value is the URI of the directory tenant, e.g. https://sts.windows.net/{tenant-guid}/. -* `unauthenticated_client_action` - (Optional) The action to take when an unauthenticated client attempts to access the app. Possible values are `AllowAnonymous` and `RedirectToLoginPage`. +* `microsoft` - (Optional) A `microsoft` block as defined below. -* `active_directory` - (Optional) Active directory Authentication configuration. +* `runtime_version` - (Optional) The runtime version of the Authentication/Authorization module. -* `facebook` - (Optional) Facebook Authentication configuration. +* `token_refresh_extension_hours` - (Optional) The number of hours after session token expiration that a session token can be used to call the token refresh API. Defaults to 72. -* `google` - (Optional) Google Authentication configuration. +* `token_store_enabled` - (Optional) If enabled the module will durably store platform-specific security tokens that are obtained during login flows. Defaults to false. -* `microsoft` - (Optional) Microsoft Account Authentication configuration. +* `twitter` - (Optional) A `twitter` block as defined below. -* `twitter` - (Optional) Twitter Authentication configuration. +* `unauthenticated_client_action` - (Optional) The action to take when an unauthenticated client attempts to access the app. Possible values are `AllowAnonymous` and `RedirectToLoginPage`. --- -`active_directory` supports the following: +A `active_directory` block supports the following: * `client_id` - (Required) The Client ID of this relying party application. Enables OpenIDConnection authentication with Azure Active Directory. @@ -258,7 +215,7 @@ Elements of `ip_restriction` support: --- -`facebook` supports the following: +A `facebook` block supports the following: * `app_id` - (Required) The App ID of the Facebook app used for login @@ -268,7 +225,7 @@ Elements of `ip_restriction` support: --- -`google` supports the following: +A `google` block supports the following: * `client_id` - (Required) The OpenID Connect Client ID for the Google web application. @@ -278,21 +235,21 @@ Elements of `ip_restriction` support: --- -`microsoft` supports the following: - -* `client_id` - (Required) The OAuth 2.0 client ID that was created for the app used for authentication. +A `ip_restriction` block supports the following: -* `client_secret` - (Required) The OAuth 2.0 client secret that was created for the app used for authentication. +* `ip_address` - (Required) The IP Address used for this IP Restriction. -* `oauth_scopes` (Optional) The OAuth 2.0 scopes that will be requested as part of Microsoft Account authentication. https://msdn.microsoft.com/en-us/library/dn631845.aspx +* `subnet_mask` - (Optional) The Subnet mask used for this IP Restriction. Defaults to `255.255.255.255`. --- -`ip_restriction` supports the following: +A `microsoft` block supports the following: -* `ip_address` - (Required) The IP Address used for this IP Restriction. +* `client_id` - (Required) The OAuth 2.0 client ID that was created for the app used for authentication. -* `subnet_mask` - (Optional) The Subnet mask used for this IP Restriction. Defaults to `255.255.255.255`. +* `client_secret` - (Required) The OAuth 2.0 client secret that was created for the app used for authentication. + +* `oauth_scopes` (Optional) The OAuth 2.0 scopes that will be requested as part of Microsoft Account authentication. https://msdn.microsoft.com/en-us/library/dn631845.aspx ## Attributes Reference @@ -314,7 +271,7 @@ The following attributes are exported: --- -`identity` exports the following: +A `identity` block exports the following: * `principal_id` - The Principal ID for the Service Principal associated with the Managed Service Identity of this App Service. @@ -324,7 +281,7 @@ The following attributes are exported: --- -`site_credential` exports the following: +A `site_credential` block exports the following: * `username` - The username which can be used to publish to this App Service * `password` - The password associated with the username, which can be used to publish to this App Service. @@ -333,7 +290,7 @@ The following attributes are exported: --- -`source_control` exports the following: +A `source_control` block exports the following: * `repo_url` - URL of the Git repository for this App Service. * `branch` - Branch name of the Git repository for this App Service. From 5a9e7fcbb4e08aeffb3b022419b75139ae8b1811 Mon Sep 17 00:00:00 2001 From: tombuildsstuff Date: Wed, 22 May 2019 15:32:13 +0200 Subject: [PATCH 38/38] r/app_service: making `auth_settings` computed/the linux tests pass --- azurerm/helpers/azure/app_service.go | 5 +++-- azurerm/resource_arm_app_service.go | 2 +- azurerm/resource_arm_app_service_test.go | 27 ++++++++++++++++++++++-- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/azurerm/helpers/azure/app_service.go b/azurerm/helpers/azure/app_service.go index 2d9116c87513..0fc246ef015a 100644 --- a/azurerm/helpers/azure/app_service.go +++ b/azurerm/helpers/azure/app_service.go @@ -143,6 +143,7 @@ func SchemaAppServiceAuthSettings() *schema.Schema { return &schema.Schema{ Type: schema.TypeList, Optional: true, + Computed: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -860,12 +861,12 @@ func FlattenAdditionalLoginParams(input *[]string) map[string]interface{} { func FlattenAppServiceAuthSettings(input *web.SiteAuthSettingsProperties) []interface{} { results := make([]interface{}, 0) - result := make(map[string]interface{}) - if input == nil { return results } + result := make(map[string]interface{}) + if input.Enabled != nil { result["enabled"] = *input.Enabled } diff --git a/azurerm/resource_arm_app_service.go b/azurerm/resource_arm_app_service.go index 5d243dbc1548..d91950fb33f0 100644 --- a/azurerm/resource_arm_app_service.go +++ b/azurerm/resource_arm_app_service.go @@ -530,7 +530,7 @@ func resourceArmAppServiceRead(d *schema.ResourceData, meta interface{}) error { authSettings := azure.FlattenAppServiceAuthSettings(authResp.SiteAuthSettingsProperties) if err := d.Set("auth_settings", authSettings); err != nil { - return fmt.Errorf("Error setting `auth_settings`: %+s", err) + return fmt.Errorf("Error setting `auth_settings`: %s", err) } scm := flattenAppServiceSourceControl(scmResp.SiteSourceControlProperties) diff --git a/azurerm/resource_arm_app_service_test.go b/azurerm/resource_arm_app_service_test.go index 4b0323156423..fb171ecdff27 100644 --- a/azurerm/resource_arm_app_service_test.go +++ b/azurerm/resource_arm_app_service_test.go @@ -3067,12 +3067,14 @@ resource "azurerm_app_service_plan" "test" { resource_group_name = "${azurerm_resource_group.test.name}" name = "acctestRG-%d" kind = "Linux" + reserved = true sku { tier = "Standard" size = "S1" } } + resource "azurerm_app_service" "test" { name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" @@ -3088,8 +3090,8 @@ resource "azurerm_app_service" "test" { issuer = "https://sts.windows.net/%s" additional_login_params = { - test_key = "test_value" - } + test_key = "test_value" + } active_directory { client_id = "aadclientid" @@ -3116,12 +3118,14 @@ resource "azurerm_app_service_plan" "test" { resource_group_name = "${azurerm_resource_group.test.name}" name = "acctestRG-%d" kind = "Linux" + reserved = true sku { tier = "Standard" size = "S1" } } + resource "azurerm_app_service" "test" { name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" @@ -3165,12 +3169,14 @@ resource "azurerm_app_service_plan" "test" { resource_group_name = "${azurerm_resource_group.test.name}" name = "acctestRG-%d" kind = "Linux" + reserved = true sku { tier = "Standard" size = "S1" } } + resource "azurerm_app_service" "test" { name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" @@ -3211,12 +3217,14 @@ resource "azurerm_app_service_plan" "test" { resource_group_name = "${azurerm_resource_group.test.name}" name = "acctestRG-%d" kind = "Linux" + reserved = true sku { tier = "Standard" size = "S1" } } + resource "azurerm_app_service" "test" { name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" @@ -3257,12 +3265,14 @@ resource "azurerm_app_service_plan" "test" { resource_group_name = "${azurerm_resource_group.test.name}" name = "acctestRG-%d" kind = "Linux" + reserved = true sku { tier = "Standard" size = "S1" } } + resource "azurerm_app_service" "test" { name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" @@ -3303,12 +3313,14 @@ resource "azurerm_app_service_plan" "test" { resource_group_name = "${azurerm_resource_group.test.name}" name = "acctestRG-%d" kind = "Linux" + reserved = true sku { tier = "Standard" size = "S1" } } + resource "azurerm_app_service" "test" { name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" @@ -3349,12 +3361,14 @@ resource "azurerm_app_service_plan" "test" { resource_group_name = "${azurerm_resource_group.test.name}" name = "acctestRG-%d" kind = "Linux" + reserved = true sku { tier = "Standard" size = "S1" } } + resource "azurerm_app_service" "test" { name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" @@ -3393,12 +3407,14 @@ resource "azurerm_app_service_plan" "test" { resource_group_name = "${azurerm_resource_group.test.name}" name = "acctestRG-%d" kind = "Linux" + reserved = true sku { tier = "Standard" size = "S1" } } + resource "azurerm_app_service" "test" { name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" @@ -3436,12 +3452,14 @@ resource "azurerm_app_service_plan" "test" { resource_group_name = "${azurerm_resource_group.test.name}" name = "acctestRG-%d" kind = "Linux" + reserved = true sku { tier = "Standard" size = "S1" } } + resource "azurerm_app_service" "test" { name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" @@ -3479,6 +3497,7 @@ resource "azurerm_app_service_plan" "test" { resource_group_name = "${azurerm_resource_group.test.name}" name = "acctestRG-%d" kind = "Linux" + reserved = true sku { tier = "Standard" @@ -3522,12 +3541,14 @@ resource "azurerm_app_service_plan" "test" { resource_group_name = "${azurerm_resource_group.test.name}" name = "acctestRG-%d" kind = "Linux" + reserved = true sku { tier = "Standard" size = "S1" } } + resource "azurerm_app_service" "test" { name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" @@ -3561,12 +3582,14 @@ resource "azurerm_app_service_plan" "test" { resource_group_name = "${azurerm_resource_group.test.name}" name = "acctestRG-%d" kind = "Linux" + reserved = true sku { tier = "Standard" size = "S1" } } + resource "azurerm_app_service" "test" { name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}"