diff --git a/azurerm/resource_arm_app_service_slot.go b/azurerm/resource_arm_app_service_slot.go index 3704040506a3..6031c6b93974 100644 --- a/azurerm/resource_arm_app_service_slot.go +++ b/azurerm/resource_arm_app_service_slot.go @@ -14,9 +14,9 @@ import ( func resourceArmAppServiceSlot() *schema.Resource { return &schema.Resource{ - Create: resourceArmAppServiceSlotCreateUpdate, + Create: resourceArmAppServiceSlotCreate, Read: resourceArmAppServiceSlotRead, - Update: resourceArmAppServiceSlotCreateUpdate, + Update: resourceArmAppServiceSlotCreate, Delete: resourceArmAppServiceSlotDelete, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, @@ -50,6 +50,8 @@ func resourceArmAppServiceSlot() *schema.Resource { "site_config": azure.SchemaAppServiceSiteConfig(), + "auth_settings": azure.SchemaAppServiceAuthSettings(), + "client_affinity_enabled": { Type: schema.TypeBool, Optional: true, @@ -140,19 +142,19 @@ func resourceArmAppServiceSlot() *schema.Resource { } } -func resourceArmAppServiceSlotCreateUpdate(d *schema.ResourceData, meta interface{}) error { +func resourceArmAppServiceSlotCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*ArmClient).appServicesClient ctx := meta.(*ArmClient).StopContext slot := d.Get("name").(string) - resGroup := d.Get("resource_group_name").(string) + resourceGroup := d.Get("resource_group_name").(string) appServiceName := d.Get("app_service_name").(string) if requireResourcesToBeImported && d.IsNewResource() { - existing, err := client.GetSlot(ctx, resGroup, appServiceName, slot) + existing, err := client.GetSlot(ctx, resourceGroup, appServiceName, slot) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { - return fmt.Errorf("Error checking for presence of existing Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resGroup, err) + return fmt.Errorf("Error checking for presence of existing Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) } } @@ -186,38 +188,99 @@ func resourceArmAppServiceSlotCreateUpdate(d *schema.ResourceData, meta interfac siteEnvelope.Identity = appServiceIdentity } - createFuture, err := client.CreateOrUpdateSlot(ctx, resGroup, appServiceName, siteEnvelope, slot) + createFuture, err := client.CreateOrUpdateSlot(ctx, resourceGroup, appServiceName, siteEnvelope, slot) if err != nil { - return err + return fmt.Errorf("Error creating Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) } err = createFuture.WaitForCompletionRef(ctx, client.Client) if err != nil { - return err + return fmt.Errorf("Error waiting for creation of Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) } - read, err := client.GetSlot(ctx, resGroup, appServiceName, slot) + read, err := client.GetSlot(ctx, resourceGroup, appServiceName, slot) if err != nil { - return err + return fmt.Errorf("Error retrieving Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) } if read.ID == nil { - return fmt.Errorf("Cannot read App Service Slot %q/%q (resource group %q) ID", appServiceName, slot, resGroup) + return fmt.Errorf("Cannot read ID for Slot %q (App Service %q / Resource Group %q) ID", slot, appServiceName, resourceGroup) } d.SetId(*read.ID) + return resourceArmAppServiceSlotUpdate(d, meta) +} + +func resourceArmAppServiceSlotUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).appServicesClient + ctx := meta.(*ArmClient).StopContext + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + appServiceName := id.Path["sites"] + slot := id.Path["slots"] + + location := azure.NormalizeLocation(d.Get("location").(string)) + appServicePlanId := d.Get("app_service_plan_id").(string) + siteConfig := azure.ExpandAppServiceSiteConfig(d.Get("site_config")) + enabled := d.Get("enabled").(bool) + httpsOnly := d.Get("https_only").(bool) + tags := d.Get("tags").(map[string]interface{}) + + siteEnvelope := web.Site{ + Location: &location, + Tags: expandTags(tags), + SiteProperties: &web.SiteProperties{ + ServerFarmID: utils.String(appServicePlanId), + Enabled: utils.Bool(enabled), + HTTPSOnly: utils.Bool(httpsOnly), + SiteConfig: &siteConfig, + }, + } + if v, ok := d.GetOk("client_affinity_enabled"); ok { + enabled := v.(bool) + siteEnvelope.SiteProperties.ClientAffinityEnabled = utils.Bool(enabled) + } + createFuture, err := client.CreateOrUpdateSlot(ctx, resourceGroup, appServiceName, siteEnvelope, slot) + if err != nil { + return fmt.Errorf("Error updating Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) + } + + err = createFuture.WaitForCompletionRef(ctx, client.Client) + if err != nil { + return fmt.Errorf("Error waiting for update of Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) + } + if d.HasChange("site_config") { // update the main configuration siteConfig := azure.ExpandAppServiceSiteConfig(d.Get("site_config")) siteConfigResource := web.SiteConfigResource{ SiteConfig: &siteConfig, } - if _, err := client.CreateOrUpdateConfigurationSlot(ctx, resGroup, appServiceName, siteConfigResource, slot); err != nil { + if _, err := client.CreateOrUpdateConfigurationSlot(ctx, resourceGroup, appServiceName, siteConfigResource, slot); err != nil { return fmt.Errorf("Error updating Configuration for App Service Slot %q/%q: %+v", appServiceName, slot, err) } } + if d.HasChange("auth_settings") { + authSettingsRaw := d.Get("auth_settings").([]interface{}) + authSettingsProperties := azure.ExpandAppServiceAuthSettings(authSettingsRaw) + id := d.Id() + authSettings := web.SiteAuthSettings{ + ID: &id, + SiteAuthSettingsProperties: &authSettingsProperties, + } + + if _, err := client.UpdateAuthSettingsSlot(ctx, resourceGroup, appServiceName, authSettings, slot); err != nil { + return fmt.Errorf("Error updating Authentication Settings for App Service %q: %+v", appServiceName, err) + } + } + if d.HasChange("app_settings") { // update the AppSettings appSettings := expandAppServiceAppSettings(d) @@ -225,7 +288,7 @@ func resourceArmAppServiceSlotCreateUpdate(d *schema.ResourceData, meta interfac Properties: appSettings, } - if _, err := client.UpdateApplicationSettingsSlot(ctx, resGroup, appServiceName, settings, slot); err != nil { + if _, err := client.UpdateApplicationSettingsSlot(ctx, resourceGroup, appServiceName, settings, slot); err != nil { return fmt.Errorf("Error updating Application Settings for App Service Slot %q/%q: %+v", appServiceName, slot, err) } } @@ -237,7 +300,7 @@ func resourceArmAppServiceSlotCreateUpdate(d *schema.ResourceData, meta interfac Properties: connectionStrings, } - if _, err := client.UpdateConnectionStringsSlot(ctx, resGroup, appServiceName, properties, slot); err != nil { + if _, err := client.UpdateConnectionStringsSlot(ctx, resourceGroup, appServiceName, properties, slot); err != nil { return fmt.Errorf("Error updating Connection Strings for App Service Slot %q/%q: %+v", appServiceName, slot, err) } } @@ -248,7 +311,7 @@ func resourceArmAppServiceSlotCreateUpdate(d *schema.ResourceData, meta interfac ID: utils.String(d.Id()), Identity: identity, } - _, err := client.UpdateSlot(ctx, resGroup, appServiceName, sitePatchResource, slot) + _, err := client.UpdateSlot(ctx, resourceGroup, appServiceName, sitePatchResource, slot) if err != nil { return fmt.Errorf("Error updating Managed Service Identity for App Service Slot %q/%q: %+v", appServiceName, slot, err) } @@ -265,62 +328,70 @@ func resourceArmAppServiceSlotRead(d *schema.ResourceData, meta interface{}) err return err } - resGroup := id.ResourceGroup + resourceGroup := id.ResourceGroup appServiceName := id.Path["sites"] slot := id.Path["slots"] ctx := meta.(*ArmClient).StopContext - resp, err := client.GetSlot(ctx, resGroup, appServiceName, slot) + resp, err := client.GetSlot(ctx, resourceGroup, appServiceName, slot) if err != nil { if utils.ResponseWasNotFound(resp.Response) { - log.Printf("[DEBUG] App Service Slot %q/%q (resource group %q) was not found - removing from state", appServiceName, slot, resGroup) + log.Printf("[DEBUG] Slot %q (App Service %q / Resource Group %q) were not found - removing from state!", slot, appServiceName, resourceGroup) d.SetId("") return nil } - return fmt.Errorf("Error making Read request on AzureRM App Service Slot %q/%q: %+v", appServiceName, slot, err) + + return fmt.Errorf("Error reading Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) } - configResp, err := client.GetConfigurationSlot(ctx, resGroup, appServiceName, slot) + configResp, err := client.GetConfigurationSlot(ctx, resourceGroup, appServiceName, slot) if err != nil { if utils.ResponseWasNotFound(configResp.Response) { - log.Printf("[DEBUG] Configuration of App Service Slot %q/%q (resource group %q) was not found", appServiceName, slot, resGroup) + log.Printf("[DEBUG] Configuration for Slot %q (App Service %q / Resource Group %q) were not found - removing from state!", slot, appServiceName, resourceGroup) d.SetId("") return nil } - return fmt.Errorf("Error making Read request on AzureRM App Service Slot Configuration %q/%q: %+v", appServiceName, slot, err) + + return fmt.Errorf("Error reading Configuration for Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) + } + + authResp, err := client.GetAuthSettingsSlot(ctx, resourceGroup, appServiceName, slot) + if err != nil { + return fmt.Errorf("Error reading Auth Settings for Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) } - appSettingsResp, err := client.ListApplicationSettingsSlot(ctx, resGroup, appServiceName, slot) + appSettingsResp, err := client.ListApplicationSettingsSlot(ctx, resourceGroup, appServiceName, slot) if err != nil { if utils.ResponseWasNotFound(appSettingsResp.Response) { - log.Printf("[DEBUG] Application Settings of App Service Slot %q/%q (resource group %q) were not found", appServiceName, slot, resGroup) + log.Printf("[DEBUG] App Settings for Slot %q (App Service %q / Resource Group %q) were not found - removing from state!", slot, appServiceName, resourceGroup) d.SetId("") return nil } - return fmt.Errorf("Error making Read request on AzureRM App Service Slot AppSettings %q/%q: %+v", appServiceName, slot, err) + + return fmt.Errorf("Error reading App Settings for Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) } - connectionStringsResp, err := client.ListConnectionStringsSlot(ctx, resGroup, appServiceName, slot) + connectionStringsResp, err := client.ListConnectionStringsSlot(ctx, resourceGroup, appServiceName, slot) if err != nil { - return fmt.Errorf("Error making Read request on AzureRM App Service Slot ConnectionStrings %q/%q: %+v", appServiceName, slot, err) + return fmt.Errorf("Error listing Connection Strings for Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) } - siteCredFuture, err := client.ListPublishingCredentialsSlot(ctx, resGroup, appServiceName, slot) + siteCredFuture, err := client.ListPublishingCredentialsSlot(ctx, resourceGroup, appServiceName, slot) if err != nil { - return err + return fmt.Errorf("Error retrieving publishing credentials for Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) } err = siteCredFuture.WaitForCompletionRef(ctx, client.Client) if err != nil { - return err + return fmt.Errorf("Error waiting for publishing credentials for Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) } siteCredResp, err := siteCredFuture.Result(client) if err != nil { - return fmt.Errorf("Error making Read request on AzureRM App Service Slot Site Credential %q/%q: %+v", appServiceName, slot, err) + return fmt.Errorf("Error reading publishing credentials for Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) } d.Set("name", slot) d.Set("app_service_name", appServiceName) - d.Set("resource_group_name", resGroup) + d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { d.Set("location", azure.NormalizeLocation(*location)) } @@ -328,31 +399,36 @@ func resourceArmAppServiceSlotRead(d *schema.ResourceData, meta interface{}) err if props := resp.SiteProperties; props != nil { d.Set("app_service_plan_id", props.ServerFarmID) d.Set("client_affinity_enabled", props.ClientAffinityEnabled) + d.Set("default_site_hostname", props.DefaultHostName) d.Set("enabled", props.Enabled) d.Set("https_only", props.HTTPSOnly) - d.Set("default_site_hostname", props.DefaultHostName) } if err := d.Set("app_settings", flattenAppServiceAppSettings(appSettingsResp.Properties)); err != nil { - return err + return fmt.Errorf("Error setting `app_settings`: %s", err) } if err := d.Set("connection_string", flattenAppServiceConnectionStrings(connectionStringsResp.Properties)); err != nil { - return err + return fmt.Errorf("Error setting `connection_string`: %s", err) } - siteConfig := azure.FlattenAppServiceSiteConfig(configResp.SiteConfig) - if err := d.Set("site_config", siteConfig); err != nil { - return err + authSettings := azure.FlattenAppServiceAuthSettings(authResp.SiteAuthSettingsProperties) + if err := d.Set("auth_settings", authSettings); err != nil { + return fmt.Errorf("Error setting `auth_settings`: %s", err) + } + + identity := azure.FlattenAppServiceIdentity(resp.Identity) + if err := d.Set("identity", identity); err != nil { + return fmt.Errorf("Error setting `identity`: %s", err) } siteCred := flattenAppServiceSiteCredential(siteCredResp.UserProperties) if err := d.Set("site_credential", siteCred); err != nil { - return err + return fmt.Errorf("Error setting `site_credential`: %s", err) } - identity := azure.FlattenAppServiceIdentity(resp.Identity) - if err := d.Set("identity", identity); err != nil { - return err + siteConfig := azure.FlattenAppServiceSiteConfig(configResp.SiteConfig) + if err := d.Set("site_config", siteConfig); err != nil { + return fmt.Errorf("Error setting `site_config`: %s", err) } flattenAndSetTags(d, resp.Tags) @@ -367,19 +443,19 @@ func resourceArmAppServiceSlotDelete(d *schema.ResourceData, meta interface{}) e if err != nil { return err } - resGroup := id.ResourceGroup + resourceGroup := id.ResourceGroup appServiceName := id.Path["sites"] slot := id.Path["slots"] - log.Printf("[DEBUG] Deleting App Service Slot %q/%q (resource group %q)", appServiceName, slot, resGroup) + log.Printf("[DEBUG] Deleting Slot %q (App Service %q / Resource Group %q)", slot, appServiceName, resourceGroup) deleteMetrics := true deleteEmptyServerFarm := false ctx := meta.(*ArmClient).StopContext - resp, err := client.DeleteSlot(ctx, resGroup, appServiceName, slot, &deleteMetrics, &deleteEmptyServerFarm) + resp, err := client.DeleteSlot(ctx, resourceGroup, appServiceName, slot, &deleteMetrics, &deleteEmptyServerFarm) if err != nil { if !utils.ResponseWasNotFound(resp) { - return err + return fmt.Errorf("Error deleting Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) } } diff --git a/azurerm/resource_arm_app_service_slot_test.go b/azurerm/resource_arm_app_service_slot_test.go index 81f590c756c5..51711cc8c4eb 100644 --- a/azurerm/resource_arm_app_service_slot_test.go +++ b/azurerm/resource_arm_app_service_slot_test.go @@ -2,13 +2,14 @@ package azurerm import ( "fmt" + "os" "testing" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" - + "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" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -282,10 +283,11 @@ func TestAccAzureRMAppServiceSlot_corsSettings(t *testing.T) { }) } -func TestAccAzureRMAppServiceSlot_defaultDocuments(t *testing.T) { +func TestAccAzureRMAppServiceSlot_authSettingsAdditionalLoginParams(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_defaultDocuments(ri, testLocation()) + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppServiceSlot_authSettingsAdditionalLoginParams(ri, testLocation(), tenantID) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -296,19 +298,28 @@ func TestAccAzureRMAppServiceSlot_defaultDocuments(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.default_documents.0", "first.html"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.default_documents.1", "second.jsp"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.default_documents.2", "third.aspx"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + 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"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, }, }) } -func TestAccAzureRMAppServiceSlot_enabled(t *testing.T) { +func TestAccAzureRMAppServiceSlot_authSettingsAdditionalAllowedExternalRedirectUrls(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_enabled(ri, testLocation(), false) + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppServiceSlot_authSettingsAdditionalAllowedExternalRedirectUrls(ri, testLocation(), tenantID) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -319,18 +330,29 @@ func TestAccAzureRMAppServiceSlot_enabled(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "enabled", "false"), + 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 TestAccAzureRMAppServiceSlot_enabledUpdate(t *testing.T) { +func TestAccAzureRMAppServiceSlot_authSettingsRuntimeVersion(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_enabled(ri, testLocation(), false) - updatedConfig := testAccAzureRMAppServiceSlot_enabled(ri, testLocation(), true) + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppServiceSlot_authSettingsRuntimeVersion(ri, testLocation(), tenantID) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -341,24 +363,28 @@ func TestAccAzureRMAppServiceSlot_enabledUpdate(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "enabled", "false"), + 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"), ), }, { - Config: updatedConfig, - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "enabled", "true"), - ), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, }, }, }) } -func TestAccAzureRMAppServiceSlot_httpsOnly(t *testing.T) { +func TestAccAzureRMAppServiceSlot_authSettingsTokenRefreshExtensionHours(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_httpsOnly(ri, testLocation(), true) + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppServiceSlot_authSettingsTokenRefreshExtensionHours(ri, testLocation(), tenantID) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -369,18 +395,28 @@ func TestAccAzureRMAppServiceSlot_httpsOnly(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "https_only", "true"), + 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 TestAccAzureRMAppServiceSlot_httpsOnlyUpdate(t *testing.T) { +func TestAccAzureRMAppServiceSlot_authSettingsUnauthenticatedClientAction(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_httpsOnly(ri, testLocation(), true) - updatedConfig := testAccAzureRMAppServiceSlot_httpsOnly(ri, testLocation(), false) + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppServiceSlot_authSettingsUnauthenticatedClientAction(ri, testLocation(), tenantID) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -391,24 +427,28 @@ func TestAccAzureRMAppServiceSlot_httpsOnlyUpdate(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "https_only", "true"), + 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"), ), }, { - Config: updatedConfig, - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "https_only", "false"), - ), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, }, }, }) } -func TestAccAzureRMAppServiceSlot_http2Enabled(t *testing.T) { +func TestAccAzureRMAppServiceSlot_authSettingsTokenStoreEnabled(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_http2Enabled(ri, testLocation()) + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppServiceSlot_authSettingsTokenStoreEnabled(ri, testLocation(), tenantID) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -419,17 +459,28 @@ func TestAccAzureRMAppServiceSlot_http2Enabled(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.http2_enabled", "true"), + 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 TestAccAzureRMAppServiceSlot_oneIpRestriction(t *testing.T) { +func TestAccAzureRMAppServiceSlot_aadAuthSettings(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_oneIpRestriction(ri, testLocation()) + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppServiceSlot_aadAuthSettings(ri, testLocation(), tenantID) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -440,20 +491,26 @@ func TestAccAzureRMAppServiceSlot_oneIpRestriction(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.0.ip_address", "10.10.10.10"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.0.subnet_mask", "255.255.255.255"), + 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 TestAccAzureRMAppServiceSlot_zeroedIpRestriction(t *testing.T) { +func TestAccAzureRMAppServiceSlot_facebookAuthSettings(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_oneIpRestriction(ri, testLocation()) - noBlocksConfig := testAccAzureRMAppServiceSlot_basic(ri, testLocation()) - blocksEmptyConfig := testAccAzureRMAppServiceSlot_zeroedIpRestriction(ri, testLocation()) + config := testAccAzureRMAppServiceSlot_facebookAuthSettings(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -461,37 +518,28 @@ func TestAccAzureRMAppServiceSlot_zeroedIpRestriction(t *testing.T) { CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, Steps: []resource.TestStep{ { - // This configuration includes a single explicit ip_restriction Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.#", "1"), - ), - }, - { - // This configuration has no site_config blocks at all. - Config: noBlocksConfig, - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.#", "1"), + 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"), ), }, { - // This configuration explicitly sets ip_restriction to [] using attribute syntax. - Config: blocksEmptyConfig, - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.#", "0"), - ), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, }, }, }) } -func TestAccAzureRMAppServiceSlot_manyIpRestrictions(t *testing.T) { +func TestAccAzureRMAppServiceSlot_googleAuthSettings(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_manyIpRestrictions(ri, testLocation()) + config := testAccAzureRMAppServiceSlot_googleAuthSettings(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -502,24 +550,25 @@ func TestAccAzureRMAppServiceSlot_manyIpRestrictions(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.0.ip_address", "10.10.10.10"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.0.subnet_mask", "255.255.255.255"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.1.ip_address", "20.20.20.0"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.1.subnet_mask", "255.255.255.0"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.2.ip_address", "30.30.0.0"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.2.subnet_mask", "255.255.0.0"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.3.ip_address", "192.168.1.2"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.3.subnet_mask", "255.255.255.0"), + 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 TestAccAzureRMAppServiceSlot_localMySql(t *testing.T) { +func TestAccAzureRMAppServiceSlot_microsoftAuthSettings(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_localMySql(ri, testLocation()) + config := testAccAzureRMAppServiceSlot_microsoftAuthSettings(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -530,17 +579,25 @@ func TestAccAzureRMAppServiceSlot_localMySql(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.local_mysql_enabled", "true"), + 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 TestAccAzureRMAppServiceSlot_managedPipelineMode(t *testing.T) { +func TestAccAzureRMAppServiceSlot_twitterAuthSettings(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_managedPipelineMode(ri, testLocation()) + config := testAccAzureRMAppServiceSlot_twitterAuthSettings(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -551,18 +608,26 @@ func TestAccAzureRMAppServiceSlot_managedPipelineMode(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.managed_pipeline_mode", "Classic"), + 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 TestAccAzureRMAppServiceSlot_tagsUpdate(t *testing.T) { +func TestAccAzureRMAppServiceSlot_multiAuthSettings(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_tags(ri, testLocation()) - updatedConfig := testAccAzureRMAppServiceSlot_tagsUpdated(ri, testLocation()) + tenantID := os.Getenv("ARM_TENANT_ID") + config1 := testAccAzureRMAppServiceSlot_aadAuthSettings(ri, testLocation(), tenantID) + config2 := testAccAzureRMAppServiceSlot_aadMicrosoftAuthSettings(ri, testLocation(), tenantID) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -570,30 +635,48 @@ func TestAccAzureRMAppServiceSlot_tagsUpdate(t *testing.T) { CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, Steps: []resource.TestStep{ { - Config: config, + Config: config1, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), - resource.TestCheckResourceAttr(resourceName, "tags.Hello", "World"), + 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"), ), }, { - Config: updatedConfig, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: config2, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), - resource.TestCheckResourceAttr(resourceName, "tags.Hello", "World"), - resource.TestCheckResourceAttr(resourceName, "tags.Terraform", "AcceptanceTests"), + 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 TestAccAzureRMAppServiceSlot_remoteDebugging(t *testing.T) { +func TestAccAzureRMAppServiceSlot_defaultDocuments(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_remoteDebugging(ri, testLocation()) + config := testAccAzureRMAppServiceSlot_defaultDocuments(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -604,18 +687,19 @@ func TestAccAzureRMAppServiceSlot_remoteDebugging(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.remote_debugging_enabled", "true"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.remote_debugging_version", "VS2015"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.default_documents.0", "first.html"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.default_documents.1", "second.jsp"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.default_documents.2", "third.aspx"), ), }, }, }) } -func TestAccAzureRMAppServiceSlot_virtualNetwork(t *testing.T) { +func TestAccAzureRMAppServiceSlot_enabled(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - location := testLocation() + config := testAccAzureRMAppServiceSlot_enabled(ri, testLocation(), false) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -623,27 +707,21 @@ func TestAccAzureRMAppServiceSlot_virtualNetwork(t *testing.T) { CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMAppServiceSlot_virtualNetwork(ri, location), - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.virtual_network_name", fmt.Sprintf("acctestvn-%d", ri)), - ), - }, - { - Config: testAccAzureRMAppServiceSlot_virtualNetworkUpdated(ri, location), + Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.virtual_network_name", fmt.Sprintf("acctestvn2-%d", ri)), + resource.TestCheckResourceAttr(resourceName, "enabled", "false"), ), }, }, }) } -func TestAccAzureRMAppServiceSlot_windowsDotNet2(t *testing.T) { +func TestAccAzureRMAppServiceSlot_enabledUpdate(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_windowsDotNet(ri, testLocation(), "v2.0") + config := testAccAzureRMAppServiceSlot_enabled(ri, testLocation(), false) + updatedConfig := testAccAzureRMAppServiceSlot_enabled(ri, testLocation(), true) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -654,17 +732,24 @@ func TestAccAzureRMAppServiceSlot_windowsDotNet2(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.dotnet_framework_version", "v2.0"), + resource.TestCheckResourceAttr(resourceName, "enabled", "false"), + ), + }, + { + Config: updatedConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "enabled", "true"), ), }, }, }) } -func TestAccAzureRMAppServiceSlot_windowsDotNet4(t *testing.T) { +func TestAccAzureRMAppServiceSlot_httpsOnly(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_windowsDotNet(ri, testLocation(), "v4.0") + config := testAccAzureRMAppServiceSlot_httpsOnly(ri, testLocation(), true) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -675,18 +760,18 @@ func TestAccAzureRMAppServiceSlot_windowsDotNet4(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.dotnet_framework_version", "v4.0"), + resource.TestCheckResourceAttr(resourceName, "https_only", "true"), ), }, }, }) } -func TestAccAzureRMAppServiceSlot_windowsDotNetUpdate(t *testing.T) { +func TestAccAzureRMAppServiceSlot_httpsOnlyUpdate(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_windowsDotNet(ri, testLocation(), "v2.0") - updatedConfig := testAccAzureRMAppServiceSlot_windowsDotNet(ri, testLocation(), "v4.0") + config := testAccAzureRMAppServiceSlot_httpsOnly(ri, testLocation(), true) + updatedConfig := testAccAzureRMAppServiceSlot_httpsOnly(ri, testLocation(), false) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -697,24 +782,24 @@ func TestAccAzureRMAppServiceSlot_windowsDotNetUpdate(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.dotnet_framework_version", "v2.0"), + resource.TestCheckResourceAttr(resourceName, "https_only", "true"), ), }, { Config: updatedConfig, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.dotnet_framework_version", "v4.0"), + resource.TestCheckResourceAttr(resourceName, "https_only", "false"), ), }, }, }) } -func TestAccAzureRMAppServiceSlot_windowsJava7Jetty(t *testing.T) { +func TestAccAzureRMAppServiceSlot_http2Enabled(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_windowsJava(ri, testLocation(), "1.7", "JETTY", "9.3") + config := testAccAzureRMAppServiceSlot_http2Enabled(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -725,19 +810,17 @@ func TestAccAzureRMAppServiceSlot_windowsJava7Jetty(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_version", "1.7"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container", "JETTY"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container_version", "9.3"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.http2_enabled", "true"), ), }, }, }) } -func TestAccAzureRMAppServiceSlot_windowsJava8Jetty(t *testing.T) { +func TestAccAzureRMAppServiceSlot_oneIpRestriction(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_windowsJava(ri, testLocation(), "1.8", "JETTY", "9.3") + config := testAccAzureRMAppServiceSlot_oneIpRestriction(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -748,18 +831,20 @@ func TestAccAzureRMAppServiceSlot_windowsJava8Jetty(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_version", "1.8"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container", "JETTY"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container_version", "9.3"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.0.ip_address", "10.10.10.10"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.0.subnet_mask", "255.255.255.255"), ), }, }, }) } -func TestAccAzureRMAppServiceSlot_windowsJava11Jetty(t *testing.T) { + +func TestAccAzureRMAppServiceSlot_zeroedIpRestriction(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_windowsJava(ri, testLocation(), "11", "JETTY", "9.3") + config := testAccAzureRMAppServiceSlot_oneIpRestriction(ri, testLocation()) + noBlocksConfig := testAccAzureRMAppServiceSlot_basic(ri, testLocation()) + blocksEmptyConfig := testAccAzureRMAppServiceSlot_zeroedIpRestriction(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -767,22 +852,37 @@ func TestAccAzureRMAppServiceSlot_windowsJava11Jetty(t *testing.T) { CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, Steps: []resource.TestStep{ { + // This configuration includes a single explicit ip_restriction Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_version", "11"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container", "JETTY"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container_version", "9.3"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.#", "1"), + ), + }, + { + // This configuration has no site_config blocks at all. + Config: noBlocksConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.#", "1"), + ), + }, + { + // This configuration explicitly sets ip_restriction to [] using attribute syntax. + Config: blocksEmptyConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.#", "0"), ), }, }, }) } -func TestAccAzureRMAppServiceSlot_windowsJava7Tomcat(t *testing.T) { +func TestAccAzureRMAppServiceSlot_manyIpRestrictions(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_windowsJava(ri, testLocation(), "1.7", "TOMCAT", "9.0") + config := testAccAzureRMAppServiceSlot_manyIpRestrictions(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -793,19 +893,24 @@ func TestAccAzureRMAppServiceSlot_windowsJava7Tomcat(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_version", "1.7"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container", "TOMCAT"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container_version", "9.0"), - ), - }, - }, - }) -} - -func TestAccAzureRMAppServiceSlot_windowsJava8Tomcat(t *testing.T) { + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.0.ip_address", "10.10.10.10"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.0.subnet_mask", "255.255.255.255"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.1.ip_address", "20.20.20.0"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.1.subnet_mask", "255.255.255.0"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.2.ip_address", "30.30.0.0"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.2.subnet_mask", "255.255.0.0"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.3.ip_address", "192.168.1.2"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.3.subnet_mask", "255.255.255.0"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_localMySql(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_windowsJava(ri, testLocation(), "1.8", "TOMCAT", "9.0") + config := testAccAzureRMAppServiceSlot_localMySql(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -816,19 +921,17 @@ func TestAccAzureRMAppServiceSlot_windowsJava8Tomcat(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_version", "1.8"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container", "TOMCAT"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container_version", "9.0"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.local_mysql_enabled", "true"), ), }, }, }) } -func TestAccAzureRMAppServiceSlot_windowsJava11Tomcat(t *testing.T) { +func TestAccAzureRMAppServiceSlot_managedPipelineMode(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_windowsJava(ri, testLocation(), "11", "TOMCAT", "9.0") + config := testAccAzureRMAppServiceSlot_managedPipelineMode(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -839,19 +942,18 @@ func TestAccAzureRMAppServiceSlot_windowsJava11Tomcat(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_version", "11"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container", "TOMCAT"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container_version", "9.0"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.managed_pipeline_mode", "Classic"), ), }, }, }) } -func TestAccAzureRMAppServiceSlot_windowsPHP7(t *testing.T) { +func TestAccAzureRMAppServiceSlot_tagsUpdate(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_windowsPHP(ri, testLocation()) + config := testAccAzureRMAppServiceSlot_tags(ri, testLocation()) + updatedConfig := testAccAzureRMAppServiceSlot_tagsUpdated(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -862,17 +964,27 @@ func TestAccAzureRMAppServiceSlot_windowsPHP7(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.php_version", "7.2"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.Hello", "World"), + ), + }, + { + Config: updatedConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.Hello", "World"), + resource.TestCheckResourceAttr(resourceName, "tags.Terraform", "AcceptanceTests"), ), }, }, }) } -func TestAccAzureRMAppServiceSlot_windowsPython(t *testing.T) { +func TestAccAzureRMAppServiceSlot_remoteDebugging(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_windowsPython(ri, testLocation()) + config := testAccAzureRMAppServiceSlot_remoteDebugging(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -883,17 +995,46 @@ func TestAccAzureRMAppServiceSlot_windowsPython(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.python_version", "3.4"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.remote_debugging_enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.remote_debugging_version", "VS2015"), ), }, }, }) } -func TestAccAzureRMAppServiceSlot_webSockets(t *testing.T) { +func TestAccAzureRMAppServiceSlot_virtualNetwork(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_webSockets(ri, testLocation()) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAppServiceSlot_virtualNetwork(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.virtual_network_name", fmt.Sprintf("acctestvn-%d", ri)), + ), + }, + { + Config: testAccAzureRMAppServiceSlot_virtualNetworkUpdated(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.virtual_network_name", fmt.Sprintf("acctestvn2-%d", ri)), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_windowsDotNet2(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_windowsDotNet(ri, testLocation(), "v2.0") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -904,7 +1045,7 @@ func TestAccAzureRMAppServiceSlot_webSockets(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.websockets_enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.dotnet_framework_version", "v2.0"), ), }, }, @@ -939,10 +1080,10 @@ func TestAccAzureRMAppServiceSlot_updateManageServiceIdentity(t *testing.T) { }) } -func TestAccAzureRMAppServiceSlot_enableManageServiceIdentity(t *testing.T) { +func TestAccAzureRMAppServiceSlot_windowsDotNet4(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_enableManageServiceIdentity(ri, testLocation()) + config := testAccAzureRMAppServiceSlot_windowsDotNet(ri, testLocation(), "v4.0") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -953,9 +1094,7 @@ func TestAccAzureRMAppServiceSlot_enableManageServiceIdentity(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "identity.0.type", "SystemAssigned"), - resource.TestMatchResourceAttr(resourceName, "identity.0.principal_id", validate.UUIDRegExp), - resource.TestMatchResourceAttr(resourceName, "identity.0.tenant_id", validate.UUIDRegExp), + resource.TestCheckResourceAttr(resourceName, "site_config.0.dotnet_framework_version", "v4.0"), ), }, }, @@ -1010,11 +1149,11 @@ func TestAccAzureRMAppServiceSlot_multipleAssignedIdentities(t *testing.T) { }) } -func TestAccAzureRMAppServiceSlot_minTls(t *testing.T) { +func TestAccAzureRMAppServiceSlot_windowsDotNetUpdate(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_minTls(ri, testLocation(), "1.0") - updatedConfig := testAccAzureRMAppServiceSlot_minTls(ri, testLocation(), "1.1") + config := testAccAzureRMAppServiceSlot_windowsDotNet(ri, testLocation(), "v2.0") + updatedConfig := testAccAzureRMAppServiceSlot_windowsDotNet(ri, testLocation(), "v4.0") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -1025,83 +1164,835 @@ func TestAccAzureRMAppServiceSlot_minTls(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.min_tls_version", "1.0"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.dotnet_framework_version", "v2.0"), ), }, { Config: updatedConfig, Check: resource.ComposeTestCheckFunc( - testCheckAzureRMAppServiceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.min_tls_version", "1.1"), + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.dotnet_framework_version", "v4.0"), ), }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_windowsJava7Jetty(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_windowsJava(ri, testLocation(), "1.7", "JETTY", "9.3") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_version", "1.7"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container", "JETTY"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container_version", "9.3"), + ), }, }, }) } -func testCheckAzureRMAppServiceSlotDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).appServicesClient +func TestAccAzureRMAppServiceSlot_windowsJava8Jetty(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_windowsJava(ri, testLocation(), "1.8", "JETTY", "9.3") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_version", "1.8"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container", "JETTY"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container_version", "9.3"), + ), + }, + }, + }) +} +func TestAccAzureRMAppServiceSlot_windowsJava11Jetty(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_windowsJava(ri, testLocation(), "11", "JETTY", "9.3") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_version", "11"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container", "JETTY"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container_version", "9.3"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_windowsJava7Tomcat(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_windowsJava(ri, testLocation(), "1.7", "TOMCAT", "9.0") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_version", "1.7"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container", "TOMCAT"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container_version", "9.0"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_windowsJava8Tomcat(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_windowsJava(ri, testLocation(), "1.8", "TOMCAT", "9.0") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_version", "1.8"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container", "TOMCAT"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container_version", "9.0"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_windowsJava11Tomcat(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_windowsJava(ri, testLocation(), "11", "TOMCAT", "9.0") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_version", "11"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container", "TOMCAT"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container_version", "9.0"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_windowsPHP7(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_windowsPHP(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.php_version", "7.2"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_windowsPython(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_windowsPython(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.python_version", "3.4"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_webSockets(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_webSockets(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.websockets_enabled", "true"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_enableManageServiceIdentity(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_enableManageServiceIdentity(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "identity.0.type", "SystemAssigned"), + resource.TestMatchResourceAttr(resourceName, "identity.0.principal_id", validate.UUIDRegExp), + resource.TestMatchResourceAttr(resourceName, "identity.0.tenant_id", validate.UUIDRegExp), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_minTls(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_minTls(ri, testLocation(), "1.0") + updatedConfig := testAccAzureRMAppServiceSlot_minTls(ri, testLocation(), "1.1") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.min_tls_version", "1.0"), + ), + }, + { + Config: updatedConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.min_tls_version", "1.1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMAppServiceSlotDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).appServicesClient + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_app_service_slot" { + continue + } + + slot := rs.Primary.Attributes["name"] + appServiceName := rs.Primary.Attributes["app_service_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.GetSlot(ctx, resourceGroup, appServiceName, slot) + + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return nil + } + return err + } + + return nil + } + + return nil +} + +func testCheckAzureRMAppServiceSlotExists(slot string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[slot] + if !ok { + return fmt.Errorf("Slot Not found: %q", slot) + } + + appServiceName := rs.Primary.Attributes["app_service_name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for App Service Slot: %q/%q", appServiceName, slot) + } + + client := testAccProvider.Meta().(*ArmClient).appServicesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.GetSlot(ctx, resourceGroup, appServiceName, slot) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: App Service slot %q/%q (resource group: %q) does not exist", appServiceName, slot, resourceGroup) + } + + return fmt.Errorf("Bad: Get on appServicesClient: %+v", err) + } + + return nil + } +} + +func testAccAzureRMAppServiceSlot_basic(rInt int, location string) string { + return fmt.Sprintf(` +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}" +} + +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%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}" + app_service_name = "${azurerm_app_service.test.name}" +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_requiresImport(rInt int, location string) string { + template := testAccAzureRMAppServiceSlot_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_app_service_slot" "import" { + name = "${azurerm_app_service_slot.test.name}" + location = "${azurerm_app_service_slot.test.location}" + resource_group_name = "${azurerm_app_service_slot.test.resource_group_name}" + app_service_plan_id = "${azurerm_app_service_slot.test.app_service_plan_id}" + app_service_name = "${azurerm_app_service_slot.test.app_service_name}" +} +`, template) +} + +func testAccAzureRMAppServiceSlot_32Bit(rInt int, location string) string { + return fmt.Sprintf(` +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}" +} + +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%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}" + app_service_name = "${azurerm_app_service.test.name}" + + site_config { + use_32_bit_worker_process = true + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_alwaysOn(rInt int, location string) string { + return fmt.Sprintf(` +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}" +} + +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%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}" + app_service_name = "${azurerm_app_service.test.name}" + + site_config { + always_on = true + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_appCommandLine(rInt int, location string) string { + return fmt.Sprintf(` +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}" +} + +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%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}" + app_service_name = "${azurerm_app_service.test.name}" + + site_config { + app_command_line = "/sbin/myservice -b 0.0.0.0" + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_appSettings(rInt int, location string) string { + return fmt.Sprintf(` +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}" +} + +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%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}" + app_service_name = "${azurerm_app_service.test.name}" + + app_settings = { + "foo" = "bar" + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_clientAffinityEnabled(rInt int, location string, clientAffinityEnabled bool) string { + return fmt.Sprintf(` +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}" +} + +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%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}" + app_service_name = "${azurerm_app_service.test.name}" + client_affinity_enabled = %t +} +`, rInt, location, rInt, rInt, rInt, clientAffinityEnabled) +} + +func testAccAzureRMAppServiceSlot_connectionStrings(rInt int, location string) string { + return fmt.Sprintf(` +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}" +} + +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%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}" + app_service_name = "${azurerm_app_service.test.name}" + + connection_string { + name = "First" + value = "first-connection-string" + type = "Custom" + } + + connection_string { + name = "Second" + value = "some-postgresql-connection-string" + type = "PostgreSQL" + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_connectionStringsUpdated(rInt int, location string) string { + return fmt.Sprintf(` +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}" +} + +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%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}" + app_service_name = "${azurerm_app_service.test.name}" + + connection_string { + name = "Second" + value = "some-postgresql-connection-string" + type = "PostgreSQL" + } + + connection_string { + name = "First" + value = "first-connection-string" + type = "Custom" + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_corsSettings(rInt int, location string) string { + return fmt.Sprintf(` +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}" +} + +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%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}" + app_service_name = "${azurerm_app_service.test.name}" + + site_config { + cors { + allowed_origins = [ + "http://www.contoso.com", + "www.contoso.com", + "contoso.com" + ] + support_credentials = true + } + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_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" + reserved = true + + 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 + } +} + +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%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}" + app_service_name = "${azurerm_app_service.test.name}" + + auth_settings { + enabled = true + issuer = "https://sts.windows.net/%s" + + additional_login_params = { + test_key = "test_value" + } - for _, rs := range s.RootModule().Resources { - if rs.Type != "azurerm_app_service_slot" { - continue - } + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" - slot := rs.Primary.Attributes["name"] - appServiceName := rs.Primary.Attributes["app_service_name"] - resourceGroup := rs.Primary.Attributes["resource_group_name"] + allowed_audiences = [ + "activedirectorytokenaudiences", + ] + } + } +} +`, rInt, location, rInt, rInt, rInt, tenantID) +} - ctx := testAccProvider.Meta().(*ArmClient).StopContext - resp, err := client.GetSlot(ctx, resourceGroup, appServiceName, slot) +func testAccAzureRMAppServiceSlot_authSettingsAdditionalAllowedExternalRedirectUrls(rInt int, location string, tenantID string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} - if err != nil { - if utils.ResponseWasNotFound(resp.Response) { - return nil - } - return err - } +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" + reserved = true - return nil - } + sku { + tier = "Standard" + size = "S1" + } +} - return nil +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}" } -func testCheckAzureRMAppServiceSlotExists(slot string) resource.TestCheckFunc { - return func(s *terraform.State) error { - // Ensure we have enough information in state to look up in API - rs, ok := s.RootModule().Resources[slot] - if !ok { - return fmt.Errorf("Slot Not found: %q", slot) - } +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%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}" + app_service_name = "${azurerm_app_service.test.name}" - appServiceName := rs.Primary.Attributes["app_service_name"] - resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] - if !hasResourceGroup { - return fmt.Errorf("Bad: no resource group found in state for App Service Slot: %q/%q", appServiceName, slot) - } + site_config { + always_on = true + } - client := testAccProvider.Meta().(*ArmClient).appServicesClient - ctx := testAccProvider.Meta().(*ArmClient).StopContext - resp, err := client.GetSlot(ctx, resourceGroup, appServiceName, slot) - if err != nil { - if utils.ResponseWasNotFound(resp.Response) { - return fmt.Errorf("Bad: App Service slot %q/%q (resource group: %q) does not exist", appServiceName, slot, resourceGroup) - } + auth_settings { + enabled = true + issuer = "https://sts.windows.net/%s" + + allowed_external_redirect_urls = [ + "https://terra.form" + ] - return fmt.Errorf("Bad: Get on appServicesClient: %+v", err) - } + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" - return nil - } + allowed_audiences = [ + "activedirectorytokenaudiences", + ] + } + } +} +`, rInt, location, rInt, rInt, rInt, tenantID) } -func testAccAzureRMAppServiceSlot_basic(rInt int, location string) string { +func testAccAzureRMAppServiceSlot_authSettingsRuntimeVersion(rInt int, location string, tenantID string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1109,9 +2000,11 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true sku { tier = "Standard" @@ -1120,7 +2013,7 @@ resource "azurerm_app_service_plan" "test" { } resource "azurerm_app_service" "test" { - name = "acctestAS-%d" + 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}" @@ -1132,26 +2025,86 @@ resource "azurerm_app_service_slot" "test" { resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" app_service_name = "${azurerm_app_service.test.name}" + + 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, rInt) +`, rInt, location, rInt, rInt, rInt, tenantID) } -func testAccAzureRMAppServiceSlot_requiresImport(rInt int, location string) string { - template := testAccAzureRMAppServiceSlot_basic(rInt, location) +func testAccAzureRMAppServiceSlot_authSettingsTokenRefreshExtensionHours(rInt int, location string, tenantID string) string { return fmt.Sprintf(` -%s +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} -resource "azurerm_app_service_slot" "import" { - name = "${azurerm_app_service_slot.test.name}" - location = "${azurerm_app_service_slot.test.location}" - resource_group_name = "${azurerm_app_service_slot.test.resource_group_name}" - app_service_plan_id = "${azurerm_app_service_slot.test.app_service_plan_id}" - app_service_name = "${azurerm_app_service_slot.test.app_service_name}" +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" + reserved = true + + sku { + tier = "Standard" + size = "S1" + } } -`, template) + +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}" } -func testAccAzureRMAppServiceSlot_32Bit(rInt int, location string) string { +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%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}" + app_service_name = "${azurerm_app_service.test.name}" + + 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, rInt, tenantID) +} + +func testAccAzureRMAppServiceSlot_authSettingsTokenStoreEnabled(rInt int, location string, tenantID string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1159,9 +2112,11 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true sku { tier = "Standard" @@ -1170,7 +2125,7 @@ resource "azurerm_app_service_plan" "test" { } resource "azurerm_app_service" "test" { - name = "acctestAS-%d" + 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}" @@ -1182,15 +2137,30 @@ resource "azurerm_app_service_slot" "test" { resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" app_service_name = "${azurerm_app_service.test.name}" - + site_config { - use_32_bit_worker_process = true + 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, rInt) +`, rInt, location, rInt, rInt, rInt, tenantID) } -func testAccAzureRMAppServiceSlot_alwaysOn(rInt int, location string) string { +func testAccAzureRMAppServiceSlot_authSettingsUnauthenticatedClientAction(rInt int, location string, tenantID string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1198,9 +2168,11 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true sku { tier = "Standard" @@ -1209,7 +2181,7 @@ resource "azurerm_app_service_plan" "test" { } resource "azurerm_app_service" "test" { - name = "acctestAS-%d" + 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}" @@ -1225,11 +2197,26 @@ resource "azurerm_app_service_slot" "test" { 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, rInt) +`, rInt, location, rInt, rInt, rInt, tenantID) } -func testAccAzureRMAppServiceSlot_appCommandLine(rInt int, location string) string { +func testAccAzureRMAppServiceSlot_aadAuthSettings(rInt int, location string, tenantID string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1237,9 +2224,11 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true sku { tier = "Standard" @@ -1248,7 +2237,7 @@ resource "azurerm_app_service_plan" "test" { } resource "azurerm_app_service" "test" { - name = "acctestAS-%d" + 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}" @@ -1262,13 +2251,26 @@ resource "azurerm_app_service_slot" "test" { app_service_name = "${azurerm_app_service.test.name}" site_config { - app_command_line = "/sbin/myservice -b 0.0.0.0" + 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, rInt) +`, rInt, location, rInt, rInt, rInt, tenantID) } -func testAccAzureRMAppServiceSlot_appSettings(rInt int, location string) string { +func testAccAzureRMAppServiceSlot_facebookAuthSettings(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1276,9 +2278,11 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true sku { tier = "Standard" @@ -1287,7 +2291,7 @@ resource "azurerm_app_service_plan" "test" { } resource "azurerm_app_service" "test" { - name = "acctestAS-%d" + 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}" @@ -1300,14 +2304,26 @@ resource "azurerm_app_service_slot" "test" { app_service_plan_id = "${azurerm_app_service_plan.test.id}" app_service_name = "${azurerm_app_service.test.name}" - app_settings = { - "foo" = "bar" + site_config { + always_on = true + } + + auth_settings { + enabled = true + facebook { + app_id = "facebookappid" + app_secret = "facebookappsecret" + + oauth_scopes = [ + "facebookscope", + ] + } } } `, rInt, location, rInt, rInt, rInt) } -func testAccAzureRMAppServiceSlot_clientAffinityEnabled(rInt int, location string, clientAffinityEnabled bool) string { +func testAccAzureRMAppServiceSlot_googleAuthSettings(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1315,9 +2331,11 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true sku { tier = "Standard" @@ -1326,24 +2344,40 @@ resource "azurerm_app_service_plan" "test" { } resource "azurerm_app_service" "test" { - name = "acctestAS-%d" + 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}" } resource "azurerm_app_service_slot" "test" { - name = "acctestASSlot-%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}" - app_service_name = "${azurerm_app_service.test.name}" - client_affinity_enabled = %t + name = "acctestASSlot-%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}" + app_service_name = "${azurerm_app_service.test.name}" + + + site_config { + always_on = true + } + + auth_settings { + enabled = true + google { + client_id = "googleclientid" + client_secret = "googleclientsecret" + + oauth_scopes = [ + "googlescope", + ] + } + } } -`, rInt, location, rInt, rInt, rInt, clientAffinityEnabled) +`, rInt, location, rInt, rInt, rInt) } -func testAccAzureRMAppServiceSlot_connectionStrings(rInt int, location string) string { +func testAccAzureRMAppServiceSlot_microsoftAuthSettings(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1351,18 +2385,19 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" 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 = "acctestAS-%d" + 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}" @@ -1375,22 +2410,26 @@ resource "azurerm_app_service_slot" "test" { app_service_plan_id = "${azurerm_app_service_plan.test.id}" app_service_name = "${azurerm_app_service.test.name}" - connection_string { - name = "First" - value = "first-connection-string" - type = "Custom" + site_config { + always_on = true } - connection_string { - name = "Second" - value = "some-postgresql-connection-string" - type = "PostgreSQL" + auth_settings { + enabled = true + microsoft { + client_id = "microsoftclientid" + client_secret = "microsoftclientsecret" + + oauth_scopes = [ + "microsoftscope", + ] + } } } `, rInt, location, rInt, rInt, rInt) } -func testAccAzureRMAppServiceSlot_connectionStringsUpdated(rInt int, location string) string { +func testAccAzureRMAppServiceSlot_twitterAuthSettings(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1398,9 +2437,11 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true sku { tier = "Standard" @@ -1409,7 +2450,7 @@ resource "azurerm_app_service_plan" "test" { } resource "azurerm_app_service" "test" { - name = "acctestAS-%d" + 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}" @@ -1422,22 +2463,22 @@ resource "azurerm_app_service_slot" "test" { app_service_plan_id = "${azurerm_app_service_plan.test.id}" app_service_name = "${azurerm_app_service.test.name}" - connection_string { - name = "Second" - value = "some-postgresql-connection-string" - type = "PostgreSQL" + site_config { + always_on = true } - connection_string { - name = "First" - value = "first-connection-string" - type = "Custom" + auth_settings { + enabled = true + twitter { + consumer_key = "twitterconsumerkey" + consumer_secret = "twitterconsumersecret" + } } } `, rInt, location, rInt, rInt, rInt) } -func testAccAzureRMAppServiceSlot_corsSettings(rInt int, location string) string { +func testAccAzureRMAppServiceSlot_aadMicrosoftAuthSettings(rInt int, location string, tenantID string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1445,9 +2486,11 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true sku { tier = "Standard" @@ -1456,7 +2499,7 @@ resource "azurerm_app_service_plan" "test" { } resource "azurerm_app_service" "test" { - name = "acctestAS-%d" + 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}" @@ -1470,18 +2513,34 @@ resource "azurerm_app_service_slot" "test" { app_service_name = "${azurerm_app_service.test.name}" site_config { - cors { - allowed_origins = [ - "http://www.contoso.com", - "www.contoso.com", - "contoso.com", + 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" - support_credentials = true + oauth_scopes = [ + "microsoftscope", + ] } } } -`, rInt, location, rInt, rInt, rInt) +`, rInt, location, rInt, rInt, rInt, tenantID, web.AzureActiveDirectory) } func testAccAzureRMAppServiceSlot_defaultDocuments(rInt int, location string) string { diff --git a/website/docs/r/app_service_slot.html.markdown b/website/docs/r/app_service_slot.html.markdown index 22212cab844f..94f53230514c 100644 --- a/website/docs/r/app_service_slot.html.markdown +++ b/website/docs/r/app_service_slot.html.markdown @@ -156,6 +156,8 @@ The following arguments are supported: * `app_settings` - (Optional) A key-value pair of App Settings. +* `auth_settings` - (Optional) A `auth_settings` block as defined below. + * `connection_string` - (Optional) An `connection_string` block as defined below. * `client_affinity_enabled` - (Optional) Should the App Service Slot send session affinity cookies, which route client requests in the same session to the same instance? @@ -238,6 +240,88 @@ A `cors` block 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. + +* `default_provider` - (Optional) The default provider to use when multiple providers have been set up. Possible values are `AzureActiveDirectory`, `Facebook`, `Google`, `MicrosoftAccount` and `Twitter`. + +~> **NOTE:** When using multiple providers, the default provider must be set for settings like `unauthenticated_client_action` to work. + +* `facebook` - (Optional) A `facebook` block as defined below. + +* `google` - (Optional) A `google` block as defined below. + +* `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}/. + +* `microsoft` - (Optional) A `microsoft` block as defined below. + +* `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. + +* `token_store_enabled` - (Optional) If enabled the module will durably store platform-specific security tokens that are obtained during login flows. Defaults to false. + +* `twitter` - (Optional) A `twitter` block as defined below. + +* `unauthenticated_client_action` - (Optional) The action to take when an unauthenticated client attempts to access the app. Possible values are `AllowAnonymous` and `RedirectToLoginPage`. + +--- + +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. + +* `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. + +--- + +A `facebook` block 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 + +--- + +A `google` block 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/ + +--- + +A `ip_restriction` block supports the following: + +* `ip_address` - (Required) The IP Address used for this IP Restriction. + +* `subnet_mask` - (Optional) The Subnet mask used for this IP Restriction. Defaults to `255.255.255.255`. + +--- + +A `microsoft` block 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 + +--- + A `identity` block supports the following: * `type` - (Required) Specifies the identity type of the App Service. Possible values are `SystemAssigned` (where Azure will generate a Service Principal for you), `UserAssigned` where you can specify the Service Principal IDs in the `identity_ids` field, and `SystemAssigned, UserAssigned` which assigns both a system managed identity as well as the specified user assigned identities.