Skip to content

Commit

Permalink
App Service / Function Apps: support for updating (#1125)
Browse files Browse the repository at this point in the history
* Enabling updates for App Services, which breaks the following test:

```
$ acctests azurerm TestAccAzureRMAppService_tagsUpdate
=== RUN   TestAccAzureRMAppService_tagsUpdate
--- FAIL: TestAccAzureRMAppService_tagsUpdate (109.41s)
	testing.go:513: Step 1 error: Check failed: Check 2/4 error: azurerm_app_service.test: Attribute 'tags.%' expected "2", got "1"
FAIL
exit status 1
FAIL	github.com/terraform-providers/terraform-provider-azurerm/azurerm	109.444s
```

* Updating the app service properties on an update

```
$ acctests azurerm TestAccAzureRMAppService_tagsUpdate
=== RUN   TestAccAzureRMAppService_tagsUpdate
--- PASS: TestAccAzureRMAppService_tagsUpdate (144.13s)
PASS
ok  	github.com/terraform-providers/terraform-provider-azurerm/azurerm	144.156s
```

* Added a test to handle updating function apps

* Ensuring we update function apps

* Updating the docs to remove the newly non-forcenew fields

* Ensuring we always update the app_settings

```
$ acctests azurerm TestAccAzureRMFunctionApp_siteConfigMulti
=== RUN   TestAccAzureRMFunctionApp_siteConfigMulti
--- PASS: TestAccAzureRMFunctionApp_siteConfigMulti (225.65s)
PASS
ok  	github.com/terraform-providers/terraform-provider-azurerm/azurerm	225.693s
```
  • Loading branch information
tombuildsstuff authored Apr 23, 2018
1 parent a15d68e commit c58548d
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 42 deletions.
40 changes: 29 additions & 11 deletions azurerm/resource_arm_app_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,20 +185,12 @@ func resourceArmAppService() *schema.Resource {
Type: schema.TypeBool,
Optional: true,
Default: false,

// 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": {
Expand Down Expand Up @@ -243,9 +235,7 @@ func resourceArmAppService() *schema.Resource {
},
},

// TODO: (tombuildsstuff) support Update once the API is fixed:
// https://github.com/Azure/azure-rest-api-specs/issues/1697
"tags": tagsForceNewSchema(),
"tags": tagsSchema(),

"site_credential": {
Type: schema.TypeList,
Expand Down Expand Up @@ -376,6 +366,34 @@ func resourceArmAppServiceUpdate(d *schema.ResourceData, meta interface{}) error
resGroup := id.ResourceGroup
name := id.Path["sites"]

location := azureRMNormalizeLocation(d.Get("location").(string))
appServicePlanId := d.Get("app_service_plan_id").(string)
enabled := d.Get("enabled").(bool)
httpsOnly := d.Get("https_only").(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),
HTTPSOnly: utils.Bool(httpsOnly),
SiteConfig: &siteConfig,
},
}

future, err := client.CreateOrUpdate(ctx, resGroup, name, siteEnvelope)
if err != nil {
return err
}

err = future.WaitForCompletion(ctx, client.Client)
if err != nil {
return err
}

if d.HasChange("site_config") {
// update the main configuration
siteConfig := expandAppServiceSiteConfig(d)
Expand Down
66 changes: 42 additions & 24 deletions azurerm/resource_arm_function_app.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,6 @@ func resourceArmFunctionApp() *schema.Resource {
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,
},

"version": {
Expand Down Expand Up @@ -108,9 +104,7 @@ func resourceArmFunctionApp() *schema.Resource {
},
},

// TODO: (tombuildsstuff) support Update once the API is fixed:
// https://github.com/Azure/azure-rest-api-specs/issues/1697
"tags": tagsForceNewSchema(),
"tags": tagsSchema(),

"default_hostname": {
Type: schema.TypeString,
Expand All @@ -126,20 +120,12 @@ func resourceArmFunctionApp() *schema.Resource {
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,
},

"https_only": {
Type: schema.TypeBool,
Optional: true,
Default: false,

// TODO: (tombuildsstuff) support Update once the API is fixed:
// https://github.com/Azure/azure-rest-api-specs/issues/1697
ForceNew: true,
},

"site_config": {
Expand Down Expand Up @@ -252,16 +238,48 @@ func resourceArmFunctionAppUpdate(d *schema.ResourceData, meta interface{}) erro
resGroup := id.ResourceGroup
name := id.Path["sites"]

if d.HasChange("app_settings") || d.HasChange("version") {
appSettings := expandFunctionAppAppSettings(d)
settings := web.StringDictionary{
Properties: appSettings,
}
location := azureRMNormalizeLocation(d.Get("location").(string))
kind := "functionapp"
appServicePlanID := d.Get("app_service_plan_id").(string)
enabled := d.Get("enabled").(bool)
clientAffinityEnabled := d.Get("client_affinity_enabled").(bool)
httpsOnly := d.Get("https_only").(bool)
tags := d.Get("tags").(map[string]interface{})
basicAppSettings := getBasicFunctionAppAppSettings(d)
siteConfig := expandFunctionAppSiteConfig(d)
siteConfig.AppSettings = &basicAppSettings

_, err := client.UpdateApplicationSettings(ctx, resGroup, name, settings)
if err != nil {
return fmt.Errorf("Error updating Application Settings for Function App %q: %+v", name, err)
}
siteEnvelope := web.Site{
Kind: &kind,
Location: &location,
Tags: expandTags(tags),
SiteProperties: &web.SiteProperties{
ServerFarmID: utils.String(appServicePlanID),
Enabled: utils.Bool(enabled),
ClientAffinityEnabled: utils.Bool(clientAffinityEnabled),
HTTPSOnly: utils.Bool(httpsOnly),
SiteConfig: &siteConfig,
},
}

future, err := client.CreateOrUpdate(ctx, resGroup, name, siteEnvelope)
if err != nil {
return err
}

err = future.WaitForCompletion(ctx, client.Client)
if err != nil {
return err
}

appSettings := expandFunctionAppAppSettings(d)
settings := web.StringDictionary{
Properties: appSettings,
}

_, err = client.UpdateApplicationSettings(ctx, resGroup, name, settings)
if err != nil {
return fmt.Errorf("Error updating Application Settings for Function App %q: %+v", name, err)
}

if d.HasChange("site_config") {
Expand Down
72 changes: 72 additions & 0 deletions azurerm/resource_arm_function_app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,39 @@ func TestAccAzureRMFunctionApp_tags(t *testing.T) {
})
}

func TestAccAzureRMFunctionApp_tagsUpdate(t *testing.T) {
resourceName := "azurerm_function_app.test"
ri := acctest.RandInt()
rs := strings.ToLower(acctest.RandString(11))
config := testAccAzureRMFunctionApp_tags(ri, rs, testLocation())
updatedConfig := testAccAzureRMFunctionApp_tagsUpdated(ri, rs, testLocation())

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMFunctionAppDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMFunctionAppExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "tags.%", "1"),
resource.TestCheckResourceAttr(resourceName, "tags.environment", "production"),
),
},
{
Config: updatedConfig,
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMFunctionAppExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "tags.%", "2"),
resource.TestCheckResourceAttr(resourceName, "tags.environment", "production"),
resource.TestCheckResourceAttr(resourceName, "tags.hello", "Berlin"),
),
},
},
})
}

