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

azurerm_function_app Example Usage (Linux) in docs produces error on apply #7960

Closed
asinitson opened this issue Jul 30, 2020 · 9 comments
Closed

Comments

@asinitson
Copy link

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Terraform (and AzureRM Provider) Version

Terraform v0.12.28

  • provider.azurerm v2.20.0

Affected Resource(s)

  • azurerm_function_app
  • azurerm_app_service_plan

Terraform Configuration Files

provider "azurerm" {
  # https://github.com/terraform-providers/terraform-provider-azurerm/releases
  version = "=2.20.0"
  features {}
  subscription_id = var.subscription.internet_test
}

# Copied straight from documentation:
# https://www.terraform.io/docs/providers/azurerm/r/function_app.html#example-usage-linux-

resource "azurerm_resource_group" "example" {
  name     = "azure-functions-cptest-rg"
  location = "westus2"
}

resource "azurerm_storage_account" "example" {
  name                     = "functionsapptestsa"
  resource_group_name      = azurerm_resource_group.example.name
  location                 = azurerm_resource_group.example.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
}

resource "azurerm_app_service_plan" "example" {
  name                = "azure-functions-test-service-plan"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  kind                = "FunctionApp"

  sku {
    tier = "Dynamic"
    size = "Y1"
  }
}

resource "azurerm_function_app" "example" {
  name                      = "test-azure-functions"
  location                  = azurerm_resource_group.example.location
  resource_group_name       = azurerm_resource_group.example.name
  app_service_plan_id       = azurerm_app_service_plan.example.id
  storage_connection_string = azurerm_storage_account.example.primary_connection_string
}

Debug Output

Panic Output

Expected Behavior

When copy-pasting example from documentation working infrastructure is expected.

Actual Behavior

Terraform spits out an error when creating azurerm_app_service_plan:

Error: `reserved` has to be set to false when kind isn't set to `Linux`

Steps to Reproduce

  1. terraform apply

Important Factoids

There seem to be some confusion around:

  • Validation logic (error above)
  • Actual Azure behavior
  • Documentation

All in all it is very challenging to produce working configuration for Linux Function, since you get stuck either because of validation or incompatible configuration parameters:

Complete working example for version 2.20.0 in documentation would be helpful or at least documentation could state that Linux Function Apps are not supported in version 2.20.0 due to bugs X and Y.

References

@prabhakarreddy1234
Copy link

I faced the same issue but i followed terraform documentation and it worked.

you need to set kind to Linux in azurerm_app_service_plan

kind        = "Linux"
reserved =  true

You can refer the examples here - https://www.terraform.io/docs/providers/azurerm/r/app_service_plan.html

@njuCZ
Copy link
Contributor

njuCZ commented Jul 30, 2020

@asinitson thanks for point this Issue. This problem has been fixed by #7943, and will be available soon in next version 2.21. Before released, you could try @prabhakarreddy1234 solution for now.

@asinitson
Copy link
Author

asinitson commented Jul 30, 2020

Solution with...

kind        = "Linux"
reserved =  true

...will cause endless resource update loops since azurerm_app_service_plan will be always marked for change. That is why I am rely hesitant to use it (it really messes up workflow).

Update

Okay, found the missing part to the full solution here. So the full solution should be:

resource "azurerm_app_service_plan" "example" {
  name                = "azure-functions-test-service-plan"
  location            = azurerm_resource_group.group.location
  resource_group_name = azurerm_resource_group.group.name
  kind                = "Linux"
  reserved            = true

  sku {
    tier = "Dynamic"
    size = "Y1"
  }

  # Avoid perpetual change cycle due to kind being set to `functionapp`
  # instead of `Linux` when creating the resource in azurerm 2.20.0
  # https://github.com/terraform-providers/terraform-provider-azurerm/issues/7960
  lifecycle {
    ignore_changes = [
      kind
    ]
  }

}

@mikemowgli
Copy link

tried this morning with release 2.21.0 and could make it work with kind = "FunctionApp" and reserved = true (and no need to ignore lifecycle changes. These settings actually produce a Linux capable App Service Plan. So for me 2.21.0 fixed this issue, along with #4396.
Can you guys confirm you have the same experience?

@asinitson
Copy link
Author

asinitson commented Jul 31, 2020

After further testing with version 2.21.0 I found out some interesting behavior. (It was a surprise for me, but I guess it makes some kind of sacred marketing Microsoft sense somewhere.) Constantly marking azurerm_app_service_plan for a change behavior depends on size and tier which control compatible and allowed parameters on the Azure side. Azure falls back to allowed values instead of failing loudly (which, in my opinion, would be correct behavior), hence this enjoyable behavior.

I don't think adding additional validation on Terraform side will make things any better (it was already making things worse in version 2.20.0) since Terraform provider will be forced to keep them in sync with whatever is the latest in the Azure.

These are compatible combinations I tested and saw working well (running terraform 2nd time resulted in no changes applied):

    sku  {
        size = "Y1"
        tier = "Dynamic"
    }
    # If you try using "Linux", you will get perpetual pending change,
    # because kind will always be set to `functionapp` (lowercase for some reason)
    kind = "FunctionApp"

    # If you set this to `20` it will fallback to 1 anyway causing perpetual pending change
    maximum_elastic_worker_count = 1
    sku  {
        size = "S1"
        tier = "Standard"
   }

    # If you try using "FunctionApp", you will get perpetual pending change,
    # because kind will always be set to `linux` (lowercase for some reason)
    kind = "Linux"
    reserved = true

    # If you set this to `20` it will fallback to 1 anyway causing perpetual pending change
    maximum_elastic_worker_count = 1

@njuCZ
Copy link
Contributor

njuCZ commented Aug 3, 2020

@asinitson you are right that azure backend service will fall back to allowed values, but which could cause fields diff in terraform and lead to annoying message. What's worse, because of the diff, terraform would try to recreate it. This is absolutely not right.

So adding some validation to avoid such config could help a lot of users. They only want to correctly provision those resources without knowing the service backend implementation details.

I am sorry for the inconvinience by the bug in version 2.20, It's a wrong commit that introduced this bug, the validation logic is not right. With proper validation, it could no doubt benefit lots of people.

@asinitson
Copy link
Author

@njuCZ: The point I was making was that wrong validation is worse than no validation.

The problem with any kind of validation is that it should be based on the same rules and ideally those rules should come from the same source. Terraform validation rules cannot be the primary source of validation and they will probably always be somewhat out of date. By making a favor to the user in some cases you will be still hurting users in other cases. All this leads to the thought that it's better not to have any validation, which at least gives user the choice of providing the right configuration and check things manually.

But maybe I am making a bigger deal out this than it really and it was just one problem and otherwise validation is pretty solid and useful. Don't have much experience with Terraform to say which way it is.

@favoretti
Copy link
Collaborator

Thanks for opening this issue! Since this issue has been reported a long time ago and relates to an older version of provider - I'm going to close it. If this is still relevant and occurring on the latest version of terraform and provider please do open a new issue!

@github-actions
Copy link

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 have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 20, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants