hashicorp / terraform-provider-azurerm

Terraform provider for Azure Resource Manager
https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs
Mozilla Public License 2.0
4.6k stars 4.64k forks source link

performing Create: pollingTrackerBase#updateRawBody: failed to unmarshal invalid character 'Y' #14941

Open hpaterson-abcam opened 2 years ago

hpaterson-abcam commented 2 years ago

terraform -v Terraform v0.13.4

Affected Resource(s)

resource "azurerm_aadb2c_directory

Terraform Configuration Files

resource "azurerm_resource_group" "resource_group" { name = "rgtest" location = "eastus"

tags = merge({ Name = "${var.resource_group_name}-${var.environment}" }, var.tags) } resource "azurerm_aadb2c_directory" "b2c" { country_code = "US" data_residency_location = "United States" display_name = "rgtestb2c" domain_name = "testb2cmydomain.onmicrosoft.com" resource_group_name = "rgtest" sku_name = "PremiumP2" depends_on = [azurerm_resource_group.resource_group]

tags = merge({ Name = "${var.resource_group_name}-${var.environment}" }, var.tags) }

Debug Output

. azurerm_aadb2c_directory.b2c: Creating... ╷ │ Error: performing Create: pollingTrackerBase#updateRawBody: failed to unmarshal response body: StatusCode=0 -- Original Error: invalid character 'Y' looking for beginning of value │ │ with azurerm_aadb2c_directory.b2c, │ on main.tf line 53, in resource "azurerm_aadb2c_directory" "b2c": │ 53: resource "azurerm_aadb2c_directory" "b2c" { │ │ performing Create: pollingTrackerBase#updateRawBody: failed to unmarshal │ response body: StatusCode=0 -- Original Error: invalid character 'Y' │ looking for beginning of value

Expected Behaviour

Azure b2c tenant creation

Actual Behaviour

Error

azurerm_aadb2c_directory.b2c: Creating... ╷ │ Error: performing Create: pollingTrackerBase#updateRawBody: failed to unmarshal response body: StatusCode=0 -- Original Error: invalid character 'Y' looking for beginning of value │ │ with azurerm_aadb2c_directory.b2c, │ on main.tf line 53, in resource "azurerm_aadb2c_directory" "b2c": │ 53: resource "azurerm_aadb2c_directory" "b2c" { │ │ performing Create: pollingTrackerBase#updateRawBody: failed to unmarshal │ response body: StatusCode=0 -- Original Error: invalid character 'Y' │ looking for beginning of value

Steps to Reproduce

  1. terraform apply

Important Factoids

This works on the POST online here https://docs.microsoft.com/en-us/rest/api/activedirectory/b2c-tenants/create

hpaterson-abcam commented 2 years ago

The issue only occurs when using a service principle and not when using Azure cli login (az login) ( running through gilab)

possibly related to user_impersonation permissions required by the API

https://docs.microsoft.com/en-us/rest/api/activedirectory/b2c-tenants/create#scopes

https://stackoverflow.com/questions/70416063/azure-service-principal-to-create-and-log-into-b2c-tenants

We could create a service user account to run the terraform but would then have an issue with MFA in CICD.

It would be helpful if the terraform gave a more meaningful error than above.

DevOpsFu commented 2 years ago

It makes sense that this only occurs when using a Service Principal. When creating a B2C directory, the user who created it becomes the owner of the new directory. This is achieved by the user account being added to the B2C directory as an External Member from the parent directory.

Service Principals cannot be added as external members of other directories, therefore it's not possible for a Service Principal to create a B2C directory - unless maybe at some point in the future the API supports specifying the user in the parent directory who will become the owner of the new B2C directory, or the ability for a Service Principal to impersonate a user is added.

manicminer commented 2 years ago

Yep! Alas this API only supports authenticated users and not authenticated service principals, as @DevOpsFu explained.

However it would still be good to try and handle the (malformed) error message from the API and provide a less cryptic error message than an unmarshaling error.

kethahel99 commented 2 years ago

Any way that we can specify a user from the parent directory as the owner and still use the SPN to automate the creation of the directory?

e.g. resource "azurerm_aadb2c_directory" "b2c" { country_code = "US" data_residency_location = "United States" display_name = "rgtestb2c" domain_name = "testb2cmydomain.onmicrosoft.com" resource_group_name = "rgtest" owner = "{user@domain.com}" sku_name = "PremiumP2" depends_on = [azurerm_resource_group.resource_group]

manicminer commented 2 years ago

Hi @kethahel99, unfortunately it doesn't appear so, at least there's no documented way to specify an owner or otherwise assume credentials for another principal.

markti commented 2 years ago

It would be very useful to specify / change the owner in this manner as @kethahel99 points out.

  1. Forcing the use of an interactive login breaks any sort of CI / CD pipeline tool of managing the B2C configuration.
  2. Implicitly specifying the owner through the identity that originally creates the resource results in a baton passing problem in the future. (e.g. what happens if the original creator leaves the company and user account is deleted)
manicminer commented 2 years ago

@markti This is an API limitation, service principals are not supported by the API. Additionally, the API is returning a junk response when the request is authenticated with a service principal.