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

Authentication not working with auth_settings_v2 because of not-omitted empty validation checks #20820

Closed
1 task done
mickare opened this issue Mar 7, 2023 · 19 comments · Fixed by #21091
Closed
1 task done

Comments

@mickare
Copy link

mickare commented Mar 7, 2023

Is there an existing issue for this?

  • I have searched the existing issues

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 Version

1.3.9

AzureRM Provider Version

3.45.0

Affected Resource(s)/Data Source(s)

azurerm_linux_web_app

Terraform Configuration Files

resource "azurerm_linux_web_app" "api" {
  name                = "app-test"
  location            = "westeurope"
  resource_group_name = "rg-test"

  auth_settings_v2 {
    auth_enabled             = true
    default_provider         = "aad"
    forward_proxy_convention = "NoProxy"
    require_authentication   = true
    require_https            = true
    unauthenticated_action   = "RedirectToLoginPage"
    active_directory_v2 {
      client_id                   = "---"
      tenant_auth_endpoint        = "---"
      client_secret_setting_name  = "MICROSOFT_PROVIDER_AUTHENTICATION_SECRET"
    }
  }
}

Debug Output/Panic Output

no relevance

Expected Behaviour

Expected resource json in authsettingsV2.

"azureActiveDirectory": {
  "enabled": true,
  "registration": {
    "openIdIssuer": "https://sts.windows.net/---/v2.0",
    "clientId": "---",
    "clientSecretSettingName": "MICROSOFT_PROVIDER_AUTHENTICATION_SECRET"
  },
  "login": {
    "loginParameters": [],
    "disableWWWAuthenticate": false
  },
  "validation": {
    "jwtClaimChecks": {},
    "defaultAuthorizationPolicy": {
      "allowedPrincipals": {}
    }
  }
}

Actual Behaviour

Actual resource json in authsettingsV2.

"azureActiveDirectory": {
  "enabled": true,
  "registration": {
    "openIdIssuer": "https://sts.windows.net/---/v2.0",
    "clientId": "---",
    "clientSecretSettingName": "MICROSOFT_PROVIDER_AUTHENTICATION_SECRET",
    "clientSecretCertificateThumbprint": ""
  },
  "login": {
        "loginParameters": [],
    "disableWWWAuthenticate": false
  },
  "validation": {
    "jwtClaimChecks": {
      "allowedGroups": [],
      "allowedClientApplications": []
    },
    "allowedAudiences": [],
    "defaultAuthorizationPolicy": {
      "allowedPrincipals": {
        "groups": [],
        "identities": []
      },
      "allowedApplications": []
    }
  }
}

Steps to Reproduce

No response

Important Factoids

No response

References

#20676

@mickare mickare added the bug label Mar 7, 2023
@github-actions github-actions bot removed the bug label Mar 7, 2023
@mickare mickare changed the title Authentication not working with auth_settings_v2 because of not-omited empty validation checks Authentication not working with auth_settings_v2 because of not-omitted empty validation checks Mar 7, 2023
@mickare
Copy link
Author

mickare commented Mar 7, 2023

The problem is that the app authentication is checking empty lists.
The arguments should be omitted if they are not configured.

Arguments that are not omitted if not empty:

@mickare
Copy link
Author

mickare commented Mar 7, 2023

For everyone who have this authentication issue:

https://app-test.azurewebsites.net/.auth/login/aad/callback
500 Internal Server Error

Removing the lists jwtClaimChecks.allowedGroups, jwtClaimChecks.allowedClientApplications, allowedPrincipals.groups, allowedPrincipals.identities, allowedApplications to tempoary fix the issue.

You can use the Azure Resource Explorer to temporary fix the issue (until the next Terraform deployment): https://resources.azure.com

@mickare
Copy link
Author

mickare commented Mar 7, 2023

It's a much BIGGER issue

Hey Hashicorp, I think you have a big issue with the new azure-sdk-for-go!

Azure does differentiates between not-existing configuration fields and empty values!

Description

In all azurerm models optional values and lists have a default value of that type. But the azure-sdk-for-go is using the pointers and omits the values if the pointer is null!

Example

If there is a Terraform model defining a field like:

JWTAllowedClientApps              []string          `tfschema:"jwt_allowed_client_applications"`

Terraforms default value will be: JWTAllowedClientApps := []

But the azure-sdk-for-go model definiton states, that:

AllowedClientApplications *[]string `json:"allowedClientApplications,omitempty"`

That omits the field from the json, ONLY when the value of the pointer *[]string is nil!

It means that all Terraform azurerm's pointer.To(...) must return nil, if the parameter should not be set in the configuration.
That means this example line of code will always set an empty list in the json.

AllowedClientApplications: pointer.To(aad.JWTAllowedClientApps),

Conclusion

There is a great mismatch between Terraform's azurerm default values in the models (always a value) and the azure-sdk-for-go models that omits only values if the pointer is nil.

