betr-io / terraform-provider-mssql

Terraform provider for Microsoft SQL Server
https://registry.terraform.io/providers/betr-io/mssql/latest
MIT License
35 stars 28 forks source link

Unsure how to use azure_login #47

Open waltervos opened 2 years ago

waltervos commented 2 years ago

Hi,

I've been going around in circles for a while now, trying to manage AD users/groups in Azure SQL databases with this provider in an Azure DevOps pipeline. Here are some excerpts from my terraform project:

resource "azurerm_mssql_server" "main" {
  ...

  azuread_administrator {
    login_username = "MyAppRegistration"
    object_id      = "<The App Reg's Object/App ID>" # As it is set when I manually set this principal as admin in the Azure Portal
    tenant_id      = data.azurerm_client_config.current.tenant_id
  }
}

resource "mssql_user" "ad_user" {
  server {
    host = azurerm_mssql_server.main.fully_qualified_domain_name
    azure_login {
      tenant_id     = data.azurerm_client_config.current.tenant_id
      client_id     = "<The same App Reg's Object/App ID>"
      client_secret = "" # leaving this empty, to pick up the MSSQL_CLIENT_SECRET environment variable
    }
  }
  database  = "some_database"
  username  = "AD_GROUP_NAME"
  object_id = "<The AD group's object ID as found in the Azure Portal>"
  roles     = ["db_owner"]
  timeouts {
    default = "90s"
  }
}

In my azure-pipelines.yml, I'm executing this task to set the MSSQL_CLIENT_SECRET environment variable:

- task: AzureCLI@2
  displayName: 'Azure: Prepare Terraform'
  inputs:
    azureSubscription: '${{parameters.ServiceConnection}}'
    scriptType: ps
    scriptLocation: inlineScript
    inlineScript: |
      Write-Host "##vso[task.setvariable variable=MSSQL_CLIENT_SECRET]$($env:servicePrincipalKey)"
    addSpnToEnvironment: true

I'm using this very same $env:servicePrincipalKey to authenticate to the Azure resource manager provider, so I "know" it's valid.

Executing this definition ultimately ends in:

2022-08-31T14:58:58.455+0200 [ERROR] vertex "mssql_user.ad_user" error: unable to create user [some_database].[AD_GROUP_NAME]: db connection failed after 1m30s timeout

│ Error: unable to create user [some_database].[AD_GROUP_NAME]: db connection failed after 1m30s timeout │ │ with mssql_user.ad_user, │ on azure_sql.tf line ..., in resource "mssql_user" "ad_user": │ ...: resource "mssql_user" "ad_user" { │

When I set the TF_LOG environment variable to INFO, I can see 90 seconds worth of log messages that say: "provider.terraform-provider-mssql_v0.2.5.exe: ... failed to connect to database: parameter 'secret' cannot be empty: timestamp=..."

I've tried looking around in the source code to see if I can find where this might be going wrong but I just don't understand Go well enough to make real sense of it. As far as I can tell, the client secret is meant to be exchanged for an OAuth token. Does anybody have any thought on what I'm doing wrong, or if this is a bug of some sorts?

magne commented 1 year ago

Did you try to leave out the client_secret attribute in the azure_login block? If I remember correctly, setting it to an empty value ("") actually sets it to a value, and prevents it from being picked up from the environment variable.