Home > Net >  In terraform using Azure, is it possible to create a key vault secret and reference that secret in t
In terraform using Azure, is it possible to create a key vault secret and reference that secret in t

Time:12-10

I am attempting to generate a random username and password, store them in key vault and then immediately (after they are stored) retrieve them and use them as variables in the sql server creation.

Considering this code:

resource "random_string" "username" {
  length = 24
  special = true
  override_special = "%@!"
}

resource "random_password" "password" {
  length = 24
  special = true
  override_special = "%@!"
}

# # Create KeyVault Secret
resource "azurerm_key_vault_secret" "sql-1-username" {
  name         = "sql-server-1-username"
  value        = random_string.username.result
  key_vault_id = azurerm_key_vault.key_vault.id
  tags = merge(local.common_tags, tomap({"type" = "key-vault-secret-username"}), tomap({"resource" = azurerm_mssql_server.sql-server_1.name}))
  depends_on = [azurerm_key_vault.key_vault]
}

resource "azurerm_key_vault_secret" "sql-1-password" {
  name         = "sql-server-1-password"
  value        = random_password.password.result
  key_vault_id = azurerm_key_vault.key_vault.id
  tags = merge(local.common_tags, tomap({"type" = "key-vault-secret-password"}), tomap({"resource" = azurerm_mssql_server.sql-server_1.name}))
  depends_on = [azurerm_key_vault.key_vault]
}

data "azurerm_key_vault_secret" "sql-server-1-username" {
  name = "sql-server-1-username"
  key_vault_id = azurerm_key_vault.key_vault.id
}

data "azurerm_key_vault_secret" "sql-server-1-password" {
  name = "sql-server-1-password"
  key_vault_id = azurerm_key_vault.key_vault.id
}

resource "azurerm_mssql_server" "sql-server_1" {
  name = "${local.resource-name-prefix}-sql-server-1"
  resource_group_name = local.resource-group-name
  location            = var.resource-location
  version                      = "12.0"
  administrator_login          = data.azurerm_key_vault_secret.sql-server-1-username.value
  administrator_login_password = data.azurerm_key_vault_secret.sql-server-1-password.value
  tags = merge(local.common_tags, tomap({"type" = "mssql-server"}))
}

When running this via terraform I get:

│ Error: KeyVault Secret "sql-server-1-username" <<<KEY VAULT>>> does not exist
│ 
│   with data.azurerm_key_vault_secret.sql-server-1-username,
│   on sql-server.tf line 31, in data "azurerm_key_vault_secret" "sql-server-1-username":
│   31: data "azurerm_key_vault_secret" "sql-server-1-username" {
│ 
╵
╷
│ Error: KeyVault Secret "sql-server-1-password" <<<KEY VAULT>>> does not exist
│ 
│   with data.azurerm_key_vault_secret.sql-server-1-password,
│   on sql-server.tf line 36, in data "azurerm_key_vault_secret" "sql-server-1-password":
│   36: data "azurerm_key_vault_secret" "sql-server-1-password" {
│ 

and I understand because at run time terraform is trying to evaluate that secret but it hasn't been created.

My question is, is there a way to define a value, store it as a key vault secret and then upon completion of that azurerm_key_vault_secret resource being complete, retrieve that value?

As a work around, I've put lifecycle blocks with ignore_change for the username and password values on both the key vault secret resources and the sql server. That should give me the same values in key vault being used as the username/password for the sql server, but that feels like the wrong solution.

What would be the better way?

CodePudding user response:

When using data.azurerm_key_vault_secret.* in azurerm_mssql_server it doesn't consider dependency , so instead of creating the keyvault secret it creates the sqlserver first as it doesn't have any dependencies on the resources created by the file thats the reason you get the error .

For solution , If you are creating the keyvault secret in the same file then instead of using data blocks , you can directly reference the value for administrator_login and administrator_login_password with azurerm_key_vault_secret.sql-1-username.value and azurerm_key_vault_secret.sql-1-password.value.

Your Code will be like below:

resource "random_string" "username" {
  length = 24
  special = true
  override_special = "%@!"
}

resource "random_password" "password" {
  length = 24
  special = true
  override_special = "%@!"
}

# # Create KeyVault Secret
resource "azurerm_key_vault_secret" "sql-1-username" {
  name         = "sql-server-1-username"
  value        = random_string.username.result
  key_vault_id = azurerm_key_vault.key_vault.id
  tags = merge(local.common_tags, tomap({"type" = "key-vault-secret-username"}), tomap({"resource" = azurerm_mssql_server.sql-server_1.name}))
  depends_on = [azurerm_key_vault.key_vault]
}

resource "azurerm_key_vault_secret" "sql-1-password" {
  name         = "sql-server-1-password"
  value        = random_password.password.result
  key_vault_id = azurerm_key_vault.key_vault.id
  tags = merge(local.common_tags, tomap({"type" = "key-vault-secret-password"}), tomap({"resource" = azurerm_mssql_server.sql-server_1.name}))
  depends_on = [azurerm_key_vault_secret.sql-1-username]
}


resource "azurerm_mssql_server" "sql-server_1" {
  name = "${local.resource-name-prefix}-sql-server-1"
  resource_group_name = local.resource-group-name
  location            = var.resource-location
  version                      = "12.0"
  administrator_login          = azurerm_key_vault_secret.sql-1-username.value
  administrator_login_password = azurerm_key_vault_secret.sql-1-password.value
  tags = merge(local.common_tags, tomap({"type" = "mssql-server"}))
  depends_on = [azurerm_key_vault_secret.sql-1-password]
}
  • Related