diff --git a/azurerm/helpers/azure/app_service.go b/azurerm/helpers/azure/app_service.go index 14cca09c524e..e1c04dc202c8 100644 --- a/azurerm/helpers/azure/app_service.go +++ b/azurerm/helpers/azure/app_service.go @@ -196,6 +196,11 @@ func SchemaAppServiceSiteConfig() *schema.Schema { string(web.OneFullStopTwo), }, false), }, + + "virtual_network_name": { + Type: schema.TypeString, + Optional: true, + }, }, }, } @@ -321,6 +326,10 @@ func ExpandAppServiceSiteConfig(input interface{}) web.SiteConfig { siteConfig.MinTLSVersion = web.SupportedTLSVersions(v.(string)) } + if v, ok := config["virtual_network_name"]; ok { + siteConfig.VnetName = utils.String(v.(string)) + } + return siteConfig } @@ -337,14 +346,13 @@ func FlattenAppServiceSiteConfig(input *web.SiteConfig) []interface{} { result["always_on"] = *input.AlwaysOn } + documents := make([]string, 0) if input.DefaultDocuments != nil { - documents := make([]string, 0) for _, document := range *input.DefaultDocuments { documents = append(documents, document) } - - result["default_documents"] = documents } + result["default_documents"] = documents if input.NetFrameworkVersion != nil { result["dotnet_framework_version"] = *input.NetFrameworkVersion @@ -423,6 +431,10 @@ func FlattenAppServiceSiteConfig(input *web.SiteConfig) []interface{} { result["linux_fx_version"] = *input.LinuxFxVersion } + if input.VnetName != nil { + result["virtual_network_name"] = *input.VnetName + } + result["scm_type"] = string(input.ScmType) result["ftps_state"] = string(input.FtpsState) result["min_tls_version"] = string(input.MinTLSVersion) diff --git a/azurerm/resource_arm_app_service_slot_test.go b/azurerm/resource_arm_app_service_slot_test.go index a493a71788f7..742a12062b73 100644 --- a/azurerm/resource_arm_app_service_slot_test.go +++ b/azurerm/resource_arm_app_service_slot_test.go @@ -458,6 +458,34 @@ func TestAccAzureRMAppServiceSlot_remoteDebugging(t *testing.T) { }) } +func TestAccAzureRMAppServiceSlot_virtualNetwork(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := acctest.RandInt() + location := testLocation() + + resource.Test(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 := acctest.RandInt() @@ -1475,6 +1503,120 @@ resource "azurerm_app_service_slot" "test" { `, rInt, location, rInt, rInt, rInt) } +func testAccAzureRMAppServiceSlot_virtualNetwork(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_virtual_network" "test" { + name = "acctestvn-%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + subnet { + name = "internal" + address_prefix = "10.0.1.0/24" + } +} + +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 { + virtual_network_name = "${azurerm_virtual_network.test.name}" + } +} +`, rInt, location, rInt, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_virtualNetworkUpdated(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_virtual_network" "test" { + name = "acctestvn-%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + subnet { + name = "internal" + address_prefix = "10.0.1.0/24" + } +} + +resource "azurerm_virtual_network" "second" { + name = "acctestvn2-%d" + address_space = ["172.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + subnet { + name = "internal" + address_prefix = "172.0.1.0/24" + } +} + +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 { + virtual_network_name = "${azurerm_virtual_network.second.name}" + } +} +`, rInt, location, rInt, rInt, rInt, rInt, rInt) +} + func testAccAzureRMAppServiceSlot_windowsDotNet(rInt int, location, version string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { diff --git a/azurerm/resource_arm_app_service_test.go b/azurerm/resource_arm_app_service_test.go index 2f7678acda56..d9b9fb37cbca 100644 --- a/azurerm/resource_arm_app_service_test.go +++ b/azurerm/resource_arm_app_service_test.go @@ -258,6 +258,34 @@ func TestAccAzureRMAppService_clientAffinityDisabled(t *testing.T) { }) } +func TestAccAzureRMAppService_virtualNetwork(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := acctest.RandInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAppService_virtualNetwork(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.virtual_network_name", fmt.Sprintf("acctestvn-%d", ri)), + ), + }, + { + Config: testAccAzureRMAppService_virtualNetworkUpdated(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.virtual_network_name", fmt.Sprintf("acctestvn2-%d", ri)), + ), + }, + }, + }) +} + func TestAccAzureRMAppService_enableManageServiceIdentity(t *testing.T) { resourceName := "azurerm_app_service.test" @@ -1212,6 +1240,104 @@ resource "azurerm_app_service" "test" { `, rInt, location, rInt, rInt, clientAffinity) } +func testAccAzureRMAppService_virtualNetwork(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_virtual_network" "test" { + name = "acctestvn-%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + subnet { + name = "internal" + address_prefix = "10.0.1.0/24" + } +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + site_config { + virtual_network_name = "${azurerm_virtual_network.test.name}" + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppService_virtualNetworkUpdated(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_virtual_network" "test" { + name = "acctestvn-%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + subnet { + name = "internal" + address_prefix = "10.0.1.0/24" + } +} + +resource "azurerm_virtual_network" "second" { + name = "acctestvn2-%d" + address_space = ["172.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + subnet { + name = "internal" + address_prefix = "172.0.1.0/24" + } +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + site_config { + virtual_network_name = "${azurerm_virtual_network.second.name}" + } +} +`, rInt, location, rInt, rInt, rInt, rInt) +} + func testAccAzureRMAppService_mangedServiceIdentity(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { diff --git a/website/docs/d/app_service.html.markdown b/website/docs/d/app_service.html.markdown index c6bbfb0fd90d..767aa2b697d3 100644 --- a/website/docs/d/app_service.html.markdown +++ b/website/docs/d/app_service.html.markdown @@ -73,6 +73,8 @@ output "app_service_id" { * `http2_enabled` - Is HTTP2 Enabled on this App Service? +* `ftps_state` - State of FTP / FTPS service for this AppService. + * `ip_restriction` - One or more `ip_restriction` blocks as defined below. * `java_version` - The version of Java in use. @@ -81,6 +83,8 @@ output "app_service_id" { * `java_container_version` - The version of the Java Container in use. +* `linux_fx_version` - Linux App Framework and version for the AppService. + * `local_mysql_enabled` - Is "MySQL In App" Enabled? This runs a local MySQL instance with your app and shares resources from the App Service plan. * `managed_pipeline_mode` - The Managed Pipeline Mode used in this App Service. @@ -101,9 +105,7 @@ output "app_service_id" { * `websockets_enabled` - Are WebSockets enabled for this App Service? -* `ftps_state` - State of FTP / FTPS service for this AppService. - -* `linux_fx_version` - Linux App Framework and version for the AppService. +* `virtual_network_name` - The name of the Virtual Network which this App Service is attached to. --- diff --git a/website/docs/r/app_service.html.markdown b/website/docs/r/app_service.html.markdown index 910885b1427a..ffe7f4fcbe5a 100644 --- a/website/docs/r/app_service.html.markdown +++ b/website/docs/r/app_service.html.markdown @@ -157,6 +157,7 @@ The following arguments are supported: * `default_documents` - (Optional) The ordering of default documents to load, if an address isn't specified. * `dotnet_framework_version` - (Optional) The version of the .net framework's CLR used in this App Service. Possible values are `v2.0` (which will use the latest version of the .net framework for the .net CLR v2 - currently `.net 3.5`) and `v4.0` (which corresponds to the latest version of the .net CLR v4 - which at the time of writing is `.net 4.7.1`). [For more information on which .net CLR version to use based on the .net framework you're targeting - please see this table](https://en.wikipedia.org/wiki/.NET_Framework_version_history#Overview). Defaults to `v4.0`. * `http2_enabled` - (Optional) Is HTTP2 Enabled on this App Service? Defaults to `false`. +* `ftps_state` - (Optional) State of FTP / FTPS service for this AppService. Possible values include: `AllAllowed`, `FtpsOnly` and `Disabled`. * `ip_restriction` - (Optional) One or more `ip_restriction` blocks as defined below. * `java_version` - (Optional) The version of Java to use. If specified `java_container` and `java_container_version` must also be specified. Possible values are `1.7` and `1.8`. * `java_container` - (Optional) The Java Container to use. If specified `java_version` and `java_container_version` must also be specified. Possible values are `JETTY` and `TOMCAT`. @@ -166,6 +167,7 @@ The following arguments are supported: ~> **NOTE:** MySQL In App is not intended for production environments and will not scale beyond a single instance. Instead you may wish [to use Azure Database for MySQL](/docs/providers/azurerm/r/mysql_database.html). +* `linux_fx_version` - (Optional) Linux App Framework and version for the AppService, e.g. `DOCKER|(golang:latest)`. * `managed_pipeline_mode` - (Optional) The Managed Pipeline Mode. Possible values are `Integrated` and `Classic`. Defaults to `Integrated`. * `min_tls_version` - (Optional) The minimum supported TLS version for the app service. Possible values are `1.0`, `1.1`, and `1.2`. Defaults to `1.2` for new app services. * `php_version` - (Optional) The version of PHP to use in this App Service. Possible values are `5.5`, `5.6`, `7.0` and `7.1`. @@ -173,18 +175,17 @@ The following arguments are supported: * `remote_debugging_enabled` - (Optional) Is Remote Debugging Enabled? Defaults to `false`. * `remote_debugging_version` - (Optional) Which version of Visual Studio should the Remote Debugger be compatible with? Possible values are `VS2012`, `VS2013`, `VS2015` and `VS2017`. * `scm_type` - (Optional) The type of Source Control enabled for this App Service. Possible values include `None` and `LocalGit`. Defaults to `None`. + +~> **NOTE:** Additional Source Control types will be added in the future, once support for them has been added in the Azure SDK for Go. + * `use_32_bit_worker_process` - (Optional) Should the App Service run in 32 bit mode, rather than 64 bit mode? ~> **NOTE:** when using an App Service Plan in the `Free` or `Shared` Tiers `use_32_bit_worker_process` must be set to `true`. -* `ftps_state` - (Optional) State of FTP / FTPS service for this AppService. Possible values include: `AllAllowed`, `FtpsOnly` and `Disabled`. - -* `linux_fx_version` - (Optional) Linux App Framework and version for the AppService, e.g. `DOCKER|(golang:latest)`. +* `virtual_network_name` - (Optional) The name of the Virtual Network which this App Service should be attached to. * `websockets_enabled` - (Optional) Should WebSockets be enabled? -~> **NOTE:** Additional Source Control types will be added in the future, once support for them has been added in the Azure SDK for Go. - --- `ip_restriction` supports the following: diff --git a/website/docs/r/app_service_slot.html.markdown b/website/docs/r/app_service_slot.html.markdown index f8c31b57b1b0..4f547faf90bc 100644 --- a/website/docs/r/app_service_slot.html.markdown +++ b/website/docs/r/app_service_slot.html.markdown @@ -205,6 +205,8 @@ The following arguments are supported: ~> **Note:** Deployment Slots are not supported in the `Free`, `Shared`, or `Basic` App Service Plans. +* `virtual_network_name` - (Optional) The name of the Virtual Network which this App Service Slot should be attached to. + * `websockets_enabled` - (Optional) Should WebSockets be enabled? ---