Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix TF issue 4151: azurerm_app_service blocks not working as expected #4328

Closed
wants to merge 2 commits into from

Conversation

neil-yechenwei
Copy link
Contributor

After tested, I found this is a bug for resource “azurerm_app_service”. User expects the configuration should be removed from app service after removed the “connection_string” settings from tf config file. Actually it won’t remove the configuration. After checked, the root cause is that the connection_string field is defined the attribute “Computed: true”, which means terraform won’t check the difference for field connection_string when the field connection_string isn’t specified in tf config file. After tested, I found the configuration can be deleted successfully after removed the attribute. And this doc "https://www.terraform.io/docs/providers/azurerm/r/app_service.html#connection_string" also instruct the field connection_string should be optional. So I’ve provided the fix.
Issue linked: terraform-providers#4151

Neil Ye (PACTERA TECHNOLOGIES INC) added 2 commits September 13, 2019 12:29
@ghost ghost added the size/S label Sep 16, 2019
@tombuildsstuff
Copy link
Contributor

hi @neil-yechenwei

Thanks for this PR.

Unfortunately the AppSettings and Connection Strings on the azurerm_app_service can be configured on Slots rather than the top-level App Service, which will take precedence when that Slot is made Active - which is why unfortunately both of these blocks have to be set to computed - for example the following Terraform Configuration:

resource "azurerm_resource_group" "test" {
  name     = "some-resource-group"
  location = "West Europe"
}

resource "azurerm_app_service_plan" "test" {
  name                = "example-appserviceplan"
  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                = "example-appservice"
  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" "first" {
  name                = "first"
  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}"

  site_config {
    dotnet_framework_version = "v4.0"
  }

  app_settings = {
    "SOME_KEY" = "some-value"
  }

  connection_string {
    name  = "Database"
    type  = "SQLServer"
    value = "Server=some-server.mydomain.com;Integrated Security=SSPI"
  }
}

resource "azurerm_app_service_slot" "second" {
  name                = "second"
  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}"

  site_config {
    dotnet_framework_version = "v4.0"
  }

  app_settings = {
    "SOME_KEY" = "some-other-value"
  }

  connection_string {
    name  = "Database"
    type  = "SQLServer"
    value = "Server=some-other-server.mydomain.com;Integrated Security=SSPI"
  }
}

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.first.name}"
}

Where changing the app_service_slot_name on the azurerm_app_service_active_slot resource would change both the app_settings and connection_strings blocks on the top level azurerm_app_service to the values from the first (or second) azurerm_app_service_slot depending on which one is active.

As such you can instead empty these blocks out by assigning an empty list to them; as shown below:

...

resource "azurerm_app_service" "test" {
  name                = "example-appservice"
  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_settings = []
  connection_strings = []
}

As such whilst I'd like to thank you for this contribution I'm going to close this PR for the moment since this behaviour is intentional to support this use-case in the Azure API.

Thanks!

@neil-yechenwei
Copy link
Contributor Author

neil-yechenwei commented Sep 16, 2019

@tombuildsstuff , thanks for your comment but I still have some concerns on it. Could you help to explain it? Thanks.
Question # 1:
After removed the "Computed=true" and re-run the test case "TestAccAzureRMAppServiceSlot_connectionStrings" which meets your use-case what you mentioned, it also work fine. So why you think "computed=true" is required for this field connection_string? Thanks.

Question # 2:
This PR is trying to fix the bug "#4151" what the user filed. The issue describes that user cannot delete all connection strings in app service once created one connection string. And I tried your above sample code, it still cannot delete the connection string with config "connection_strings = []" and threw below error. If you could, could you provide an entire sample you tested successfully for deleting all connection string after created connection string? Thanks.
Error message:
Error: Unsupported argument
on main.tf line 30, in resource "azurerm_app_service" "test":
30: connection_string = []
An argument named "connection_string" is not expected here. Did you mean to
define a block of type "connection_string"?

My sample code:
resource "azurerm_resource_group" "test" {
name = "neilappservicetestrg02"
location = "eastus2"
}

resource "azurerm_app_service_plan" "test" {
name = "neilsptest01"
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 = "neilastest01"
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
app_service_plan_id = "${azurerm_app_service_plan.test.id}"

connection_string = []
}

Question # 3:
I think it means that the field can be specified or not be specified and the diff verify for the field would be ignored while specifying "optional=true" and "computed=true" in the same time. If my understanding is incorrect, could you help to explain what does the field connection_string mean while specifying "optional =true" and "computed=true" in the same time? Thanks.

Question # 4:
You said "In order to support this use-case in Terraform both of these blocks are marked as 'Computed', which means that if a users configured values for them then we'll use those values, however if they have no values configured then we'll use whatever's returned from Azure." but I have some different idea. According by the doc https://www.terraform.io/docs/extend/schemas/schema-behaviors.html, it means the field is read-only when used "computed=true". The scenario you just said should be covered by the attributed "optional=true". Please see the doc https://www.terraform.io/docs/extend/schemas/schema-behaviors.html, right?

@caiocsgomes
Copy link

I'm having the same issue. Is there some update on this?

@ghost
Copy link

ghost commented Jan 29, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error 🤖 🙉 , please reach out to my human friends 👉 hashibot-feedback@hashicorp.com. Thanks!

@ghost ghost locked and limited conversation to collaborators Jan 29, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants