Daniel Becroft
Daniel Becroft

Reputation: 716

Terraform with Azure gives circular dependency

I'm trying to use the Azure provider to provision the infrastructure. I've got the same process working via the AzureCLI, but want to move to Terraform.

Unfortunately, I've hit a circular dependency that I can't seem to resolve. I've got the following items.

  1. Cognitive service with a generated API key
  2. AppService with a SystemAssigned identity;
  3. Keyvault, with the identity assigned in (2) given read access;
  4. Keyvault secret with the API key generated in (1).
  5. AppService in (2) needs to be updated with the secret Id generated in (3). - Problem.

Now: I need to set the configuration of the AppService to reference the secret Id that I generate when adding to the vault, but I can't.

Is there a way to edit these values so the configuration can be set up in parts? ie provision x then modify?

Edit: My Terraform file is below:

provider "azurerm" {
    version = "=1.28.0"
}

variable "TENANT_ID" {
  type = string
}

resource "azurerm_resource_group" "test" {
    name = "resourceGroup1"
    location = "australiaeast"
}

resource "azurerm_app_service_plan" "plan" {
  name = "resourceGroup1"
  location = "${azurerm_resource_group.test.location}"
  resource_group_name = "${azurerm_resource_group.test.name}"
  kind = "Linux"

  sku {
    tier = "Basic"
    size = "B1"
  }
}

resource "azurerm_cognitive_account" "cognitive" {
  name = "resourceGroup1-cognitive"
  location = "${azurerm_resource_group.test.location}"
  resource_group_name = "${azurerm_resource_group.test.name}"
  kind = "ComputerVision"

  sku {
    name = "S0"
    tier = "Standard"
  }
}

resource "azurerm_key_vault" "keyvault" {
  name = "resourceGroup1-keyvault"
  location = "${azurerm_resource_group.test.location}"
  resource_group_name = "${azurerm_resource_group.test.name}"
  tenant_id = var.TENANT_ID

  sku {
    name = "standard"
  }

  access_policy {
    tenant_id = "${azurerm_app_service.api.identity.0.tenant_id}"
    object_id = "${azurerm_app_service.api.identity.0.principal_id}"

    secret_permissions = [ "get" ]
  }
}

resource "azurerm_key_vault_secret" "keyvault-apikey" {
  name = "AzureComputerVisionApiKey"
  value = "${azurerm_cognitive_account.cognitive.primary_access_key}"
  key_vault_id = "${azurerm_key_vault.keyvault.id}"
}

resource "azurerm_app_service" "api" {
  name = "resourceGroup1-api"
  location = "${azurerm_resource_group.test.location}"
  resource_group_name = "${azurerm_resource_group.test.name}"
  app_service_plan_id = "${azurerm_app_service_plan.plan.id}"

  identity {
    type = "SystemAssigned"
  }

  app_settings = {
    "ASPNETCORE_AzureComputerVisionApiKey" = "THIS IS A NORMAL SECRET VALUE"
  }
}

If I change the value for the "ASPNETCORE_AzureComputerVisionApiKey" line to be:

    "ASPNETCORE_AzureComputerVisionApiKey" = "@Microsoft.KeyVault(${azurerm_key_vault_secret.keyvault-apikey.id})"

So that it references the Key Vault secret, I get the following error during a terraform plan operation:

Error: Cycle: azurerm_app_service.api, azurerm_key_vault.keyvault, azurerm_key_vault_secret.keyvault-apikey

Upvotes: 1

Views: 1555

Answers (1)

Charles Xu
Charles Xu

Reputation: 31414

For your issue, as the error shows, it's a problem about the cyclic dependency.

When you change the appsettings in the resource azurerm_app_service like this:

"ASPNETCORE_AzureComputerVisionApiKey" = "@Microsoft.KeyVault(${azurerm_key_vault_secret.keyvault-apikey.id})"

Then the dependency will like this:

azurerm_key_vault_secret dependents on azurerm_key_vault

azurerm_key_vault dependents on azurerm_app_service

azurerm_app_service dependents on azurerm_key_vault

So it shows the error and cannot create all the resources.

The solution is to change the sequence of the creation of resources like this:

  1. azurerm_cognitive_account
  2. azurerm_key_vault without the access policy
  3. azurerm_key_vault_secret
  4. azurerm_app_service
  5. azurerm_key_vault_access_policy

Just separate the key vault and the key vault access policy, then the cyclic dependency will disappear.

Upvotes: 4

Related Questions