func TestAccAzureRMFunctionApp_appSettings(t *testing.T) {
resourceName := "azurerm_function_app.test"
ri := acctest.RandInt()
Expand Down Expand Up @@ -428,6 +461,45 @@ resource "azurerm_function_app" "test" {
`, rInt, location, storage)
}

func testAccAzureRMFunctionApp_tagsUpdated(rInt int, storage string, location string) string {
return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
name = "acctestRG-%[1]d"
location = "%[2]s"
}
resource "azurerm_storage_account" "test" {
name = "acctestsa%[3]s"
resource_group_name = "${azurerm_resource_group.test.name}"
location = "${azurerm_resource_group.test.location}"
account_tier = "Standard"
account_replication_type = "LRS"
}
resource "azurerm_app_service_plan" "test" {
name = "acctestASP-%[1]d"
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
sku {
tier = "Standard"
size = "S1"
}
}
resource "azurerm_function_app" "test" {
name = "acctest-%[1]d-func"
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
app_service_plan_id = "${azurerm_app_service_plan.test.id}"
storage_connection_string = "${azurerm_storage_account.test.primary_connection_string}"
tags {
environment = "production"
hello = "Berlin"
}
}
`, rInt, location, storage)
}

func testAccAzureRMFunctionApp_version(rInt int, storage string, location string, version string) string {
return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
Expand Down
6 changes: 3 additions & 3 deletions website/docs/r/app_service.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -121,15 +121,15 @@ The following arguments are supported:

* `connection_string` - (Optional) An `connection_string` block as defined below.

* `client_affinity_enabled` - (Optional) Should the App Service send session affinity cookies, which route client requests in the same session to the same instance? Changing this forces a new resource to be created.
* `client_affinity_enabled` - (Optional) Should the App Service send session affinity cookies, which route client requests in the same session to the same instance?

* `enabled` - (Optional) Is the App Service Enabled? Changing this forces a new resource to be created.

* `https_only` - (Optional) Can the App Service only be accessed via HTTPS? Defaults to `false`. Changing this forces a new resource to be created.
* `https_only` - (Optional) Can the App Service only be accessed via HTTPS? Defaults to `false`.

* `site_config` - (Optional) A `site_config` object as defined below.

* `tags` - (Optional) A mapping of tags to assign to the resource. Changing this forces a new resource to be created.
* `tags` - (Optional) A mapping of tags to assign to the resource.

---

Expand Down
8 changes: 4 additions & 4 deletions website/docs/r/function_app.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -101,17 +101,17 @@ The following arguments are supported:

* `connection_string` - (Optional) An `connection_string` block as defined below.

* `client_affinity_enabled` - (Optional) Should the Function App send session affinity cookies, which route client requests in the same session to the same instance? Changing this forces a new resource to be created.
* `client_affinity_enabled` - (Optional) Should the Function App send session affinity cookies, which route client requests in the same session to the same instance?

* `enabled` - (Optional) Is the Function App enabled? Changing this forces a new resource to be created.
* `enabled` - (Optional) Is the Function App enabled?

* `https_only` - (Optional) Can the Function App only be accessed via HTTPS? Defaults to `false`. Changing this forces a new resource to be created.
* `https_only` - (Optional) Can the Function App only be accessed via HTTPS? Defaults to `false`.

* `version` - (Optional) The runtime version associated with the Function App. Possible values are `~1` and `beta`. Defaults to `~1`.

* `site_config` - (Optional) A `site_config` object as defined below.

* `tags` - (Optional) A mapping of tags to assign to the resource. Changing this forces a new resource to be created.
* `tags` - (Optional) A mapping of tags to assign to the resource.

---

Expand Down

0 comments on commit c58548d

Please sign in to comment.