The deployed services will not working properly because of an invalid appsevice or authentication configuration that exists but is empty.

Probably a lot more of services are affected!

@mickare
Copy link
Author

mickare commented Mar 7, 2023

Created a PR in hashicorp/go-azure-helpers to add a new pointer method FromSliceOrOmitEmpty .

This could be used to replace all the problematic pointer.To calls when creating the azure-sdk-for-go data structure

@xiaxyi
Copy link
Contributor

xiaxyi commented Mar 9, 2023

Thanks @mickare for raising this issue, I apologize for not being able to test the empty string list and the null value, can you share more details about how the empty string differs from the null when api is checking this property, did empty list mean anything for this property?

@mickare
Copy link
Author

mickare commented Mar 9, 2023

Hi @xiaxyi, there is a HUGE difference between an "empty list" and a "missing list".

Showing the problem with code is much faster.

package main

import (
	"encoding/json"
	"fmt"
)

type Model struct {
	X []int  `json:"x,omitempty"`
	Y *[]int `json:"y,omitempty"`
}

func main() {
	var slice []int

	a := Model{}
	b := Model{slice, &slice}
	c := Model{[]int{}, &[]int{}}
	d := Model{[]int{1, 2}, &[]int{3, 4}}
	fmt.Printf("a: %+v\n", a)
	fmt.Printf("b: %+v\n", b)
	fmt.Printf("c: %+v\n", c)
	fmt.Printf("d: %+v\n", d)

	a_json, _ := json.Marshal(a)
	b_json, _ := json.Marshal(b)
	c_json, _ := json.Marshal(c)
	d_json, _ := json.Marshal(d)
	fmt.Printf("a->Json: %s\n", a_json)
	fmt.Printf("b->Json: %s\n", b_json)
	fmt.Printf("c->Json: %s\n", c_json)
	fmt.Printf("d->Json: %s\n", d_json)
}

Output:

a: {X:[] Y:<nil>}
b: {X:[] Y:0xc000010030}
c: {X:[] Y:0xc000010048}
d: {X:[1 2] Y:0xc000010060}
a->Json: {}
b->Json: {"y":null}
c->Json: {"y":[]}
d->Json: {"x":[1,2],"y":[3,4]}

The difference between cases a,b,c show that it does matter if an empty pointer or an empty list is provided to any model that is serialized with json.

Case C is the problematic one when terraform-provider-azurerm models are transformed to azure-sdk-for-go models.
E.g.: AllowedClientApplications: &aad.JWTAllowedClientApps (here)

@teemukj
Copy link

teemukj commented Mar 10, 2023

Can confirm the issue when trying to configure App Service authentication with auth_settings_v2. For me the issue emerged when trying to provide pre-created app registration, after first testing it by toggling/auto-generating the auth and app registration directly from Portal.

I used hours to debug the issue, but only difference I found (comparing first the manual and auto-generated app registrations, then the actual /providers/Microsoft.Web/sites/xxx/config/authsettingsV2 resources as well.) was just what described by @mickare about the empty list stuff.

Examples of the differences in settings (az webapp auth microsoft show) when autogenerated vs. when created with Terraform:

Autogenerated (auth working):

{
  "enabled": true,
  "isAutoProvisioned": true,
  "login": {
    "disableWWWAuthenticate": false
  },
  "registration": {
    "clientId": "xxxxx",
    "clientSecretSettingName": "MICROSOFT_PROVIDER_AUTHENTICATION_SECRET",
    "openIdIssuer": "https://sts.windows.net/yyyyy/v2.0"
  },
  "validation": {
    "allowedAudiences": [
      "api://xxxxx"
    ],
    "defaultAuthorizationPolicy": {
      "allowedPrincipals": {}
    },
    "jwtClaimChecks": {}
  }
}

Created with Terraform (auth not working, HTTP 500 with no other details):

{
  "enabled": true,
  "login": {
    "disableWWWAuthenticate": false,
    "loginParameters": []
  },
  "registration": {
    "clientId": "xxxxx",
    "clientSecretCertificateThumbprint": "",
    "clientSecretSettingName": "MICROSOFT_PROVIDER_AUTHENTICATION_SECRET",
    "openIdIssuer": "https://sts.windows.net/yyyyy/v2.0"
  },
  "validation": {
    "allowedAudiences": [
      "api://xxxxx"
    ],
    "defaultAuthorizationPolicy": {
      "allowedApplications": [],
      "allowedPrincipals": {
        "groups": [],
        "identities": []
      }
    },
    "jwtClaimChecks": {
      "allowedClientApplications": [],
      "allowedGroups": []
    }
  }
}

auth_settings_v2 block used in Terraform

