Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 34 additions & 6 deletions infra/terraform/env/dev/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -194,13 +194,26 @@ resource "azurerm_key_vault_access_policy" "deployer" {
secret_permissions = ["Get", "List", "Set", "Delete", "Purge", "Recover"]
}

resource "azurerm_key_vault_access_policy" "ci_deployers" {
for_each = var.ci_deployer_object_ids

key_vault_id = azurerm_key_vault.kv.id
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = each.value
Comment on lines +197 to +202

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Bootstrap CI access before refreshing managed secrets

For the existing dev vault state that this change targets, the CI identity still has no data-plane permission when the workflow invokes its normal terraform apply -auto-approve (.github/workflows/infrastructure.yml:222-227). Terraform refreshes the tracked azurerm_key_vault_secret resources before it can create this policy, so those reads receive 403 and the apply exits before this resource or its depends_on edges can take effect. Consequently, merging this commit alone leaves the failed CI run unable to apply; the policy must be granted through a bootstrap path that does not require reading the existing secrets first.

Useful? React with 👍 / 👎.


secret_permissions = ["Get", "List", "Set", "Delete", "Purge", "Recover"]
}

resource "azurerm_key_vault_secret" "cosmos_endpoint" {
count = var.enable_cosmos ? 1 : 0
name = "cosmos-db-endpoint"
value = azurerm_cosmosdb_account.cosmos[0].endpoint
key_vault_id = azurerm_key_vault.kv.id

depends_on = [azurerm_key_vault_access_policy.deployer]
depends_on = [
azurerm_key_vault_access_policy.deployer,
azurerm_key_vault_access_policy.ci_deployers,
]
}

resource "azurerm_key_vault_secret" "cosmos_key" {
Expand All @@ -209,7 +222,10 @@ resource "azurerm_key_vault_secret" "cosmos_key" {
value = azurerm_cosmosdb_account.cosmos[0].primary_key
key_vault_id = azurerm_key_vault.kv.id

depends_on = [azurerm_key_vault_access_policy.deployer]
depends_on = [
azurerm_key_vault_access_policy.deployer,
azurerm_key_vault_access_policy.ci_deployers,
]
}

resource "azurerm_key_vault_secret" "cosmos_connection_string" {
Expand All @@ -218,23 +234,32 @@ resource "azurerm_key_vault_secret" "cosmos_connection_string" {
value = azurerm_cosmosdb_account.cosmos[0].primary_sql_connection_string
key_vault_id = azurerm_key_vault.kv.id

depends_on = [azurerm_key_vault_access_policy.deployer]
depends_on = [
azurerm_key_vault_access_policy.deployer,
azurerm_key_vault_access_policy.ci_deployers,
]
}

resource "azurerm_key_vault_secret" "appinsights_connection_string" {
name = "appinsights-connection-string"
value = azurerm_application_insights.ai.connection_string
key_vault_id = azurerm_key_vault.kv.id

depends_on = [azurerm_key_vault_access_policy.deployer]
depends_on = [
azurerm_key_vault_access_policy.deployer,
azurerm_key_vault_access_policy.ci_deployers,
]
}

resource "azurerm_key_vault_secret" "storage_connection_string" {
name = "storage-connection-string"
value = azurerm_storage_account.st.primary_connection_string
key_vault_id = azurerm_key_vault.kv.id

depends_on = [azurerm_key_vault_access_policy.deployer]
depends_on = [
azurerm_key_vault_access_policy.deployer,
azurerm_key_vault_access_policy.ci_deployers,
]
}

resource "azurerm_redis_cache" "redis" {
Expand All @@ -255,7 +280,10 @@ resource "azurerm_key_vault_secret" "redis_password" {
value = azurerm_redis_cache.redis[0].primary_access_key
key_vault_id = azurerm_key_vault.kv.id

depends_on = [azurerm_key_vault_access_policy.deployer]
depends_on = [
azurerm_key_vault_access_policy.deployer,
azurerm_key_vault_access_policy.ci_deployers,
]
}

resource "azurerm_cognitive_account" "openai" {
Expand Down
4 changes: 4 additions & 0 deletions infra/terraform/env/dev/terraform.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ enable_container_apps = true
enable_static_web_app = true
enable_budget_alerts = false

ci_deployer_object_ids = [
"d487629d-0758-4192-bf00-dfd4f214a738", # GitHub Actions OIDC service principal
]

admin_email = ""
monthly_budget_amount = 100

Expand Down
6 changes: 6 additions & 0 deletions infra/terraform/env/dev/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ variable "enable_budget_alerts" {
default = true
}

variable "ci_deployer_object_ids" {
type = set(string)
description = "Microsoft Entra object IDs for CI/CD principals that need Key Vault secret permissions during Terraform plan/apply."
default = []
}

variable "admin_email" {
type = string
description = "Email address that receives budget alerts. Empty disables budget alerts regardless of enable_budget_alerts."
Expand Down
Loading