diff --git a/azurerm/import_arm_app_service_slot_test.go b/azurerm/import_arm_app_service_slot_test.go new file mode 100644 index 000000000000..8972305edacd --- /dev/null +++ b/azurerm/import_arm_app_service_slot_test.go @@ -0,0 +1,31 @@ +package azurerm + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccAzureRMAppServiceSlot_importBasic(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + + ri := acctest.RandInt() + config := testAccAzureRMAppServiceSlot_basic(ri, testLocation()) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} diff --git a/azurerm/provider.go b/azurerm/provider.go index f114de6e0e99..4b85f7f5ca17 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -92,6 +92,8 @@ func Provider() terraform.ResourceProvider { "azurerm_application_insights": resourceArmApplicationInsights(), "azurerm_app_service": resourceArmAppService(), "azurerm_app_service_plan": resourceArmAppServicePlan(), + "azurerm_app_service_active_slot": resourceArmAppServiceActiveSlot(), + "azurerm_app_service_slot": resourceArmAppServiceSlot(), "azurerm_automation_account": resourceArmAutomationAccount(), "azurerm_automation_credential": resourceArmAutomationCredential(), "azurerm_automation_runbook": resourceArmAutomationRunbook(), diff --git a/azurerm/resource_arm_app_service_active_slot.go b/azurerm/resource_arm_app_service_active_slot.go new file mode 100644 index 000000000000..5ca4ac0f2058 --- /dev/null +++ b/azurerm/resource_arm_app_service_active_slot.go @@ -0,0 +1,112 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/web/mgmt/2016-09-01/web" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmAppServiceActiveSlot() *schema.Resource { + return &schema.Resource{ + Create: resourceArmAppServiceActiveSlotCreate, + Read: resourceArmAppServiceActiveSlotRead, + Update: resourceArmAppServiceActiveSlotCreate, + Delete: resourceArmAppServiceActiveSlotDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ + + "resource_group_name": resourceGroupNameSchema(), + + "app_service_name": { + Type: schema.TypeString, + ForceNew: true, + Required: true, + }, + + "app_service_slot_name": { + Type: schema.TypeString, + Required: true, + }, + }, + } +} + +func resourceArmAppServiceActiveSlotCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).appServicesClient + ctx := meta.(*ArmClient).StopContext + + appServiceName := d.Get("app_service_name").(string) + resGroup := d.Get("resource_group_name").(string) + targetSlot := d.Get("app_service_slot_name").(string) + preserveVnet := true + + resp, err := client.Get(ctx, resGroup, appServiceName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("[DEBUG] App Service %q (resource group %q) was not found.", appServiceName, resGroup) + } + return fmt.Errorf("Error making Read request on AzureRM App Service %q: %+v", appServiceName, err) + } + + _, err = client.Get(ctx, resGroup, targetSlot) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("[DEBUG] App Service Target Active Slot %q/%q (resource group %q) was not found.", appServiceName, targetSlot, resGroup) + } + return fmt.Errorf("Error making Read request on AzureRM App Service Slot %q/%q: %+v", appServiceName, targetSlot, err) + } + + cmsSlotEntity := web.CsmSlotEntity{ + TargetSlot: &targetSlot, + PreserveVnet: &preserveVnet, + } + + future, err := client.SwapSlotWithProduction(ctx, resGroup, appServiceName, cmsSlotEntity) + if err != nil { + return fmt.Errorf("Error swapping App Service Slot %q/%q: %+v", appServiceName, targetSlot, err) + } + err = future.WaitForCompletion(ctx, client.Client) + if err != nil { + return fmt.Errorf("Error swapping App Service Slot %q/%q: %+v", appServiceName, targetSlot, err) + } + d.SetId(*resp.ID) + return resourceArmAppServiceActiveSlotRead(d, meta) +} + +func resourceArmAppServiceActiveSlotRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).appServicesClient + ctx := meta.(*ArmClient).StopContext + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resGroup := id.ResourceGroup + name := id.Path["sites"] + + resp, err := client.Get(ctx, resGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] App Service %q (resource group %q) was not found - removing from state", name, resGroup) + d.SetId("") + return nil + } + return fmt.Errorf("Error making Read request on AzureRM App Service %q: %+v", name, err) + } + + d.Set("app_service_name", resp.Name) + d.Set("resource_group_name", resp.ResourceGroup) + d.Set("app_service_slot_name", resp.SiteProperties.SlotSwapStatus.SourceSlotName) + return nil +} + +func resourceArmAppServiceActiveSlotDelete(d *schema.ResourceData, meta interface{}) error { + // There is nothing to delete so return nil + return nil +} diff --git a/azurerm/resource_arm_app_service_active_slot_test.go b/azurerm/resource_arm_app_service_active_slot_test.go new file mode 100644 index 000000000000..8218f759a219 --- /dev/null +++ b/azurerm/resource_arm_app_service_active_slot_test.go @@ -0,0 +1,197 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccAzureRMAppServiceActiveSlot_basic(t *testing.T) { + resourceName := "azurerm_app_service_active_slot.test" + ri := acctest.RandInt() + config := testAccAzureRMAppServiceActiveSlot_basic(ri, testLocation()) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + // Destroy actually does nothing so we just return nil + CheckDestroy: nil, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "app_service_slot_name", fmt.Sprintf("acctestASSlot-%d", ri)), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceActiveSlot_update(t *testing.T) { + resourceName := "azurerm_app_service_active_slot.test" + ri := acctest.RandInt() + config := testAccAzureRMAppServiceActiveSlot_update(ri, testLocation()) + config2 := testAccAzureRMAppServiceActiveSlot_updated(ri, testLocation()) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + // Destroy actually does nothing so we just return nil + CheckDestroy: nil, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "app_service_slot_name", fmt.Sprintf("acctestASSlot-%d", ri)), + ), + }, + { + Config: config2, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "app_service_slot_name", fmt.Sprintf("acctestASSlot2-%d", ri)), + ), + }, + }, + }) +} + +func testAccAzureRMAppServiceActiveSlot_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" + app_service_name = "${azurerm_app_service.test.name}" + 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_active_slot" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_name = "${azurerm_app_service.test.name}" + app_service_slot_name = "${azurerm_app_service_slot.test.name}" + } + `, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceActiveSlot_update(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" + app_service_name = "${azurerm_app_service.test.name}" + 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" "test2" { + name = "acctestASSlot2-%d" + app_service_name = "${azurerm_app_service.test.name}" + 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_active_slot" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_name = "${azurerm_app_service.test.name}" + app_service_slot_name = "${azurerm_app_service_slot.test.name}" + } + `, rInt, location, rInt, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceActiveSlot_updated(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" + app_service_name = "${azurerm_app_service.test.name}" + 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" "test2" { + name = "acctestASSlot2-%d" + app_service_name = "${azurerm_app_service.test.name}" + 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_active_slot" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_name = "${azurerm_app_service.test.name}" + app_service_slot_name = "${azurerm_app_service_slot.test2.name}" + } + `, rInt, location, rInt, rInt, rInt, rInt) +} diff --git a/azurerm/resource_arm_app_service_slot.go b/azurerm/resource_arm_app_service_slot.go new file mode 100644 index 000000000000..389403285a87 --- /dev/null +++ b/azurerm/resource_arm_app_service_slot.go @@ -0,0 +1,467 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/web/mgmt/2016-09-01/web" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmAppServiceSlot() *schema.Resource { + return &schema.Resource{ + Create: resourceArmAppServiceSlotCreate, + Read: resourceArmAppServiceSlotRead, + Update: resourceArmAppServiceSlotUpdate, + Delete: resourceArmAppServiceSlotDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateAppServiceName, + }, + + "resource_group_name": resourceGroupNameSchema(), + + "location": locationSchema(), + + "app_service_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "app_service_plan_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "site_config": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "always_on": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + + "default_documents": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + + "dotnet_framework_version": { + Type: schema.TypeString, + Optional: true, + Default: "v4.0", + ValidateFunc: validation.StringInSlice([]string{ + "v2.0", + "v4.0", + }, true), + DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + }, + + "java_version": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + "1.7", + "1.8", + }, false), + }, + + "java_container": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + "JETTY", + "TOMCAT", + }, true), + DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + }, + + "java_container_version": { + Type: schema.TypeString, + Optional: true, + }, + + "local_mysql_enabled": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + + "managed_pipeline_mode": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{ + string(web.Classic), + string(web.Integrated), + }, true), + DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + }, + + "php_version": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + "5.5", + "5.6", + "7.0", + "7.1", + }, false), + }, + + "python_version": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + "2.7", + "3.4", + }, false), + }, + + "remote_debugging_enabled": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + + "remote_debugging_version": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{ + "VS2012", + "VS2013", + "VS2015", + "VS2017", + }, true), + DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + }, + + "use_32_bit_worker_process": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + + "websockets_enabled": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + }, + }, + }, + + "client_affinity_enabled": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + + // TODO: (tombuildsstuff) support Update once the API is fixed: + // https://github.com/Azure/azure-rest-api-specs/issues/1697 + ForceNew: true, + }, + + "enabled": { + Type: schema.TypeBool, + Optional: true, + Default: true, + + // TODO: (tombuildsstuff) support Update once the API is fixed: + // https://github.com/Azure/azure-rest-api-specs/issues/1697 + ForceNew: true, + }, + + "app_settings": { + Type: schema.TypeMap, + Optional: true, + Computed: true, + }, + + "connection_string": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + "value": { + Type: schema.TypeString, + Required: true, + }, + "type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(web.APIHub), + string(web.Custom), + string(web.DocDb), + string(web.EventHub), + string(web.MySQL), + string(web.NotificationHub), + string(web.PostgreSQL), + string(web.RedisCache), + string(web.ServiceBus), + string(web.SQLAzure), + string(web.SQLServer), + }, true), + DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + }, + }, + }, + }, + + // TODO: (tombuildsstuff) support Update once the API is fixed: + // https://github.com/Azure/azure-rest-api-specs/issues/1697 + "tags": tagsForceNewSchema(), + + "default_site_hostname": { + Type: schema.TypeString, + Computed: true, + }, + + "outbound_ip_addresses": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceArmAppServiceSlotCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).appServicesClient + + log.Printf("[INFO] preparing arguments for AzureRM App Service Slot creation.") + + slot := d.Get("name").(string) + resGroup := d.Get("resource_group_name").(string) + location := d.Get("location").(string) + appServiceName := d.Get("app_service_name").(string) + appServicePlanId := d.Get("app_service_plan_id").(string) + enabled := d.Get("enabled").(bool) + tags := d.Get("tags").(map[string]interface{}) + + siteConfig := expandAppServiceSiteConfig(d) + + siteEnvelope := web.Site{ + Location: &location, + Tags: expandTags(tags), + SiteProperties: &web.SiteProperties{ + ServerFarmID: utils.String(appServicePlanId), + Enabled: utils.Bool(enabled), + SiteConfig: &siteConfig, + }, + } + + if v, ok := d.GetOk("client_affinity_enabled"); ok { + enabled := v.(bool) + siteEnvelope.SiteProperties.ClientAffinityEnabled = utils.Bool(enabled) + } + + // NOTE: these seem like sensible defaults, in lieu of any better documentation. + skipDNSRegistration := false + forceDNSRegistration := false + skipCustomDomainVerification := true + ttlInSeconds := "60" + ctx := meta.(*ArmClient).StopContext + + resp, err := client.Get(ctx, resGroup, appServiceName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("[DEBUG] App Service %q (resource group %q) was not found.", appServiceName, resGroup) + } + return fmt.Errorf("Error making Read request on AzureRM App Service %q: %+v", appServiceName, err) + } + + createFuture, err := client.CreateOrUpdateSlot(ctx, resGroup, appServiceName, siteEnvelope, slot, &skipDNSRegistration, &skipCustomDomainVerification, &forceDNSRegistration, ttlInSeconds) + if err != nil { + return err + } + + err = createFuture.WaitForCompletion(ctx, client.Client) + if err != nil { + return err + } + + read, err := client.GetSlot(ctx, resGroup, appServiceName, slot) + if err != nil { + return err + } + + if read.ID == nil { + return fmt.Errorf("Cannot read App Service Slot %q/%q (resource group %q) ID", appServiceName, slot, resGroup) + } + + 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 + } + + resGroup := id.ResourceGroup + appServiceName := id.Path["sites"] + slot := id.Path["slots"] + + if d.HasChange("site_config") { + // update the main configuration + siteConfig := expandAppServiceSiteConfig(d) + siteConfigResource := web.SiteConfigResource{ + SiteConfig: &siteConfig, + } + _, err := client.CreateOrUpdateConfigurationSlot(ctx, resGroup, appServiceName, siteConfigResource, slot) + if err != nil { + return fmt.Errorf("Error updating Configuration for App Service Slot %q/%q: %+v", appServiceName, slot, err) + } + } + + if d.HasChange("app_settings") { + // update the AppSettings + appSettings := expandAppServiceAppSettings(d) + settings := web.StringDictionary{ + Properties: appSettings, + } + + _, err := client.UpdateApplicationSettingsSlot(ctx, resGroup, appServiceName, settings, slot) + if err != nil { + return fmt.Errorf("Error updating Application Settings for App Service Slot %q/%q: %+v", appServiceName, slot, err) + } + } + + if d.HasChange("connection_string") { + // update the ConnectionStrings + connectionStrings := expandAppServiceConnectionStrings(d) + properties := web.ConnectionStringDictionary{ + Properties: connectionStrings, + } + + _, err := client.UpdateConnectionStringsSlot(ctx, resGroup, appServiceName, properties, slot) + if err != nil { + return fmt.Errorf("Error updating Connection Strings for App Service %q/%q: %+v", appServiceName, slot, err) + } + } + + return resourceArmAppServiceSlotRead(d, meta) +} + +func resourceArmAppServiceSlotRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).appServicesClient + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resGroup := id.ResourceGroup + appServiceName := id.Path["sites"] + slot := id.Path["slots"] + + ctx := meta.(*ArmClient).StopContext + resp, err := client.GetSlot(ctx, resGroup, 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) + d.SetId("") + return nil + } + return fmt.Errorf("Error making Read request on AzureRM App Service Slot %q/%q: %+v", appServiceName, slot, err) + } + + configResp, err := client.GetConfigurationSlot(ctx, resGroup, appServiceName, slot) + if err != nil { + return fmt.Errorf("Error making Read request on AzureRM App Service Slot Configuration %q/%q: %+v", appServiceName, slot, err) + } + + appSettingsResp, err := client.ListApplicationSettingsSlot(ctx, resGroup, appServiceName, slot) + if err != nil { + return fmt.Errorf("Error making Read request on AzureRM App Service Slot AppSettings %q/%q: %+v", appServiceName, slot, err) + } + + connectionStringsResp, err := client.ListConnectionStringsSlot(ctx, resGroup, appServiceName, slot) + if err != nil { + return fmt.Errorf("Error making Read request on AzureRM App Service Slot ConnectionStrings %q/%q: %+v", appServiceName, slot, err) + } + + d.Set("name", slot) + d.Set("app_service_name", appServiceName) + d.Set("resource_group_name", resGroup) + d.Set("location", azureRMNormalizeLocation(*resp.Location)) + + if props := resp.SiteProperties; props != nil { + d.Set("app_service_plan_id", props.ServerFarmID) + d.Set("client_affinity_enabled", props.ClientAffinityEnabled) + d.Set("enabled", props.Enabled) + d.Set("default_site_hostname", props.DefaultHostName) + d.Set("outbound_ip_addresses", props.OutboundIPAddresses) + } + + if err := d.Set("app_settings", flattenAppServiceAppSettings(appSettingsResp.Properties)); err != nil { + return err + } + if err := d.Set("connection_string", flattenAppServiceConnectionStrings(connectionStringsResp.Properties)); err != nil { + return err + } + + siteConfig := flattenAppServiceSiteConfig(configResp.SiteConfig) + if err := d.Set("site_config", siteConfig); err != nil { + return err + } + + flattenAndSetTags(d, resp.Tags) + + return nil +} + +func resourceArmAppServiceSlotDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).appServicesClient + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := 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) + + deleteMetrics := true + deleteEmptyServerFarm := false + skipDNSRegistration := true + ctx := meta.(*ArmClient).StopContext + resp, err := client.DeleteSlot(ctx, resGroup, appServiceName, slot, &deleteMetrics, &deleteEmptyServerFarm, &skipDNSRegistration) + if err != nil { + if !utils.ResponseWasNotFound(resp) { + return err + } + } + + return nil +} diff --git a/azurerm/resource_arm_app_service_slot_test.go b/azurerm/resource_arm_app_service_slot_test.go new file mode 100644 index 000000000000..cb9282daf600 --- /dev/null +++ b/azurerm/resource_arm_app_service_slot_test.go @@ -0,0 +1,1266 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMAppServiceSlot_basic(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := acctest.RandInt() + config := testAccAzureRMAppServiceSlot_basic(ri, testLocation()) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_32Bit(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := acctest.RandInt() + config := testAccAzureRMAppServiceSlot_32Bit(ri, testLocation()) + + resource.Test(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.use_32_bit_worker_process", "true"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_alwaysOn(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := acctest.RandInt() + config := testAccAzureRMAppServiceSlot_alwaysOn(ri, testLocation()) + + resource.Test(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.always_on", "true"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_appSettings(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := acctest.RandInt() + config := testAccAzureRMAppServiceSlot_appSettings(ri, testLocation()) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "app_settings.foo", "bar"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_clientAffinityEnabled(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := acctest.RandInt() + config := testAccAzureRMAppServiceSlot_clientAffinityEnabled(ri, testLocation()) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "client_affinity_enabled", "true"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_connectionStrings(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := acctest.RandInt() + config := testAccAzureRMAppServiceSlot_connectionStrings(ri, testLocation()) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "connection_string.0.name", "Example"), + resource.TestCheckResourceAttr(resourceName, "connection_string.0.value", "some-postgresql-connection-string"), + resource.TestCheckResourceAttr(resourceName, "connection_string.0.type", "PostgreSQL"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_defaultDocuments(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := acctest.RandInt() + config := testAccAzureRMAppServiceSlot_defaultDocuments(ri, testLocation()) + + resource.Test(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.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_enabled(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := acctest.RandInt() + config := testAccAzureRMAppServiceSlot_enabled(ri, testLocation()) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "enabled", "false"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_localMySql(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := acctest.RandInt() + config := testAccAzureRMAppServiceSlot_localMySql(ri, testLocation()) + + resource.Test(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.local_mysql_enabled", "true"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_managedPipelineMode(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := acctest.RandInt() + config := testAccAzureRMAppServiceSlot_managedPipelineMode(ri, testLocation()) + + resource.Test(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.managed_pipeline_mode", "Classic"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_tagsUpdate(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := acctest.RandInt() + config := testAccAzureRMAppServiceSlot_tags(ri, testLocation()) + updatedConfig := testAccAzureRMAppServiceSlot_tagsUpdated(ri, testLocation()) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + 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_remoteDebugging(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := acctest.RandInt() + config := testAccAzureRMAppServiceSlot_remoteDebugging(ri, testLocation()) + + resource.Test(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.remote_debugging_enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.remote_debugging_version", "VS2015"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_windowsDotNet2(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := acctest.RandInt() + config := testAccAzureRMAppServiceSlot_windowsDotNet(ri, testLocation(), "v2.0") + + resource.Test(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.dotnet_framework_version", "v2.0"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_windowsDotNet4(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := acctest.RandInt() + config := testAccAzureRMAppServiceSlot_windowsDotNet(ri, testLocation(), "v4.0") + + resource.Test(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.dotnet_framework_version", "v4.0"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_windowsDotNetUpdate(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := acctest.RandInt() + config := testAccAzureRMAppServiceSlot_windowsDotNet(ri, testLocation(), "v2.0") + updatedConfig := testAccAzureRMAppServiceSlot_windowsDotNet(ri, testLocation(), "v4.0") + + resource.Test(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.dotnet_framework_version", "v2.0"), + ), + }, + { + Config: updatedConfig, + Check: resource.ComposeTestCheckFunc( + 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 := acctest.RandInt() + config := testAccAzureRMAppServiceSlot_windowsJava(ri, testLocation(), "1.7", "JETTY", "9.3") + + resource.Test(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", "JETTY"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container_version", "9.3"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_windowsJava8Jetty(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := acctest.RandInt() + config := testAccAzureRMAppServiceSlot_windowsJava(ri, testLocation(), "1.8", "JETTY", "9.3") + + resource.Test(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_windowsJava7Tomcat(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := acctest.RandInt() + config := testAccAzureRMAppServiceSlot_windowsJava(ri, testLocation(), "1.7", "TOMCAT", "9.0") + + resource.Test(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 := acctest.RandInt() + config := testAccAzureRMAppServiceSlot_windowsJava(ri, testLocation(), "1.8", "TOMCAT", "9.0") + + resource.Test(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_windowsPHP7(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := acctest.RandInt() + config := testAccAzureRMAppServiceSlot_windowsPHP(ri, testLocation()) + + resource.Test(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.1"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_windowsPython(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := acctest.RandInt() + config := testAccAzureRMAppServiceSlot_windowsPython(ri, testLocation()) + + resource.Test(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 := acctest.RandInt() + config := testAccAzureRMAppServiceSlot_webSockets(ri, testLocation()) + + resource.Test(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 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_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_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) 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 = true +} +`, rInt, location, rInt, rInt, rInt) +} + +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 = "Example" + value = "some-postgresql-connection-string" + type = "PostgreSQL" + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_defaultDocuments(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 { + default_documents = [ + "first.html", + "second.jsp", + "third.aspx", + ] + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_enabled(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}" + enabled = false +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_localMySql(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 { + local_mysql_enabled = true + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_managedPipelineMode(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 { + managed_pipeline_mode = "Classic" + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_tags(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}" + + tags { + "Hello" = "World" + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_tagsUpdated(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}" + + tags { + "Hello" = "World" + "Terraform" = "AcceptanceTests" + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_remoteDebugging(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 { + remote_debugging_enabled = true + remote_debugging_version = "VS2015" + } + + tags { + "Hello" = "World" + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_windowsDotNet(rInt int, location, version 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 { + dotnet_framework_version = "%s" + } +} +`, rInt, location, rInt, rInt, rInt, version) +} + +func testAccAzureRMAppServiceSlot_windowsJava(rInt int, location, javaVersion, container, containerVersion 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 { + java_version = "%s" + java_container = "%s" + java_container_version = "%s" + } +} +`, rInt, location, rInt, rInt, rInt, javaVersion, container, containerVersion) +} + +func testAccAzureRMAppServiceSlot_windowsPHP(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 { + php_version = "7.1" + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_windowsPython(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 { + python_version = "3.4" + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_webSockets(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 { + websockets_enabled = true + } +} +`, rInt, location, rInt, rInt, rInt) +} diff --git a/website/azurerm.erb b/website/azurerm.erb index 24b9de9ef5dd..12624777ffc4 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -115,6 +115,14 @@ azurerm_app_service_plan +