auth_settings_v2 {
    auth_enabled           = true
    require_authentication = true
    unauthenticated_action = "Return401"
    active_directory_v2 {
      client_id                  = "xxxxx"
      tenant_auth_endpoint       = "https://sts.windows.net/yyyyy/v2.0"
      client_secret_setting_name = "MICROSOFT_PROVIDER_AUTHENTICATION_SECRET"

      allowed_audiences = [
        "api://xxxxx"
      ]
    }
    login {
      token_store_enabled = true
    }
  }

This makes the auth_settings_v2 currently unusable.

@xiaxyi
Copy link
Contributor

xiaxyi commented Mar 10, 2023

Thanks @mickare and @teemukj for the update, I see this issue, we do need to make the non-configured field to null, instead of initating it as an empty list...

I see you are making PR to the pointer functions from sdk perspective, I'm not sure about how the reviewers' opinion about it, but I'll try seeking for solutions from the RP's perspective.

@Sanorikos
Copy link

Same issue here with data source from a azurerm_windows_web_app with configured auth_settings_v2:

data "azurerm_windows_web_app" "example" {
  name                = "web-example"
  resource_group_name = "example-rg-app"
}
╷
│ Error: encoding: setting "auth_settings_v2": Invalid address to set: []string{"auth_settings_v2", "0", "active_directory_v2", "0", "tenant_auth_endpoint"}
│
│   with data.azurerm_windows_web_app.example,
│   on 120_appservice.tf line 9, in data "azurerm_windows_web_app" "example":
│    9: data "azurerm_windows_web_app" "example" {
│
│ encoding: setting "auth_settings_v2": Invalid address to set: []string{"auth_settings_v2", "0",
│ "active_directory_v2", "0", "tenant_auth_endpoint"}
╵

@ncook-hxgn
Copy link

ncook-hxgn commented Mar 16, 2023

Same, running from Azure Pipelines (Microsoft Hosted Agent) with Service Connection, using Terraform 1.40.0 with AzureRM 3.47.0 on Ubuntu 22.04.2 LTS.

Edit: I'd just use auth_settings but I need the groups feature of the AAD auth provider.

Here's some code to reproduce:

# Run the script to get the environment variables of interest.
# This is a data source, so it will run at plan time.
# this bit of code says a lot, imho.
data "external" "env" {
  program = ["sh", "-c", "jq -n 'env | {ARM_TENANT_ID,ARM_SUBSCRIPTION_ID,ARM_CLIENT_ID,ARM_CLIENT_SECRET}'"]
}

# Define a Resource Group for an Azure App
resource "azurerm_resource_group" "example_rg" {
  name     = "${var.app_name}-rg"
  location = "West Europe"
}

# Define an Azure App Service Plan for Linux
# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service_plan
resource "azurerm_service_plan" "example_service_plan" {
  name                = "${var.app_name}-serviceplan"
  location            = azurerm_resource_group.example_rg.location
  resource_group_name = azurerm_resource_group.example_rg.name
  os_type             = "Linux"
  sku_name            = "B1"
}

# Define an Azure Web App
# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/azurerm_linux_web_app
resource "azurerm_linux_web_app" "example_wa" {
  name                = "${var.app_name}"
  resource_group_name = azurerm_resource_group.example_rg.name
  location            = azurerm_service_plan.example_service_plan.location
  service_plan_id     = azurerm_service_plan.example_service_plan.id


  # Enable a System Managed Identity for the Azure Web App
  identity {
    type = "SystemAssigned"
  }
  
  site_config {
    # iisnode
    application_stack {
      node_version = "16-lts"
    }
  }
  
  # Configure the Azure Web app with your AAD Auth Provider (see web.config)
  auth_settings_v2 {
    enabled                       = true
    allow_unauthenticated_access  = false
    issuer                        = "https://login.microsoftonline.com/${data.external.env.result["ARM_TENANT_ID"]}/v2.0"
    default_provider              = "AzureActiveDirectory"
    client_id                     = data.external.env.result["ARM_CLIENT_ID"]
    client_secret                 = data.external.env.result["ARM_CLIENT_SECRET"]
    additional_login_params       = ["scope=openid profile email User.Read"]
    token_refresh_extension_hours = 24
    token_store_enabled           = true
    unauthenticated_client_action = "RedirectToLoginPage"

    identity_providers {
      id = "AzureActiveDirectory"
      configuration {
        groups_claim = "groups"
        allowed_groups = var.app_allowed_groups
      }
    }
  }

}

# Output the Azure Web App URL
output "webapp_url" {
  value = "https://${azurerm_linux_web_app.example_wa.default_hostname}"
}

Yields

...
/opt/hostedtoolcache/terraform/1.4.0/x64/terraform validate
╷
│ Error: Unsupported block type
│ 
│   on main.tf line 46, in resource "azurerm_linux_web_app" "example_wa":
│   43:     auth_settings_v2 {
│ 
│ Blocks of type "auth_settings_v2" are not expected here.
╵
...

@teemukj
Copy link

teemukj commented Mar 16, 2023

...
/opt/hostedtoolcache/terraform/1.4.0/x64/terraform validate
╷
│ Error: Unsupported block type
│ 
│   on main.tf line 46, in resource "azurerm_linux_web_app" "example_wa":
│   43:     auth_settings_v2 {
│ 
│ Blocks of type "auth_settings_v2" are not expected here.
╵
...

@ncook-hxgn
This Unsupported block type error is not related to the same (root) issue, but rather a syntax error / misconfiguration of the auth_settings_v2 block. Also, maybe double check that your azurem provider version is actually 3.45.0 or higher, since it seems that Terraform did not recognize the auth_settings_v2 block at all, which often means that it is not available in the provider version used.

@ncook-hxgn
Copy link

ncook-hxgn commented Mar 16, 2023

@teemukj I am using Terraform 1.40.0 with AzureRM 3.47.0 on Ubuntu 22.04.2 LTS, so I don't think it's the azurerm version.

The documentation has no examples of auth_settings_v2 blocks, and to be honest it's quite hard to navigate the docs. Sometimes you click a link and get taken to a property of the same name from the parent block. Sometimes, it takes you nowhere - as it turns out, this link on the docs page for azurerm_linux_web_app for the auth_settings_v2 block goes to itself, not to the start of the section for auth_settings_v2 so that I can see what that block consists of.

I digress. Given the lack of examples to work from, is there something obviously wrong that you can see in my code?

I managed to get auth_settings working OK, but I need to use auth_settings_v2 so that I can make use of allowed_groups. .

Then, given the lack of examples of auth_settings_v2, I had Chat-GPT take a stab at what it might look like. The robot told me that whilst auth_settings is a direct child block of the azurerm_linux_web_app, the auth_settings_v2 block should be in the site_config block. Is that true? 'Cos I tried it and got the exact same error of Unsupported Block Type. There's nothing in the docs suggesting that I guess, so, I assume the robot was lying.


Edit: Yeah it looks like my terraform is the wrong structure. So, am I correct in thinking that v3.45.0 is when auth_settings_v2 was introduced?

I'm using VS Code, with the Microsoft Terraform Extension..
It's using AzureRM 3.44.. could that be why I don't get intellisense on auth_settings_v2 ? Intellisense would help me confirm I've got my block in the right place. Created Azure/vscode-azureterraform#249


Edit 2: .It looks a bit like the active_directory_v2 block isn't covered by testing? It appears to be missing from this diff from #20449..


Edit 3: This works, I get an app deployed. However, upon visiting the app and consenting to permissions, the redirect back to my site via the callback url fails. That's a seperate issue (I raised #20989), and definitely a regression from active_directory

This code is for the next person looking for an example azurerm_linux_web_app with active_directory_v2:

# Run the script to get the environment variables of interest.
# This is a data source, so it will run at plan time.
# this bit of code says a lot, imho.
data "external" "env" {
  program = ["sh", "-c", "jq -n 'env | {ARM_TENANT_ID,ARM_SUBSCRIPTION_ID,ARM_CLIENT_ID,ARM_CLIENT_SECRET}'"]
}

# Define a Resource Group for an Azure App
resource "azurerm_resource_group" "example_rg" {
  name     = "${var.app_name}-rg"
  location = "West Europe"
}

# Define an Azure App Service Plan for Linux
# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service_plan
resource "azurerm_service_plan" "example_service_plan" {
  name                = "${var.app_name}-serviceplan"
  location            = azurerm_resource_group.example_rg.location
  resource_group_name = azurerm_resource_group.example_rg.name
  os_type             = "Linux"
  sku_name            = "B1"
}

# Define an Azure Web App
# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/azurerm_linux_web_app
resource "azurerm_linux_web_app" "example_wa" {
  name                = "${var.app_name}"
  resource_group_name = azurerm_resource_group.example_rg.name
  location            = azurerm_service_plan.example_service_plan.location
  service_plan_id     = azurerm_service_plan.example_service_plan.id


  # Enable a System Managed Identity for the Azure Web App
  identity {
    type = "SystemAssigned"
  }

  # iisnode
  site_config {
    application_stack {
      node_version = "16-lts"
    }
  }

  # Configure the Azure Web app with your AAD Auth Provider (see web.config)
  auth_settings_v2 {
    auth_enabled                  = true
    require_authentication        = true
    default_provider              = "AzureActiveDirectory"
    unauthenticated_action        = "RedirectToLoginPage"

    # our default_provider:
    active_directory_v2 {
      tenant_auth_endpoint        = "https://login.microsoftonline.com/${data.external.env.result["ARM_TENANT_ID"]}/v2.0"
      client_secret_setting_name  = "MICROSOFT_PROVIDER_AUTHENTICATION_SECRET" # should be used instead of ARM_CLIENT_SECRET
      client_id                   = data.external.env.result["ARM_CLIENT_ID"]
      allowed_groups              = var.app_allowed_groups
    }

    # use a store for tokens (az blob storage backed)
    login {
      token_store_enabled = true
    }
  }
}

# Output the Azure Web App URL
output "webapp_url" {
  value = "https://${azurerm_linux_web_app.example_wa.default_hostname}"
}

@diab0l
Copy link

diab0l commented Mar 20, 2023

I've hit the same issue and resorted to using azapi as a workaround until this bug is resolved.

resource "azurerm_linux_web_app" "wa" {
  name                = var.app_name
  resource_group_name = var.resource_group_name
  location            = var.resource_location
  service_plan_id     = var.asp_id

  identity {
    type = "SystemAssigned"
  }

  site_config {
  }

  app_settings = {
    MICROSOFT_PROVIDER_AUTHENTICATION_SECRET = "${var.auth_secret}"
  }

  sticky_settings {
    app_setting_names = [
      "MICROSOFT_PROVIDER_AUTHENTICATION_SECRET"
    ]
  }

  lifecycle {
    ignore_changes = [
      auth_settings_v2
    ]
  }
}

resource "azapi_update_resource" "wa_auth_v2_config" {
  type        = "Microsoft.Web/sites/config@2022-03-01"
  resource_id = "${azurerm_linux_web_app.wa.id}/config/authsettingsV2"

  body = jsonencode({
    "properties" = {
      "globalValidation" = ...,
      "httpSettings" = ...,
      "identityProviders" = ...,
      "login" = ...
  })
  
  depends_on = [
    azurerm_linux_web_app.wa
  ]
}

It is not quite as nice as the azurerm way, but it works for now.

@spaelling

This comment was marked as off-topic.

@github-actions
Copy link

This functionality has been released in v3.49.0 of the Terraform Provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading.

For further feature requests or bug reports with this functionality, please create a new GitHub issue following the template. Thank you!

@ncook-hxgn
Copy link

I tried 3.49, and the problem might be fixed but I can't tell because it crashed.

Using the following terraform code (unchanged from before really)

# Run the script to get the environment variables of interest.
# This is a data source, so it will run at plan time.
data "external" "env" {
  program = ["sh", "-c", "jq -n 'env | {ARM_TENANT_ID,ARM_SUBSCRIPTION_ID,ARM_CLIENT_ID,ARM_CLIENT_SECRET}'"]
}

# Define a Resource Group for an Azure App
resource "azurerm_resource_group" "example_rg" {
  name     = "${var.app_name}-rg"
  location = "West Europe"
}

# Define an Azure App Service Plan for Linux
# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service_plan
resource "azurerm_service_plan" "example_service_plan" {
  name                = "${var.app_name}-serviceplan"
  location            = azurerm_resource_group.example_rg.location
  resource_group_name = azurerm_resource_group.example_rg.name
  os_type             = "Linux"
  sku_name            = "B1"
}

# Define an Azure Web App
# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/azurerm_linux_web_app
resource "azurerm_linux_web_app" "example_wa" {
  name                = "${var.app_name}"
  resource_group_name = azurerm_resource_group.example_rg.name
  location            = azurerm_service_plan.example_service_plan.location
  service_plan_id     = azurerm_service_plan.example_service_plan.id


  # Enable a System Managed Identity for the Azure Web App
  identity {
    type = "SystemAssigned"
  }

  # iisnode
  site_config {
    application_stack {
      node_version = "16-lts"
    }
  }

  # Configure the Azure Web app with your AAD Auth Provider (see web.config)
  #auth_settings {
  #  enabled                       = true
  #  issuer                        = "https://sts.windows.net/${data.external.env.result["ARM_TENANT_ID"]}"
  #  default_provider              = "AzureActiveDirectory"
  #  token_refresh_extension_hours = 24
  #  token_store_enabled           = true
  #  unauthenticated_client_action = "RedirectToLoginPage"
  #
  #  active_directory {
  #    client_id     = data.external.env.result["ARM_CLIENT_ID"]
  #    client_secret = data.external.env.result["ARM_CLIENT_SECRET"]
  #  }
  #}
  # Configure the Azure Web app with your AAD Auth Provider (see web.config)
  auth_settings_v2 {
    auth_enabled                  = true
    require_authentication        = true
    default_provider              = "AzureActiveDirectory"
    unauthenticated_action        = "RedirectToLoginPage"
    # our default_provider:
    active_directory_v2 {
      tenant_auth_endpoint        = "https://login.microsoftonline.com/${data.external.env.result["ARM_TENANT_ID"]}/v2.0"
      client_secret_setting_name  = "MICROSOFT_PROVIDER_AUTHENTICATION_SECRET"  # should be used instead of ARM_CLIENT_SECRET
      client_id                   = data.external.env.result["ARM_CLIENT_ID"]
      # client_secret               = data.external.env.result["ARM_CLIENT_SECRET"]
      allowed_groups              = var.app_allowed_groups
    }
    # use a store for tokens (az blob storage backed)
    login {
      token_store_enabled = true
    }
  }
}

# Output the Azure Web App URL
output "webapp_url" {
  value = "https://${azurerm_linux_web_app.example_wa.default_hostname}"
}

This is the output I got:

azurerm_linux_web_app.example_wa: Creating...
azurerm_linux_web_app.example_wa: Still creating... [10s elapsed]
azurerm_linux_web_app.example_wa: Still creating... [20s elapsed]
azurerm_linux_web_app.example_wa: Still creating... [30s elapsed]
azurerm_linux_web_app.example_wa: Still creating... [40s elapsed]
╷
│ Error: Plugin did not respond
│ 
│   with azurerm_linux_web_app.example_wa,
│   on main.tf line 26, in resource "azurerm_linux_web_app" "example_wa":
│   26: resource "azurerm_linux_web_app" "example_wa" {
│ 
│ The plugin encountered an error, and failed to respond to the
│ plugin.(*GRPCProvider).ApplyResourceChange call. The plugin logs may
│ contain more details.
╵

Stack trace from the terraform-provider-azurerm_v3.49.0_x5 plugin:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x49a993b]

goroutine 140 [running]:
github.com/hashicorp/terraform-provider-azurerm/internal/services/appservice/helpers.expandAadAuthV2Settings({0xc00117d7a0, 0x1, 0x0?})
	github.com/hashicorp/terraform-provider-azurerm/internal/services/appservice/helpers/auth_v2_schema.go:981 +0x55b
github.com/hashicorp/terraform-provider-azurerm/internal/services/appservice/helpers.ExpandAuthV2Settings({0xc00149f6c0, 0x1, 0x75b6c00?})
	github.com/hashicorp/terraform-provider-azurerm/internal/services/appservice/helpers/auth_v2_schema.go:2059 +0x12a
github.com/hashicorp/terraform-provider-azurerm/internal/services/appservice.LinuxWebAppResource.Create.func1({0x75c4168, 0xc001d41da0}, {0xc0027f0000, {0x75c4c90, 0xc000453cf8}, 0xc000227e80, 0x0, {0x75c60b0, 0xbb25668}})
	github.com/hashicorp/terraform-provider-azurerm/internal/services/appservice/linux_web_app_resource.go:385 +0x1b0d
github.com/hashicorp/terraform-provider-azurerm/internal/sdk.(*ResourceWrapper).Resource.func2({0x75c4168, 0xc001d41da0}, 0x1a3185c431c?, {0x617f780?, 0xc0027f0000?})
	github.com/hashicorp/terraform-provider-azurerm/internal/sdk/wrapper_resource.go:52 +0x163
github.com/hashicorp/terraform-provider-azurerm/internal/sdk.diagnosticsWrapper.func1({0x75c4168, 0xc001d41da0}, 0x0?, {0x617f780, 0xc0027f0000})
	github.com/hashicorp/terraform-provider-azurerm/internal/sdk/wrapper_resource.go:185 +0xbe
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*Resource).create(0xc000176000, {0x75c41a0, 0xc001370990}, 0xd?, {0x617f780, 0xc0027f0000})
	github.com/hashicorp/terraform-plugin-sdk/v2@v2.24.1/helper/schema/resource.go:707 +0x12e
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*Resource).Apply(0xc000176000, {0x75c41a0, 0xc001370990}, 0xc000fc2b60, 0xc000227c80, {0x617f780, 0xc0027f0000})
	github.com/hashicorp/terraform-plugin-sdk/v2@v2.24.1/helper/schema/resource.go:837 +0xa85
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*GRPCProviderServer).ApplyResourceChange(0xc0013ea2b8, {0x75c41a0?, 0xc001370870?}, 0xc00136e8c0)
	github.com/hashicorp/terraform-plugin-sdk/v2@v2.24.1/helper/schema/grpc_provider.go:1021 +0xe8d
github.com/hashicorp/terraform-plugin-go/tfprotov5/tf5server.(*server).ApplyResourceChange(0xc0013d0500, {0x75c41a0?, 0xc001370240?}, 0xc0019647e0)
	github.com/hashicorp/terraform-plugin-go@v0.14.3/tfprotov5/tf5server/server.go:818 +0x574
github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5._Provider_ApplyResourceChange_Handler({0x68d1600?, 0xc0013d0500}, {0x75c41a0, 0xc001370240}, 0xc001964770, 0x0)
	github.com/hashicorp/terraform-plugin-go@v0.14.3/tfprotov5/internal/tfplugin5/tfplugin5_grpc.pb.go:385 +0x170
google.golang.org/grpc.(*Server).processUnaryRPC(0xc000468000, {0x75d43c0, 0xc001947380}, 0xc001b80480, 0xc001a76780, 0xbae4da0, 0x0)
	google.golang.org/grpc@v1.51.0/server.go:1340 +0xd23
google.golang.org/grpc.(*Server).handleStream(0xc000468000, {0x75d43c0, 0xc001947380}, 0xc001b80480, 0x0)
	google.golang.org/grpc@v1.51.0/server.go:1713 +0xa2f
google.golang.org/grpc.(*Server).serveStreams.func1.2()
	google.golang.org/grpc@v1.51.0/server.go:965 +0x98
created by google.golang.org/grpc.(*Server).serveStreams.func1
	google.golang.org/grpc@v1.51.0/server.go:963 +0x28a

Error: The terraform-provider-azurerm_v3.49.0_x5 plugin crashed!

This is always indicative of a bug within the plugin. It would be immensely
helpful if you could report the crash with the plugin's maintainers so that it
can be fixed. The output above should help diagnose the issue.

##[debug]Exit code 1 received from tool '/opt/hostedtoolcache/terraform/1.4.2/x64/terraform'

@rapides
Copy link

rapides commented Mar 27, 2023

I tried 3.49, and the problem might be fixed but I can't tell because it crashed.

Using the following terraform code (unchanged from before really)

# Run the script to get the environment variables of interest.
# This is a data source, so it will run at plan time.
data "external" "env" {
  program = ["sh", "-c", "jq -n 'env | {ARM_TENANT_ID,ARM_SUBSCRIPTION_ID,ARM_CLIENT_ID,ARM_CLIENT_SECRET}'"]
}

# Define a Resource Group for an Azure App
resource "azurerm_resource_group" "example_rg" {
  name     = "${var.app_name}-rg"
  location = "West Europe"
}

# Define an Azure App Service Plan for Linux
# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service_plan
resource "azurerm_service_plan" "example_service_plan" {
  name                = "${var.app_name}-serviceplan"
  location            = azurerm_resource_group.example_rg.location
  resource_group_name = azurerm_resource_group.example_rg.name
  os_type             = "Linux"
  sku_name            = "B1"
}

# Define an Azure Web App
# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/azurerm_linux_web_app
resource "azurerm_linux_web_app" "example_wa" {
  name                = "${var.app_name}"
  resource_group_name = azurerm_resource_group.example_rg.name
  location            = azurerm_service_plan.example_service_plan.location
  service_plan_id     = azurerm_service_plan.example_service_plan.id


  # Enable a System Managed Identity for the Azure Web App
  identity {
    type = "SystemAssigned"
  }

  # iisnode
  site_config {
    application_stack {
      node_version = "16-lts"
    }
  }

  # Configure the Azure Web app with your AAD Auth Provider (see web.config)
  #auth_settings {
  #  enabled                       = true
  #  issuer                        = "https://sts.windows.net/${data.external.env.result["ARM_TENANT_ID"]}"
  #  default_provider              = "AzureActiveDirectory"
  #  token_refresh_extension_hours = 24
  #  token_store_enabled           = true
  #  unauthenticated_client_action = "RedirectToLoginPage"
  #
  #  active_directory {
  #    client_id     = data.external.env.result["ARM_CLIENT_ID"]
  #    client_secret = data.external.env.result["ARM_CLIENT_SECRET"]
  #  }
  #}
  # Configure the Azure Web app with your AAD Auth Provider (see web.config)
  auth_settings_v2 {
    auth_enabled                  = true
    require_authentication        = true
    default_provider              = "AzureActiveDirectory"
    unauthenticated_action        = "RedirectToLoginPage"
    # our default_provider:
    active_directory_v2 {
      tenant_auth_endpoint        = "https://login.microsoftonline.com/${data.external.env.result["ARM_TENANT_ID"]}/v2.0"
      client_secret_setting_name  = "MICROSOFT_PROVIDER_AUTHENTICATION_SECRET"  # should be used instead of ARM_CLIENT_SECRET
      client_id                   = data.external.env.result["ARM_CLIENT_ID"]
      # client_secret               = data.external.env.result["ARM_CLIENT_SECRET"]
      allowed_groups              = var.app_allowed_groups
    }
    # use a store for tokens (az blob storage backed)
    login {
      token_store_enabled = true
    }
  }
}

# Output the Azure Web App URL
output "webapp_url" {
  value = "https://${azurerm_linux_web_app.example_wa.default_hostname}"
}

This is the output I got:

azurerm_linux_web_app.example_wa: Creating...
azurerm_linux_web_app.example_wa: Still creating... [10s elapsed]
azurerm_linux_web_app.example_wa: Still creating... [20s elapsed]
azurerm_linux_web_app.example_wa: Still creating... [30s elapsed]
azurerm_linux_web_app.example_wa: Still creating... [40s elapsed]
╷
│ Error: Plugin did not respond
│ 
│   with azurerm_linux_web_app.example_wa,
│   on main.tf line 26, in resource "azurerm_linux_web_app" "example_wa":
│   26: resource "azurerm_linux_web_app" "example_wa" {
│ 
│ The plugin encountered an error, and failed to respond to the
│ plugin.(*GRPCProvider).ApplyResourceChange call. The plugin logs may
│ contain more details.
╵

Stack trace from the terraform-provider-azurerm_v3.49.0_x5 plugin:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x49a993b]

goroutine 140 [running]:
github.com/hashicorp/terraform-provider-azurerm/internal/services/appservice/helpers.expandAadAuthV2Settings({0xc00117d7a0, 0x1, 0x0?})
	github.com/hashicorp/terraform-provider-azurerm/internal/services/appservice/helpers/auth_v2_schema.go:981 +0x55b
github.com/hashicorp/terraform-provider-azurerm/internal/services/appservice/helpers.ExpandAuthV2Settings({0xc00149f6c0, 0x1, 0x75b6c00?})
	github.com/hashicorp/terraform-provider-azurerm/internal/services/appservice/helpers/auth_v2_schema.go:2059 +0x12a
github.com/hashicorp/terraform-provider-azurerm/internal/services/appservice.LinuxWebAppResource.Create.func1({0x75c4168, 0xc001d41da0}, {0xc0027f0000, {0x75c4c90, 0xc000453cf8}, 0xc000227e80, 0x0, {0x75c60b0, 0xbb25668}})
	github.com/hashicorp/terraform-provider-azurerm/internal/services/appservice/linux_web_app_resource.go:385 +0x1b0d
github.com/hashicorp/terraform-provider-azurerm/internal/sdk.(*ResourceWrapper).Resource.func2({0x75c4168, 0xc001d41da0}, 0x1a3185c431c?, {0x617f780?, 0xc0027f0000?})
	github.com/hashicorp/terraform-provider-azurerm/internal/sdk/wrapper_resource.go:52 +0x163
github.com/hashicorp/terraform-provider-azurerm/internal/sdk.diagnosticsWrapper.func1({0x75c4168, 0xc001d41da0}, 0x0?, {0x617f780, 0xc0027f0000})
	github.com/hashicorp/terraform-provider-azurerm/internal/sdk/wrapper_resource.go:185 +0xbe
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*Resource).create(0xc000176000, {0x75c41a0, 0xc001370990}, 0xd?, {0x617f780, 0xc0027f0000})
	github.com/hashicorp/terraform-plugin-sdk/v2@v2.24.1/helper/schema/resource.go:707 +0x12e
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*Resource).Apply(0xc000176000, {0x75c41a0, 0xc001370990}, 0xc000fc2b60, 0xc000227c80, {0x617f780, 0xc0027f0000})
	github.com/hashicorp/terraform-plugin-sdk/v2@v2.24.1/helper/schema/resource.go:837 +0xa85
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*GRPCProviderServer).ApplyResourceChange(0xc0013ea2b8, {0x75c41a0?, 0xc001370870?}, 0xc00136e8c0)
	github.com/hashicorp/terraform-plugin-sdk/v2@v2.24.1/helper/schema/grpc_provider.go:1021 +0xe8d
github.com/hashicorp/terraform-plugin-go/tfprotov5/tf5server.(*server).ApplyResourceChange(0xc0013d0500, {0x75c41a0?, 0xc001370240?}, 0xc0019647e0)
	github.com/hashicorp/terraform-plugin-go@v0.14.3/tfprotov5/tf5server/server.go:818 +0x574
github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5._Provider_ApplyResourceChange_Handler({0x68d1600?, 0xc0013d0500}, {0x75c41a0, 0xc001370240}, 0xc001964770, 0x0)
	github.com/hashicorp/terraform-plugin-go@v0.14.3/tfprotov5/internal/tfplugin5/tfplugin5_grpc.pb.go:385 +0x170
google.golang.org/grpc.(*Server).processUnaryRPC(0xc000468000, {0x75d43c0, 0xc001947380}, 0xc001b80480, 0xc001a76780, 0xbae4da0, 0x0)
	google.golang.org/grpc@v1.51.0/server.go:1340 +0xd23
google.golang.org/grpc.(*Server).handleStream(0xc000468000, {0x75d43c0, 0xc001947380}, 0xc001b80480, 0x0)
	google.golang.org/grpc@v1.51.0/server.go:1713 +0xa2f
google.golang.org/grpc.(*Server).serveStreams.func1.2()
	google.golang.org/grpc@v1.51.0/server.go:965 +0x98
created by google.golang.org/grpc.(*Server).serveStreams.func1
	google.golang.org/grpc@v1.51.0/server.go:963 +0x28a

Error: The terraform-provider-azurerm_v3.49.0_x5 plugin crashed!

This is always indicative of a bug within the plugin. It would be immensely
helpful if you could report the crash with the plugin's maintainers so that it
can be fixed. The output above should help diagnose the issue.

##[debug]Exit code 1 received from tool '/opt/hostedtoolcache/terraform/1.4.2/x64/terraform'

I have exactly the same issue. Does anyone work on this?

@aristosvo
Copy link
Collaborator

Fix is already merged in #21113 and will be in next release :)

@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 Apr 29, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet