Apply Terraform environments via nx release publish - #1926
Conversation
There was a problem hiding this comment.
Pull request overview
This PR extends the Nx-based Terraform tooling to support a plan-then-apply workflow for deployable Terraform environments under infra/resources/*, and wires the apply step into the existing nx release publish pipeline (release-v2.yaml). It introduces an environment.json manifest to make environment projects versionable via Nx Release (parallel to module.json for publishable modules), and adds new executors/tasks to upload a reviewed plan bundle and later apply that exact bundle.
Changes:
- Add
terraformPlanUpload+terraformApplytasks in@pagopa/dx-tasks, with plan bundle storage backed by the same Terraform backend (Azure Blob / S3). - Extend
@pagopa/nx-terraform-plugindiscovery/versioning to supportenvironment.jsonand addplan-upload+release-applyexecutors/targets for environment projects. - Update
release-v2.yamlto conditionally run infra plan/apply jobs after a successful Nx Release publish from a merged Version Packages PR.
Reviewed changes
Copilot reviewed 48 out of 74 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml | Locks new runtime deps for @pagopa/dx-tasks (AWS S3 + Azure Blob/Identity SDKs). |
| packages/nx-terraform-plugin/tsdown.config.ts | Adds build entries for new plan-upload and release-apply executors. |
| packages/nx-terraform-plugin/src/release/version-actions.ts | Extends Nx Release version manifest handling to support environment.json for applications and module.json for libraries. |
| packages/nx-terraform-plugin/src/release/tests/version-actions.test.ts | Adds coverage for environment.json version read/update behavior for application projects. |
| packages/nx-terraform-plugin/src/project.ts | Adds environment-specific release targets (tf-plan-upload, nx-release-publish→release-apply) gated by presence of environment.json. |
| packages/nx-terraform-plugin/src/options.ts | Introduces planUploadTargetName option with default tf-plan-upload. |
| packages/nx-terraform-plugin/src/manifest.ts | Adds environment.json schema + parser + typed error. |
| packages/nx-terraform-plugin/src/index.ts | Extends discovery to detect environment.json roots and pass validated manifests into project creation. |
| packages/nx-terraform-plugin/src/executors/release-apply/schema.ts | Adds zod schema/types for the release-apply executor. |
| packages/nx-terraform-plugin/src/executors/release-apply/schema.json | Adds Nx executor JSON schema for release-apply. |
| packages/nx-terraform-plugin/src/executors/release-apply/release-apply.ts | Adds executor to dispatch dx-tasks terraformApply. |
| packages/nx-terraform-plugin/src/executors/release-apply/tests/release-apply.test.ts | Adds unit tests for the release-apply executor dispatch behavior and validation. |
| packages/nx-terraform-plugin/src/executors/plan-upload/schema.ts | Adds zod schema/types for the plan-upload executor. |
| packages/nx-terraform-plugin/src/executors/plan-upload/schema.json | Adds Nx executor JSON schema for plan-upload. |
| packages/nx-terraform-plugin/src/executors/plan-upload/plan-upload.ts | Adds executor to dispatch dx-tasks terraformPlanUpload. |
| packages/nx-terraform-plugin/src/executors/plan-upload/tests/plan-upload.test.ts | Adds unit tests for the plan-upload executor dispatch behavior and validation. |
| packages/nx-terraform-plugin/src/discovery.ts | Adds environment.json manifest discovery/validation helper. |
| packages/nx-terraform-plugin/src/tests/project.test.ts | Ensures inferred targets/release config are added only when environment.json is present. |
| packages/nx-terraform-plugin/src/tests/options.test.ts | Updates options parsing test expectations for planUploadTargetName. |
| packages/nx-terraform-plugin/src/tests/index.test.ts | Updates discovery glob expectation to include environment.json. |
| packages/nx-terraform-plugin/src/tests/environment-manifest.test.ts | Adds tests for parsing/validation errors of environment.json. |
| packages/nx-terraform-plugin/src/tests/environment-discovery.test.ts | Adds tests for readEnvironmentManifest behavior and failure modes. |
| packages/nx-terraform-plugin/executors.json | Registers plan-upload and release-apply executors for Nx. |
| packages/nx-terraform-plugin/dist/release/version-actions.js | Updates committed dist output for version actions. |
| packages/nx-terraform-plugin/dist/index.js | Updates committed dist output for environment manifest discovery + targets. |
| packages/nx-terraform-plugin/dist/executors/release-apply/release-apply.js | Adds committed dist output for release-apply. |
| packages/nx-terraform-plugin/dist/executors/publish/publish.js | Updates committed dist output (import ordering change). |
| packages/nx-terraform-plugin/dist/executors/plan-upload/plan-upload.js | Adds committed dist output for plan-upload. |
| packages/dx-tasks/src/terraform/plan-upload.ts | Implements plan generation with fixed output path + bundle upload. |
| packages/dx-tasks/src/terraform/plan-storage.ts | Implements backend detection + plan bundle upload/download/delete for Azure Blob/S3. |
| packages/dx-tasks/src/terraform/plan-file.ts | Defines shared fixed plan filename (tfplan.binary). |
| packages/dx-tasks/src/terraform/apply.ts | Implements deterministic bundle download + non-interactive apply + report rendering. |
| packages/dx-tasks/src/terraform/tests/plan-upload.test.ts | Tests plan upload task contract (out path + bundle upload + failure propagation). |
| packages/dx-tasks/src/terraform/tests/plan-storage.test.ts | Tests backend parsing and Azure/S3 bundle operations. |
| packages/dx-tasks/src/terraform/tests/apply.test.ts | Tests apply flow ordering, deterministic plan path, reporting, and bundle deletion semantics. |
| packages/dx-tasks/src/tasks.ts | Registers new terraformPlanUpload and terraformApply tasks. |
| packages/dx-tasks/src/index.ts | Exports terraformApplyReportNamespace. |
| packages/dx-tasks/src/default-dispatcher.ts | Registers new tasks and apply report namespace in the default dispatcher. |
| packages/dx-tasks/README.md | Documents the new two-phase plan-upload/apply flow and its guarantees. |
| packages/dx-tasks/package.json | Adds runtime dependencies for S3/Azure plan bundle storage. |
| nx.json | Adds infra/resources/* to Nx workspace layout globs. |
| infra/resources/prod/environment.json | Adds initial environment manifest for prod (version tracked by Nx release). |
| infra/resources/dev/environment.json | Adds initial environment manifest for dev (version tracked by Nx release). |
| actions/run-dx-task/dist/sts-DDWGGX27.mjs | Updates bundled action dist output (dependency graph changes). |
| actions/run-dx-task/dist/sso-oidc-BTzPTtFh.mjs | Updates bundled action dist output. |
| actions/run-dx-task/dist/signin-dYF3Ny11.mjs | Updates bundled action dist output. |
| actions/run-dx-task/dist/protocols-DBrQMhkG.mjs | Updates bundled action dist output. |
| actions/run-dx-task/dist/package-CWUbVncD.mjs | Updates bundled action dist output. |
| actions/run-dx-task/dist/dist-cjs-DagSoMyA.mjs | Updates bundled action dist output. |
| actions/run-dx-task/dist/dist-cjs-D44eV2pe.mjs | Updates bundled action dist output. |
| actions/run-dx-task/dist/dist-cjs-C_zZvNfb.mjs | Updates bundled action dist output. |
| actions/run-dx-task/dist/dist-cjs-BSDmKwcD.mjs | Updates bundled action dist output. |
| actions/run-dx-task/dist/dist-cjs-BOMh5aL3.mjs | Updates bundled action dist output. |
| actions/run-dx-task/dist/dist-cjs-Bm3Qasiq.mjs | Updates bundled action dist output. |
| actions/run-dx-task/dist/chunk-BTyA9uPd.mjs | Updates bundled action dist output. |
| actions/nx-release/tsup.config.ts | Adds new script entry to build (extract-infra-projects-to-apply). |
| actions/nx-release/scripts/shared.ts | Adds isEnvironmentProject() helper (tag-based). |
| actions/nx-release/scripts/extract-infra-projects-to-apply.ts | New script to derive environment projects from merged Version Packages PR tags. |
| actions/nx-release/scripts/dist/shared.js | Updates built shared script exports to include isEnvironmentProject. |
| actions/nx-release/scripts/tests/shared-is-environment-project.test.ts | Tests environment-tag detection for projects. |
| actions/nx-release/scripts/tests/extract-infra-projects-to-apply.test.ts | Tests project extraction logic from PR body/tag metadata. |
| actions/nx-release/README.md | Documents new action outputs (release-mode, published-pr-number). |
| actions/nx-release/action.yaml | Exposes release-mode + published-pr-number outputs and emits PR number in publish mode. |
| .nx/version-plans/version-plan-1782922991561.md | Version plan for nx-release output contract change. |
| .nx/version-plans/version-plan-1782919859121.md | Version plan for @pagopa/nx-terraform-plugin new executors/targets. |
| .nx/version-plans/version-plan-1782919849313.md | Version plan for @pagopa/dx-tasks new plan/apply + storage support. |
| .github/workflows/release-v2.yaml | Adds conditional infra plan/apply jobs gated on Nx Release publish mode and merged PR number. |
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
- Updated plan-upload, plan, and release-apply executors to accept `sensitiveKeys` option for redacting sensitive Terraform output. - Modified schemas and JSON configurations to include `sensitiveKeys` as an array of strings. - Enhanced tests to validate the handling of sensitive output keys across executors. - Updated options schema to include `sensitiveOutputKeys` for plugin configuration.
|
Keep Terraform environment releases serialized using the supported GitHub Actions concurrency settings. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Ensure Nx release bookkeeping uses environment.json for application projects and module.json for libraries. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Honor Nx dry-run signals so release previews cannot dispatch infrastructure changes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Only deploy commits reachable from the protected default branch and derive credentialed runner and environment settings from trusted environment manifests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Expose runnable JavaScript and declaration files instead of raw TypeScript from the package exports map. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Include dependency source inputs in both Terraform plan storage action build hashes so Nx cannot restore stale bundles. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep committed action and plugin artifacts aligned with the reviewed source fixes and compiled dx-tasks exports. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Accept only commits that are ancestors of or identical to the protected default branch head. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Make the apply job depend directly on validation so it can use the trusted runner, environment, and source commit outputs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep the documented tasks subpath available after moving package exports to compiled JavaScript. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep the deployment workflow focused on orchestration by validating trusted commits, manifests, and protected environments in a tested reusable task. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
📋 Pre-commit Output LogGenerated on Wed Jul 15 16:11:20 UTC 2026 |
|
Tip ✅ All Terraform module locks are up to dateNo module changes detected - everything is in sync! 📋 Pre-commit Output LogGenerated on Wed Jul 15 16:12:01 UTC 2026 |
|
Tip ✅ All Terraform module locks are up to dateNo module changes detected - everything is in sync! 📋 Pre-commit Output LogGenerated on Wed Jul 15 16:12:02 UTC 2026 |
|
Azure Static Web Apps: Your stage site is ready! Visit it here: https://proud-mud-0405c6703-1926.westeurope.1.azurestaticapps.net |
📖 Terraform Plan (infra/resources/prod) - successShow Plan # module.metrics_portal.module.container_app.azurerm_container_app.this has changed
~ resource "azurerm_container_app" "this" {
id = "/subscriptions/02a23258-2e41-433c-8e9a-465b99e77bca/resourceGroups/dx-p-itn-common-rg-01/providers/Microsoft.App/containerApps/dx-p-itn-metrics-portal-ca-01"
~ latest_revision_fqdn = "dx-p-itn-metrics-portal-ca-01--8peu.gentlesmoke-9b3e8724.italynorth.azurecontainerapps.io" -> "dx-p-itn-metrics-portal-ca-01--ji90.gentlesmoke-9b3e8724.italynorth.azurecontainerapps.io"
name = "dx-p-itn-metrics-portal-ca-01"
tags = {
"CostCenter" = "TS000 - Tecnologia e Servizi"
"CreatedBy" = "Terraform"
"Environment" = "Prod"
"ManagementTeam" = "Developer Experience"
"ModuleName" = "azure_container_app"
"ModuleSource" = "DX"
"ModuleVersion" = "4.2.0"
"Owner" = "DevEx"
"Source" = "https://github.com/pagopa/dx/blob/main/infra/resources/prod"
}
# (9 unchanged attributes hidden)
# (5 unchanged blocks hidden)
}
Unless you have made equivalent changes to your configuration, or ignored the
relevant attributes using ignore_changes, the following plan may include
actions to undo or respond to these changes.
─────────────────────────────────────────────────────────────────────────────
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
~ update in-place
Terraform will perform the following actions:
# module.mcp_server.aws_s3_bucket_server_side_encryption_configuration.mcp_knowledge_base will be updated in-place
~ resource "aws_s3_bucket_server_side_encryption_configuration" "mcp_knowledge_base" {
id = "dx-p-euc1-docs-kb-s3-01"
# (3 unchanged attributes hidden)
- rule {
- blocked_encryption_types = [
- "SSE-C",
] -> null
- bucket_key_enabled = false -> null
- apply_server_side_encryption_by_default {
- sse_algorithm = "AES256" -> null
# (1 unchanged attribute hidden)
}
}
+ rule {
+ blocked_encryption_types = []
+ apply_server_side_encryption_by_default {
+ sse_algorithm = "AES256"
# (1 unchanged attribute hidden)
}
}
}
# module.metrics_portal.azurerm_container_app_job.import will be updated in-place
~ resource "azurerm_container_app_job" "import" {
id = "/subscriptions/02a23258-2e41-433c-8e9a-465b99e77bca/resourceGroups/dx-p-itn-common-rg-01/providers/Microsoft.App/jobs/dx-p-itn-metrics-portal-caj-01"
name = "dx-p-itn-metrics-portal-caj-01"
tags = {
"CostCenter" = "TS000 - Tecnologia e Servizi"
"CreatedBy" = "Terraform"
"Environment" = "Prod"
"ManagementTeam" = "Developer Experience"
"Owner" = "DevEx"
"Source" = "https://github.com/pagopa/dx/blob/main/infra/resources/prod"
}
# (8 unchanged attributes hidden)
- secret {
# At least one attribute in this block is (or was) sensitive,
# so its contents will not be displayed.
}
- secret {
# At least one attribute in this block is (or was) sensitive,
# so its contents will not be displayed.
}
- secret {
# At least one attribute in this block is (or was) sensitive,
# so its contents will not be displayed.
}
- secret {
# At least one attribute in this block is (or was) sensitive,
# so its contents will not be displayed.
}
+ secret {
# At least one attribute in this block is (or was) sensitive,
# so its contents will not be displayed.
}
+ secret {
# At least one attribute in this block is (or was) sensitive,
# so its contents will not be displayed.
}
+ secret {
# At least one attribute in this block is (or was) sensitive,
# so its contents will not be displayed.
}
+ secret {
# At least one attribute in this block is (or was) sensitive,
# so its contents will not be displayed.
}
# (3 unchanged blocks hidden)
}
# module.metrics_portal.azurerm_key_vault_secret.github_app_private_key will be updated in-place
~ resource "azurerm_key_vault_secret" "github_app_private_key" {
id = "https://dx-p-itn-common-kv-01.vault.azure.net/secrets/dx-metrics-github-app-private-key/23abb2ec910b4ca28c4d43b558a9c7b1"
name = "dx-metrics-github-app-private-key"
~ tags = {
- "file-encoding" = "utf-8" -> null
}
# (11 unchanged attributes hidden)
}
# module.metrics_portal.module.container_app.azapi_resource.managed_certificate[0] will be updated in-place
~ resource "azapi_resource" "managed_certificate" {
id = "/subscriptions/02a23258-2e41-433c-8e9a-465b99e77bca/resourceGroups/dx-p-itn-common-rg-01/providers/Microsoft.App/managedEnvironments/dx-p-itn-common-cae-01/managedCertificates/cert-metrics-dx-pagopa-it"
name = "cert-metrics-dx-pagopa-it"
~ output = {
- id = "/subscriptions/02a23258-2e41-433c-8e9a-465b99e77bca/resourceGroups/dx-p-itn-common-rg-01/providers/Microsoft.App/managedEnvironments/dx-p-itn-common-cae-01/managedCertificates/cert-metrics-dx-pagopa-it"
- properties = {
- provisioningState = "Succeeded"
}
- type = "Microsoft.App/managedEnvironments/managedCertificates"
} -> (known after apply)
+ tags = {
+ "CostCenter" = "TS000 - Tecnologia e Servizi"
+ "CreatedBy" = "Terraform"
+ "Environment" = "Prod"
+ "ManagementTeam" = "Developer Experience"
+ "ModuleName" = "azure_container_app"
+ "ModuleSource" = "DX"
+ "ModuleVersion" = "4.2.2"
+ "Owner" = "DevEx"
+ "Source" = "https://github.com/pagopa/dx/blob/main/infra/resources/prod"
}
# (9 unchanged attributes hidden)
}
# module.metrics_portal.module.container_app.azurerm_container_app.this will be updated in-place
~ resource "azurerm_container_app" "this" {
id = "/subscriptions/02a23258-2e41-433c-8e9a-465b99e77bca/resourceGroups/dx-p-itn-common-rg-01/providers/Microsoft.App/containerApps/dx-p-itn-metrics-portal-ca-01"
name = "dx-p-itn-metrics-portal-ca-01"
~ tags = {
"CostCenter" = "TS000 - Tecnologia e Servizi"
"CreatedBy" = "Terraform"
"Environment" = "Prod"
"ManagementTeam" = "Developer Experience"
"ModuleName" = "azure_container_app"
"ModuleSource" = "DX"
~ "ModuleVersion" = "4.2.0" -> "4.2.2"
"Owner" = "DevEx"
"Source" = "https://github.com/pagopa/dx/blob/main/infra/resources/prod"
}
# (10 unchanged attributes hidden)
# (5 unchanged blocks hidden)
}
# module.metrics_portal.module.container_app.azurerm_dns_cname_record.this[0] will be updated in-place
~ resource "azurerm_dns_cname_record" "this" {
id = "/subscriptions/02a23258-2e41-433c-8e9a-465b99e77bca/resourceGroups/dx-p-itn-network-rg-01/providers/Microsoft.Network/dnsZones/dx.pagopa.it/CNAME/metrics"
name = "metrics"
~ tags = {
"CostCenter" = "TS000 - Tecnologia e Servizi"
"CreatedBy" = "Terraform"
"Environment" = "Prod"
"ManagementTeam" = "Developer Experience"
"ModuleName" = "azure_container_app"
"ModuleSource" = "DX"
~ "ModuleVersion" = "4.2.0" -> "4.2.2"
"Owner" = "DevEx"
"Source" = "https://github.com/pagopa/dx/blob/main/infra/resources/prod"
}
# (6 unchanged attributes hidden)
}
# module.metrics_portal.module.container_app.azurerm_dns_txt_record.validation[0] will be updated in-place
~ resource "azurerm_dns_txt_record" "validation" {
id = "/subscriptions/02a23258-2e41-433c-8e9a-465b99e77bca/resourceGroups/dx-p-itn-network-rg-01/providers/Microsoft.Network/dnsZones/dx.pagopa.it/TXT/asuid.metrics"
name = "asuid.metrics"
~ tags = {
"CostCenter" = "TS000 - Tecnologia e Servizi"
"CreatedBy" = "Terraform"
"Environment" = "Prod"
"ManagementTeam" = "Developer Experience"
"ModuleName" = "azure_container_app"
"ModuleSource" = "DX"
~ "ModuleVersion" = "4.2.0" -> "4.2.2"
"Owner" = "DevEx"
"Source" = "https://github.com/pagopa/dx/blob/main/infra/resources/prod"
}
# (4 unchanged attributes hidden)
# (1 unchanged block hidden)
}
Plan: 0 to add, 7 to change, 0 to destroy.
Warning: Argument is deprecated
with module.container_app_infra.azurerm_monitor_diagnostic_setting.container_app_environment,
on .terraform/modules/container_app_infra/monitoring.tf line 3, in resource "azurerm_monitor_diagnostic_setting" "container_app_environment":
3: resource "azurerm_monitor_diagnostic_setting" "container_app_environment" {
`metric` has been deprecated in favour of the `enabled_metric` property and
will be removed in v5.0 of the AzureRM provider |
Code Review ReportTerraform Plan:
|
📖 Terraform Plan (infra/resources/dev) - successShow Plan # module.ai_foundry.azurerm_cognitive_account.this will be destroyed
# (because azurerm_cognitive_account.this is not in configuration)
- resource "azurerm_cognitive_account" "this" {
- custom_subdomain_name = "dx-d-itn-aif-01" -> null
- dynamic_throttling_enabled = false -> null
- endpoint = "https://dx-d-itn-aif-01.cognitiveservices.azure.com/" -> null
- fqdns = [] -> null
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-ai-rg-01/providers/Microsoft.CognitiveServices/accounts/dx-d-itn-aif-01" -> null
- kind = "AIServices" -> null
- local_auth_enabled = false -> null
- location = "italynorth" -> null
- name = "dx-d-itn-aif-01" -> null
- outbound_network_access_restricted = false -> null
- project_management_enabled = true -> null
- public_network_access_enabled = false -> null
- resource_group_name = "dx-d-itn-ai-rg-01" -> null
- sku_name = "S0" -> null
- tags = {
- "BusinessUnit" = "DevEx"
- "CostCenter" = "TS000 - Tecnologia e Servizi"
- "CreatedBy" = "Terraform"
- "Environment" = "Dev"
- "ManagementTeam" = "Developer Experience"
- "Source" = "https://github.com/pagopa/dx/blob/main/infra/resources/dev"
} -> null
# (6 unchanged attributes hidden)
- identity {
- identity_ids = [] -> null
- principal_id = "e39e5ffa-ddbe-4180-b130-b7cd00e36ce8" -> null
- tenant_id = "7788edaf-0346-4068-9d79-c868aed15b3d" -> null
- type = "SystemAssigned" -> null
}
- network_acls {
- bypass = "AzureServices" -> null
- default_action = "Deny" -> null
- ip_rules = [] -> null
}
- storage {
- storage_account_id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-ai-rg-01/providers/Microsoft.Storage/storageAccounts/dxditnaist01" -> null
# (1 unchanged attribute hidden)
}
}
# module.ai_foundry.azurerm_cognitive_account_project.terraform_ci will be destroyed
# (because azurerm_cognitive_account_project.terraform_ci is not in configuration)
- resource "azurerm_cognitive_account_project" "terraform_ci" {
- cognitive_account_id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-ai-rg-01/providers/Microsoft.CognitiveServices/accounts/dx-d-itn-aif-01" -> null
- default = true -> null
- description = "Enforce rules at CI stage" -> null
- display_name = "Terraform CI" -> null
- endpoints = {
- "AI Foundry API" = "https://dx-d-itn-aif-01.services.ai.azure.com/api/projects/dx-d-itn-terraformci-proj-01"
} -> null
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-ai-rg-01/providers/Microsoft.CognitiveServices/accounts/dx-d-itn-aif-01/projects/dx-d-itn-terraformci-proj-01" -> null
- location = "italynorth" -> null
- name = "dx-d-itn-terraformci-proj-01" -> null
- tags = {
- "BusinessUnit" = "DevEx"
- "CostCenter" = "TS000 - Tecnologia e Servizi"
- "CreatedBy" = "Terraform"
- "Environment" = "Dev"
- "ManagementTeam" = "Developer Experience"
- "Source" = "https://github.com/pagopa/dx/blob/main/infra/resources/dev"
} -> null
- identity {
- identity_ids = [] -> null
- principal_id = "14b8bbb1-959a-4909-a2dc-7efb7a4853ca" -> null
- tenant_id = "7788edaf-0346-4068-9d79-c868aed15b3d" -> null
- type = "SystemAssigned" -> null
}
}
# module.ai_foundry.azurerm_cognitive_deployment.this will be destroyed
# (because azurerm_cognitive_deployment.this is not in configuration)
- resource "azurerm_cognitive_deployment" "this" {
- cognitive_account_id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-ai-rg-01/providers/Microsoft.CognitiveServices/accounts/dx-d-itn-aif-01" -> null
- dynamic_throttling_enabled = false -> null
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-ai-rg-01/providers/Microsoft.CognitiveServices/accounts/dx-d-itn-aif-01/deployments/gpt-5-5" -> null
- name = "gpt-5-5" -> null
- version_upgrade_option = "OnceNewDefaultVersionAvailable" -> null
# (1 unchanged attribute hidden)
- model {
- format = "OpenAI" -> null
- name = "gpt-5.5" -> null
- version = "2026-04-24" -> null
}
- sku {
- capacity = 100 -> null
- name = "GlobalStandard" -> null
# (3 unchanged attributes hidden)
}
}
# module.ai_foundry.azurerm_private_dns_zone.foundry["cognitive_services"] will be destroyed
# (because azurerm_private_dns_zone.foundry is not in configuration)
- resource "azurerm_private_dns_zone" "foundry" {
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-network-rg-01/providers/Microsoft.Network/privateDnsZones/privatelink.cognitiveservices.azure.com" -> null
- max_number_of_record_sets = 25000 -> null
- max_number_of_virtual_network_links = 1000 -> null
- max_number_of_virtual_network_links_with_registration = 100 -> null
- name = "privatelink.cognitiveservices.azure.com" -> null
- number_of_record_sets = 2 -> null
- resource_group_name = "dx-d-itn-network-rg-01" -> null
- tags = {
- "BusinessUnit" = "DevEx"
- "CostCenter" = "TS000 - Tecnologia e Servizi"
- "CreatedBy" = "Terraform"
- "Environment" = "Dev"
- "ManagementTeam" = "Developer Experience"
- "Source" = "https://github.com/pagopa/dx/blob/main/infra/resources/dev"
} -> null
- soa_record {
- email = "azureprivatedns-host.microsoft.com" -> null
- expire_time = 2419200 -> null
- fqdn = "privatelink.cognitiveservices.azure.com." -> null
- host_name = "azureprivatedns.net" -> null
- minimum_ttl = 10 -> null
- refresh_time = 3600 -> null
- retry_time = 300 -> null
- serial_number = 1 -> null
- tags = {} -> null
- ttl = 3600 -> null
}
}
# module.ai_foundry.azurerm_private_dns_zone.foundry["openai"] will be destroyed
# (because azurerm_private_dns_zone.foundry is not in configuration)
- resource "azurerm_private_dns_zone" "foundry" {
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-network-rg-01/providers/Microsoft.Network/privateDnsZones/privatelink.openai.azure.com" -> null
- max_number_of_record_sets = 25000 -> null
- max_number_of_virtual_network_links = 1000 -> null
- max_number_of_virtual_network_links_with_registration = 100 -> null
- name = "privatelink.openai.azure.com" -> null
- number_of_record_sets = 2 -> null
- resource_group_name = "dx-d-itn-network-rg-01" -> null
- tags = {
- "BusinessUnit" = "DevEx"
- "CostCenter" = "TS000 - Tecnologia e Servizi"
- "CreatedBy" = "Terraform"
- "Environment" = "Dev"
- "ManagementTeam" = "Developer Experience"
- "Source" = "https://github.com/pagopa/dx/blob/main/infra/resources/dev"
} -> null
- soa_record {
- email = "azureprivatedns-host.microsoft.com" -> null
- expire_time = 2419200 -> null
- fqdn = "privatelink.openai.azure.com." -> null
- host_name = "azureprivatedns.net" -> null
- minimum_ttl = 10 -> null
- refresh_time = 3600 -> null
- retry_time = 300 -> null
- serial_number = 1 -> null
- tags = {} -> null
- ttl = 3600 -> null
}
}
# module.ai_foundry.azurerm_private_dns_zone.foundry["services_ai"] will be destroyed
# (because azurerm_private_dns_zone.foundry is not in configuration)
- resource "azurerm_private_dns_zone" "foundry" {
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-network-rg-01/providers/Microsoft.Network/privateDnsZones/privatelink.services.ai.azure.com" -> null
- max_number_of_record_sets = 25000 -> null
- max_number_of_virtual_network_links = 1000 -> null
- max_number_of_virtual_network_links_with_registration = 100 -> null
- name = "privatelink.services.ai.azure.com" -> null
- number_of_record_sets = 2 -> null
- resource_group_name = "dx-d-itn-network-rg-01" -> null
- tags = {
- "BusinessUnit" = "DevEx"
- "CostCenter" = "TS000 - Tecnologia e Servizi"
- "CreatedBy" = "Terraform"
- "Environment" = "Dev"
- "ManagementTeam" = "Developer Experience"
- "Source" = "https://github.com/pagopa/dx/blob/main/infra/resources/dev"
} -> null
- soa_record {
- email = "azureprivatedns-host.microsoft.com" -> null
- expire_time = 2419200 -> null
- fqdn = "privatelink.services.ai.azure.com." -> null
- host_name = "azureprivatedns.net" -> null
- minimum_ttl = 10 -> null
- refresh_time = 3600 -> null
- retry_time = 300 -> null
- serial_number = 1 -> null
- tags = {} -> null
- ttl = 3600 -> null
}
}
# module.ai_foundry.azurerm_private_dns_zone_virtual_network_link.foundry["cognitive_services"] will be destroyed
# (because azurerm_private_dns_zone_virtual_network_link.foundry is not in configuration)
- resource "azurerm_private_dns_zone_virtual_network_link" "foundry" {
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-network-rg-01/providers/Microsoft.Network/privateDnsZones/privatelink.cognitiveservices.azure.com/virtualNetworkLinks/dx-d-itn-common-vnet-01" -> null
- name = "dx-d-itn-common-vnet-01" -> null
- private_dns_zone_name = "privatelink.cognitiveservices.azure.com" -> null
- registration_enabled = false -> null
- resolution_policy = "Default" -> null
- resource_group_name = "dx-d-itn-network-rg-01" -> null
- tags = {
- "BusinessUnit" = "DevEx"
- "CostCenter" = "TS000 - Tecnologia e Servizi"
- "CreatedBy" = "Terraform"
- "Environment" = "Dev"
- "ManagementTeam" = "Developer Experience"
- "Source" = "https://github.com/pagopa/dx/blob/main/infra/resources/dev"
} -> null
- virtual_network_id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-network-rg-01/providers/Microsoft.Network/virtualNetworks/dx-d-itn-common-vnet-01" -> null
}
# module.ai_foundry.azurerm_private_dns_zone_virtual_network_link.foundry["openai"] will be destroyed
# (because azurerm_private_dns_zone_virtual_network_link.foundry is not in configuration)
- resource "azurerm_private_dns_zone_virtual_network_link" "foundry" {
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-network-rg-01/providers/Microsoft.Network/privateDnsZones/privatelink.openai.azure.com/virtualNetworkLinks/dx-d-itn-common-vnet-01" -> null
- name = "dx-d-itn-common-vnet-01" -> null
- private_dns_zone_name = "privatelink.openai.azure.com" -> null
- registration_enabled = false -> null
- resolution_policy = "Default" -> null
- resource_group_name = "dx-d-itn-network-rg-01" -> null
- tags = {
- "BusinessUnit" = "DevEx"
- "CostCenter" = "TS000 - Tecnologia e Servizi"
- "CreatedBy" = "Terraform"
- "Environment" = "Dev"
- "ManagementTeam" = "Developer Experience"
- "Source" = "https://github.com/pagopa/dx/blob/main/infra/resources/dev"
} -> null
- virtual_network_id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-network-rg-01/providers/Microsoft.Network/virtualNetworks/dx-d-itn-common-vnet-01" -> null
}
# module.ai_foundry.azurerm_private_dns_zone_virtual_network_link.foundry["services_ai"] will be destroyed
# (because azurerm_private_dns_zone_virtual_network_link.foundry is not in configuration)
- resource "azurerm_private_dns_zone_virtual_network_link" "foundry" {
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-network-rg-01/providers/Microsoft.Network/privateDnsZones/privatelink.services.ai.azure.com/virtualNetworkLinks/dx-d-itn-common-vnet-01" -> null
- name = "dx-d-itn-common-vnet-01" -> null
- private_dns_zone_name = "privatelink.services.ai.azure.com" -> null
- registration_enabled = false -> null
- resolution_policy = "Default" -> null
- resource_group_name = "dx-d-itn-network-rg-01" -> null
- tags = {
- "BusinessUnit" = "DevEx"
- "CostCenter" = "TS000 - Tecnologia e Servizi"
- "CreatedBy" = "Terraform"
- "Environment" = "Dev"
- "ManagementTeam" = "Developer Experience"
- "Source" = "https://github.com/pagopa/dx/blob/main/infra/resources/dev"
} -> null
- virtual_network_id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-network-rg-01/providers/Microsoft.Network/virtualNetworks/dx-d-itn-common-vnet-01" -> null
}
# module.ai_foundry.azurerm_private_endpoint.foundry will be destroyed
# (because azurerm_private_endpoint.foundry is not in configuration)
- resource "azurerm_private_endpoint" "foundry" {
- custom_dns_configs = [] -> null
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-ai-rg-01/providers/Microsoft.Network/privateEndpoints/dx-d-itn-foundry-pep-01" -> null
- location = "italynorth" -> null
- name = "dx-d-itn-foundry-pep-01" -> null
- network_interface = [
- {
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-ai-rg-01/providers/Microsoft.Network/networkInterfaces/dx-d-itn-foundry-pep-01.nic.569264c2-1f79-4625-85f7-80158abb4ba2"
- name = "dx-d-itn-foundry-pep-01.nic.569264c2-1f79-4625-85f7-80158abb4ba2"
},
] -> null
- private_dns_zone_configs = [
- {
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-ai-rg-01/providers/Microsoft.Network/privateEndpoints/dx-d-itn-foundry-pep-01/privateDnsZoneGroups/private-dns-zone-group/privateDnsZoneConfigs/privatelink.cognitiveservices.azure.com"
- name = "privatelink.cognitiveservices.azure.com"
- private_dns_zone_id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-network-rg-01/providers/Microsoft.Network/privateDnsZones/privatelink.cognitiveservices.azure.com"
- record_sets = [
- {
- fqdn = "dx-d-itn-aif-01.privatelink.cognitiveservices.azure.com"
- ip_addresses = [
- "10.51.0.10",
]
- name = "dx-d-itn-aif-01"
- ttl = 10
- type = "A"
},
]
},
- {
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-ai-rg-01/providers/Microsoft.Network/privateEndpoints/dx-d-itn-foundry-pep-01/privateDnsZoneGroups/private-dns-zone-group/privateDnsZoneConfigs/privatelink.openai.azure.com"
- name = "privatelink.openai.azure.com"
- private_dns_zone_id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-network-rg-01/providers/Microsoft.Network/privateDnsZones/privatelink.openai.azure.com"
- record_sets = [
- {
- fqdn = "dx-d-itn-aif-01.privatelink.openai.azure.com"
- ip_addresses = [
- "10.51.0.11",
]
- name = "dx-d-itn-aif-01"
- ttl = 10
- type = "A"
},
]
},
- {
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-ai-rg-01/providers/Microsoft.Network/privateEndpoints/dx-d-itn-foundry-pep-01/privateDnsZoneGroups/private-dns-zone-group/privateDnsZoneConfigs/privatelink.services.ai.azure.com"
- name = "privatelink.services.ai.azure.com"
- private_dns_zone_id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-network-rg-01/providers/Microsoft.Network/privateDnsZones/privatelink.services.ai.azure.com"
- record_sets = [
- {
- fqdn = "dx-d-itn-aif-01.privatelink.services.ai.azure.com"
- ip_addresses = [
- "10.51.0.12",
]
- name = "dx-d-itn-aif-01"
- ttl = 10
- type = "A"
},
]
},
] -> null
- resource_group_name = "dx-d-itn-ai-rg-01" -> null
- subnet_id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-network-rg-01/providers/Microsoft.Network/virtualNetworks/dx-d-itn-common-vnet-01/subnets/dx-d-itn-pep-snet-01" -> null
- tags = {
- "BusinessUnit" = "DevEx"
- "CostCenter" = "TS000 - Tecnologia e Servizi"
- "CreatedBy" = "Terraform"
- "Environment" = "Dev"
- "ManagementTeam" = "Developer Experience"
- "Source" = "https://github.com/pagopa/dx/blob/main/infra/resources/dev"
} -> null
# (1 unchanged attribute hidden)
- private_dns_zone_group {
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-ai-rg-01/providers/Microsoft.Network/privateEndpoints/dx-d-itn-foundry-pep-01/privateDnsZoneGroups/private-dns-zone-group" -> null
- name = "private-dns-zone-group" -> null
- private_dns_zone_ids = [
- "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-network-rg-01/providers/Microsoft.Network/privateDnsZones/privatelink.cognitiveservices.azure.com",
- "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-network-rg-01/providers/Microsoft.Network/privateDnsZones/privatelink.openai.azure.com",
- "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-network-rg-01/providers/Microsoft.Network/privateDnsZones/privatelink.services.ai.azure.com",
] -> null
}
- private_service_connection {
- is_manual_connection = false -> null
- name = "dx-d-itn-foundry-pep-01" -> null
- private_connection_resource_id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-ai-rg-01/providers/Microsoft.CognitiveServices/accounts/dx-d-itn-aif-01" -> null
- private_ip_address = "10.51.0.10" -> null
- subresource_names = [
- "account",
] -> null
# (2 unchanged attributes hidden)
}
}
# module.ai_gateway.azurerm_api_management_api.foundry will be destroyed
# (because azurerm_api_management_api.foundry is not in configuration)
- resource "azurerm_api_management_api" "foundry" {
- api_management_name = "dx-d-itn-ai-apim-01" -> null
- api_type = "http" -> null
- display_name = "AI Foundry" -> null
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-ai-rg-01/providers/Microsoft.ApiManagement/service/dx-d-itn-ai-apim-01/apis/ai-foundry;rev=1" -> null
- is_current = true -> null
- is_online = false -> null
- name = "ai-foundry" -> null
- path = "ai" -> null
- protocols = [
- "https",
] -> null
- resource_group_name = "dx-d-itn-ai-rg-01" -> null
- revision = "1" -> null
- subscription_required = false -> null
- version = "v1" -> null
- version_set_id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-ai-rg-01/providers/Microsoft.ApiManagement/service/dx-d-itn-ai-apim-01/apiVersionSets/ai-foundry" -> null
# (5 unchanged attributes hidden)
- subscription_key_parameter_names {
- header = "Ocp-Apim-Subscription-Key" -> null
- query = "subscription-key" -> null
}
}
# module.ai_gateway.azurerm_api_management_api_operation.responses will be destroyed
# (because azurerm_api_management_api_operation.responses is not in configuration)
- resource "azurerm_api_management_api_operation" "responses" {
- api_management_name = "dx-d-itn-ai-apim-01" -> null
- api_name = "ai-foundry" -> null
- display_name = "Create response" -> null
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-ai-rg-01/providers/Microsoft.ApiManagement/service/dx-d-itn-ai-apim-01/apis/ai-foundry/operations/create-response" -> null
- method = "POST" -> null
- operation_id = "create-response" -> null
- resource_group_name = "dx-d-itn-ai-rg-01" -> null
- url_template = "/responses" -> null
# (1 unchanged attribute hidden)
- request {
# (1 unchanged attribute hidden)
}
}
# module.ai_gateway.azurerm_api_management_api_operation_tag.responses will be destroyed
# (because azurerm_api_management_api_operation_tag.responses is not in configuration)
- resource "azurerm_api_management_api_operation_tag" "responses" {
- api_operation_id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-ai-rg-01/providers/Microsoft.ApiManagement/service/dx-d-itn-ai-apim-01/apis/ai-foundry/operations/create-response" -> null
- display_name = "Terraform Permission Check" -> null
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-ai-rg-01/providers/Microsoft.ApiManagement/service/dx-d-itn-ai-apim-01/apis/ai-foundry/operations/create-response/tags/terraform-permission-check" -> null
- name = "terraform-permission-check" -> null
}
# module.ai_gateway.azurerm_api_management_api_policy.foundry will be destroyed
# (because azurerm_api_management_api_policy.foundry is not in configuration)
- resource "azurerm_api_management_api_policy" "foundry" {
- api_management_name = "dx-d-itn-ai-apim-01" -> null
- api_name = "ai-foundry" -> null
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-ai-rg-01/providers/Microsoft.ApiManagement/service/dx-d-itn-ai-apim-01/apis/ai-foundry" -> null
- resource_group_name = "dx-d-itn-ai-rg-01" -> null
- xml_content = <<-EOT
<policies>
<inbound>
<base />
<set-backend-service backend-id="foundry" />
<rewrite-uri template="/openai/v1/responses" copy-unmatched-params="true" />
<authentication-managed-identity resource="https://ai.azure.com" />
<llm-emit-token-metric>
<dimension name="Operation ID" />
</llm-emit-token-metric>
<llm-token-limit remaining-quota-tokens-header-name="remaining-tokens" remaining-tokens-header-name="remaining-tokens" tokens-per-minute="100000" token-quota="10000000" token-quota-period="Daily" counter-key="@(context.Subscription.Id)" estimate-prompt-tokens="false" tokens-consumed-header-name="consumed-tokens" />
<!--TODO: add cache-->
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
EOT -> null
# (1 unchanged attribute hidden)
}
# module.ai_gateway.azurerm_api_management_api_version_set.foundry will be destroyed
# (because azurerm_api_management_api_version_set.foundry is not in configuration)
- resource "azurerm_api_management_api_version_set" "foundry" {
- api_management_name = "dx-d-itn-ai-apim-01" -> null
- display_name = "AI Foundry" -> null
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-ai-rg-01/providers/Microsoft.ApiManagement/service/dx-d-itn-ai-apim-01/apiVersionSets/ai-foundry" -> null
- name = "ai-foundry" -> null
- resource_group_name = "dx-d-itn-ai-rg-01" -> null
- versioning_scheme = "Segment" -> null
# (3 unchanged attributes hidden)
}
# module.ai_gateway.azurerm_api_management_backend.foundry will be destroyed
# (because azurerm_api_management_backend.foundry is not in configuration)
- resource "azurerm_api_management_backend" "foundry" {
- api_management_name = "dx-d-itn-ai-apim-01" -> null
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-ai-rg-01/providers/Microsoft.ApiManagement/service/dx-d-itn-ai-apim-01/backends/foundry" -> null
- name = "foundry" -> null
- protocol = "http" -> null
- resource_group_name = "dx-d-itn-ai-rg-01" -> null
- url = "https://dx-d-itn-aif-01.services.ai.azure.com/api/projects/dx-d-itn-terraformci-proj-01" -> null
# (3 unchanged attributes hidden)
- circuit_breaker_rule {
- accept_retry_after_enabled = false -> null
- name = "default" -> null
- trip_duration = "PT30S" -> null
- failure_condition {
- count = 5 -> null
- error_reasons = [] -> null
- interval_duration = "PT1M" -> null
- percentage = 0 -> null
- status_code_range {
- max = 599 -> null
- min = 500 -> null
}
}
}
}
# module.ai_gateway.azurerm_role_assignment.apim_foundry will be destroyed
# (because azurerm_role_assignment.apim_foundry is not in configuration)
- resource "azurerm_role_assignment" "apim_foundry" {
- description = "Allow the AI gateway (APIM) managed identity to invoke Foundry project models via Entra ID" -> null
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-ai-rg-01/providers/Microsoft.CognitiveServices/accounts/dx-d-itn-aif-01/projects/dx-d-itn-terraformci-proj-01/providers/Microsoft.Authorization/roleAssignments/0eecae28-9ac1-a5d1-fb78-619be93b8403" -> null
- name = "0eecae28-9ac1-a5d1-fb78-619be93b8403" -> null
- principal_id = "f8d3d56e-88bd-417e-a127-7ec19e3d62d2" -> null
- principal_type = "ServicePrincipal" -> null
- role_definition_id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/providers/Microsoft.Authorization/roleDefinitions/53ca6127-db72-4b80-b1b0-d745d6d5456d" -> null
- role_definition_name = "Foundry User" -> null
- scope = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-ai-rg-01/providers/Microsoft.CognitiveServices/accounts/dx-d-itn-aif-01/projects/dx-d-itn-terraformci-proj-01" -> null
# (3 unchanged attributes hidden)
}
# module.ai_gateway.azurerm_subnet.apim will be destroyed
# (because azurerm_subnet.apim is not in configuration)
- resource "azurerm_subnet" "apim" {
- address_prefixes = [
- "10.51.5.32/27",
] -> null
- default_outbound_access_enabled = true -> null
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-network-rg-01/providers/Microsoft.Network/virtualNetworks/dx-d-itn-common-vnet-01/subnets/dx-d-itn-ai-apim-snet-01" -> null
- name = "dx-d-itn-ai-apim-snet-01" -> null
- private_endpoint_network_policies = "Disabled" -> null
- private_link_service_network_policies_enabled = true -> null
- resource_group_name = "dx-d-itn-network-rg-01" -> null
- service_endpoint_policy_ids = [] -> null
- service_endpoints = [] -> null
- virtual_network_name = "dx-d-itn-common-vnet-01" -> null
# (1 unchanged attribute hidden)
}
# module.ai_gateway.dx_available_subnet_cidr.apim will be destroyed
# (because dx_available_subnet_cidr.apim is not in configuration)
- resource "dx_available_subnet_cidr" "apim" {
- cidr_block = "10.51.5.32/27" -> null
- id = "_subscriptions_35e6e3b2-4388-470e-a1b9-ad3bc34326d1_resourceGroups_dx-d-itn-network-rg-01_providers_Microsoft.Network_virtualNetworks_dx-d-itn-common-vnet-01_27_10.51.5.32_27" -> null
- prefix_length = 27 -> null
- virtual_network_id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-network-rg-01/providers/Microsoft.Network/virtualNetworks/dx-d-itn-common-vnet-01" -> null
}
# module.mcp_server.aws_s3_bucket_server_side_encryption_configuration.mcp_knowledge_base will be updated in-place
~ resource "aws_s3_bucket_server_side_encryption_configuration" "mcp_knowledge_base" {
id = "dx-d-euc1-docs-kb-s3-01"
# (3 unchanged attributes hidden)
- rule {
- blocked_encryption_types = [
- "SSE-C",
] -> null
- bucket_key_enabled = false -> null
- apply_server_side_encryption_by_default {
- sse_algorithm = "AES256" -> null
# (1 unchanged attribute hidden)
}
}
+ rule {
+ blocked_encryption_types = []
+ apply_server_side_encryption_by_default {
+ sse_algorithm = "AES256"
# (1 unchanged attribute hidden)
}
}
}
# module.ai_gateway.module.apim.azurerm_api_management.this will be destroyed
# (because azurerm_api_management.this is not in configuration)
- resource "azurerm_api_management" "this" {
- client_certificate_enabled = false -> null
- developer_portal_url = "https://dx-d-itn-ai-apim-01.developer.azure-api.net" -> null
- gateway_disabled = false -> null
- gateway_regional_url = "https://dx-d-itn-ai-apim-01-italynorth-01.regional.azure-api.net" -> null
- gateway_url = "https://dx-d-itn-ai-apim-01.azure-api.net" -> null
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-ai-rg-01/providers/Microsoft.ApiManagement/service/dx-d-itn-ai-apim-01" -> null
- location = "italynorth" -> null
- management_api_url = "https://dx-d-itn-ai-apim-01.management.azure-api.net" -> null
- min_api_version = "2021-08-01" -> null
- name = "dx-d-itn-ai-apim-01" -> null
- notification_sender_email = "apimgmt-noreply@mail.windowsazure.com" -> null
- private_ip_addresses = [
- "10.51.5.36",
] -> null
- public_ip_addresses = [
- "72.146.240.161",
] -> null
- public_network_access_enabled = true -> null
- publisher_email = "team-devex@pagopa.it" -> null
- publisher_name = "PagoPA S.p.A." -> null
- resource_group_name = "dx-d-itn-ai-rg-01" -> null
- scm_url = "https://dx-d-itn-ai-apim-01.scm.azure-api.net" -> null
- sku_name = "Developer_1" -> null
- tags = {
- "BusinessUnit" = "DevEx"
- "CostCenter" = "TS000 - Tecnologia e Servizi"
- "CreatedBy" = "Terraform"
- "Environment" = "Dev"
- "ManagementTeam" = "Developer Experience"
- "ModuleName" = "azure_api_management"
- "ModuleSource" = "DX"
- "ModuleVersion" = "2.2.3"
- "Source" = "https://github.com/pagopa/dx/blob/main/infra/resources/dev"
} -> null
- virtual_network_type = "Internal" -> null
- zones = [] -> null
# (2 unchanged attributes hidden)
- delegation {
- subscriptions_enabled = false -> null
- user_registration_enabled = false -> null
# (2 unchanged attributes hidden)
}
- hostname_configuration {
- proxy {
- certificate_source = "BuiltIn" -> null
- default_ssl_binding = true -> null
- host_name = "dx-d-itn-ai-apim-01.azure-api.net" -> null
- negotiate_client_certificate = false -> null
# (9 unchanged attributes hidden)
}
}
- identity {
- identity_ids = [] -> null
- principal_id = "f8d3d56e-88bd-417e-a127-7ec19e3d62d2" -> null
- tenant_id = "7788edaf-0346-4068-9d79-c868aed15b3d" -> null
- type = "SystemAssigned" -> null
}
- protocols {
- enable_http2 = false -> null
- http2_enabled = false -> null
}
- security {
- backend_ssl30_enabled = false -> null
- backend_tls10_enabled = false -> null
- backend_tls11_enabled = false -> null
- enable_backend_ssl30 = false -> null
- enable_backend_tls10 = false -> null
- enable_backend_tls11 = false -> null
- enable_frontend_ssl30 = false -> null
- enable_frontend_tls10 = false -> null
- enable_frontend_tls11 = false -> null
- frontend_ssl30_enabled = false -> null
- frontend_tls10_enabled = false -> null
- frontend_tls11_enabled = false -> null
- tls_ecdhe_ecdsa_with_aes128_cbc_sha_ciphers_enabled = false -> null
- tls_ecdhe_ecdsa_with_aes256_cbc_sha_ciphers_enabled = false -> null
- tls_ecdhe_rsa_with_aes128_cbc_sha_ciphers_enabled = false -> null
- tls_ecdhe_rsa_with_aes256_cbc_sha_ciphers_enabled = false -> null
- tls_rsa_with_aes128_cbc_sha256_ciphers_enabled = false -> null
- tls_rsa_with_aes128_cbc_sha_ciphers_enabled = false -> null
- tls_rsa_with_aes128_gcm_sha256_ciphers_enabled = false -> null
- tls_rsa_with_aes256_cbc_sha256_ciphers_enabled = false -> null
- tls_rsa_with_aes256_cbc_sha_ciphers_enabled = false -> null
- tls_rsa_with_aes256_gcm_sha384_ciphers_enabled = false -> null
- triple_des_ciphers_enabled = false -> null
}
- sign_in {
- enabled = false -> null
}
- sign_up {
- enabled = false -> null
- terms_of_service {
- consent_required = false -> null
- enabled = false -> null
# (1 unchanged attribute hidden)
}
}
- tenant_access {
- enabled = false -> null
- primary_key = (sensitive value) -> null
- secondary_key = (sensitive value) -> null
- tenant_id = "/tenant/access" -> null
}
- virtual_network_configuration {
- subnet_id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-network-rg-01/providers/Microsoft.Network/virtualNetworks/dx-d-itn-common-vnet-01/subnets/dx-d-itn-ai-apim-snet-01" -> null
}
}
# module.ai_gateway.module.apim.azurerm_api_management_diagnostic.applicationinsights[0] will be destroyed
# (because azurerm_api_management_diagnostic.applicationinsights is not in configuration)
- resource "azurerm_api_management_diagnostic" "applicationinsights" {
- always_log_errors = true -> null
- api_management_logger_id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-ai-rg-01/providers/Microsoft.ApiManagement/service/dx-d-itn-ai-apim-01/loggers/dx-d-itn-ai-apim-01-logger" -> null
- api_management_name = "dx-d-itn-ai-apim-01" -> null
- http_correlation_protocol = "W3C" -> null
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-ai-rg-01/providers/Microsoft.ApiManagement/service/dx-d-itn-ai-apim-01/diagnostics/applicationinsights" -> null
- identifier = "applicationinsights" -> null
- log_client_ip = true -> null
- resource_group_name = "dx-d-itn-ai-rg-01" -> null
- sampling_percentage = 100 -> null
- verbosity = "information" -> null
# (1 unchanged attribute hidden)
- backend_request {
- body_bytes = 0 -> null
- headers_to_log = [] -> null
- data_masking {
- query_params {
- mode = "Hide" -> null
- value = "*" -> null
}
}
}
- frontend_request {
- body_bytes = 0 -> null
- headers_to_log = [] -> null
- data_masking {
- query_params {
- mode = "Hide" -> null
- value = "*" -> null
}
}
}
}
# module.ai_gateway.module.apim.azurerm_api_management_logger.this[0] will be destroyed
# (because azurerm_api_management_logger.this is not in configuration)
- resource "azurerm_api_management_logger" "this" {
- api_management_name = "dx-d-itn-ai-apim-01" -> null
- buffered = true -> null
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-ai-rg-01/providers/Microsoft.ApiManagement/service/dx-d-itn-ai-apim-01/loggers/dx-d-itn-ai-apim-01-logger" -> null
- name = "dx-d-itn-ai-apim-01-logger" -> null
- resource_group_name = "dx-d-itn-ai-rg-01" -> null
- resource_id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-common-rg-01/providers/Microsoft.Insights/components/dx-d-itn-common-appi-01" -> null
# (1 unchanged attribute hidden)
- application_insights {
- connection_string = (sensitive value) -> null
# (1 unchanged attribute hidden)
}
}
# module.ai_gateway.module.apim.azurerm_network_security_group.nsg_apim will be destroyed
# (because azurerm_network_security_group.nsg_apim is not in configuration)
- resource "azurerm_network_security_group" "nsg_apim" {
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-network-rg-01/providers/Microsoft.Network/networkSecurityGroups/dx-d-itn-ai-apim-nsg-01" -> null
- location = "italynorth" -> null
- name = "dx-d-itn-ai-apim-nsg-01" -> null
- resource_group_name = "dx-d-itn-network-rg-01" -> null
- security_rule = [
- {
- access = "Allow"
- description = "Access to Azure Key Vault for core service functionality"
- destination_address_prefix = "AzureKeyVault"
- destination_address_prefixes = []
- destination_application_security_group_ids = []
- destination_port_range = "443"
- destination_port_ranges = []
- direction = "Outbound"
- name = "azure-keyvault"
- priority = 202
- protocol = "Tcp"
- source_address_prefix = "VirtualNetwork"
- source_address_prefixes = []
- source_application_security_group_ids = []
- source_port_range = "*"
- source_port_ranges = []
},
- {
- access = "Allow"
- description = "Access to Azure SQL endpoints for core service functionality"
- destination_address_prefix = "SQL"
- destination_address_prefixes = []
- destination_application_security_group_ids = []
- destination_port_range = "1433"
- destination_port_ranges = []
- direction = "Outbound"
- name = "sql"
- priority = 201
- protocol = "Tcp"
- source_address_prefix = "VirtualNetwork"
- source_address_prefixes = []
- source_application_security_group_ids = []
- source_port_range = "*"
- source_port_ranges = []
},
- {
- access = "Allow"
- description = "Azure Infrastructure Load Balancer"
- destination_address_prefix = "VirtualNetwork"
- destination_address_prefixes = []
- destination_application_security_group_ids = []
- destination_port_range = "6390"
- destination_port_ranges = []
- direction = "Inbound"
- name = "azure-load-balancer"
- priority = 201
- protocol = "Tcp"
- source_address_prefix = "AzureLoadBalancer"
- source_address_prefixes = []
- source_application_security_group_ids = []
- source_port_range = "*"
- source_port_ranges = []
},
- {
- access = "Allow"
- description = "Dependency on Azure Storage for core service functionality"
- destination_address_prefix = "Storage"
- destination_address_prefixes = []
- destination_application_security_group_ids = []
- destination_port_range = "443"
- destination_port_ranges = []
- direction = "Outbound"
- name = "storage"
- priority = 200
- protocol = "Tcp"
- source_address_prefix = "VirtualNetwork"
- source_address_prefixes = []
- source_application_security_group_ids = []
- source_port_range = "*"
- source_port_ranges = []
},
- {
- access = "Allow"
- description = "Management endpoint for Azure portal and PowerShell"
- destination_address_prefix = "VirtualNetwork"
- destination_address_prefixes = []
- destination_application_security_group_ids = []
- destination_port_range = "3443"
- destination_port_ranges = []
- direction = "Inbound"
- name = "apim-management"
- priority = 200
- protocol = "Tcp"
- source_address_prefix = "ApiManagement"
- source_address_prefixes = []
- source_application_security_group_ids = []
- source_port_range = "*"
- source_port_ranges = []
},
- {
- access = "Allow"
- description = "Publish Diagnostics Logs and Metrics, Resource Health, and Application Insights"
- destination_address_prefix = "AzureMonitor"
- destination_address_prefixes = []
- destination_application_security_group_ids = []
- destination_port_ranges = [
- "1886",
- "443",
]
- direction = "Outbound"
- name = "azure-monitor"
- priority = 203
- protocol = "Tcp"
- source_address_prefix = "VirtualNetwork"
- source_address_prefixes = []
- source_application_security_group_ids = []
- source_port_range = "*"
- source_port_ranges = []
# (1 unchanged attribute hidden)
},
] -> null
- tags = {
- "BusinessUnit" = "DevEx"
- "CostCenter" = "TS000 - Tecnologia e Servizi"
- "CreatedBy" = "Terraform"
- "Environment" = "Dev"
- "ManagementTeam" = "Developer Experience"
- "ModuleName" = "azure_api_management"
- "ModuleSource" = "DX"
- "ModuleVersion" = "2.2.3"
- "Source" = "https://github.com/pagopa/dx/blob/main/infra/resources/dev"
} -> null
}
# module.ai_gateway.module.apim.azurerm_private_dns_a_record.apim_azure_api_net[0] will be destroyed
# (because azurerm_private_dns_a_record.apim_azure_api_net is not in configuration)
- resource "azurerm_private_dns_a_record" "apim_azure_api_net" {
- fqdn = "dx-d-itn-ai-apim-01.azure-api.net." -> null
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-network-rg-01/providers/Microsoft.Network/privateDnsZones/azure-api.net/A/dx-d-itn-ai-apim-01" -> null
- name = "dx-d-itn-ai-apim-01" -> null
- records = [
- "10.51.5.36",
] -> null
- resource_group_name = "dx-d-itn-network-rg-01" -> null
- tags = {
- "BusinessUnit" = "DevEx"
- "CostCenter" = "TS000 - Tecnologia e Servizi"
- "CreatedBy" = "Terraform"
- "Environment" = "Dev"
- "ManagementTeam" = "Developer Experience"
- "ModuleName" = "azure_api_management"
- "ModuleSource" = "DX"
- "ModuleVersion" = "2.2.3"
- "Source" = "https://github.com/pagopa/dx/blob/main/infra/resources/dev"
} -> null
- ttl = 3600 -> null
- zone_name = "azure-api.net" -> null
}
# module.ai_gateway.module.apim.azurerm_private_dns_a_record.apim_management_azure_api_net[0] will be destroyed
# (because azurerm_private_dns_a_record.apim_management_azure_api_net is not in configuration)
- resource "azurerm_private_dns_a_record" "apim_management_azure_api_net" {
- fqdn = "dx-d-itn-ai-apim-01.management.azure-api.net." -> null
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-network-rg-01/providers/Microsoft.Network/privateDnsZones/management.azure-api.net/A/dx-d-itn-ai-apim-01" -> null
- name = "dx-d-itn-ai-apim-01" -> null
- records = [
- "10.51.5.36",
] -> null
- resource_group_name = "dx-d-itn-network-rg-01" -> null
- tags = {
- "BusinessUnit" = "DevEx"
- "CostCenter" = "TS000 - Tecnologia e Servizi"
- "CreatedBy" = "Terraform"
- "Environment" = "Dev"
- "ManagementTeam" = "Developer Experience"
- "ModuleName" = "azure_api_management"
- "ModuleSource" = "DX"
- "ModuleVersion" = "2.2.3"
- "Source" = "https://github.com/pagopa/dx/blob/main/infra/resources/dev"
} -> null
- ttl = 3600 -> null
- zone_name = "management.azure-api.net" -> null
}
# module.ai_gateway.module.apim.azurerm_private_dns_a_record.apim_scm_azure_api_net[0] will be destroyed
# (because azurerm_private_dns_a_record.apim_scm_azure_api_net is not in configuration)
- resource "azurerm_private_dns_a_record" "apim_scm_azure_api_net" {
- fqdn = "dx-d-itn-ai-apim-01.scm.azure-api.net." -> null
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-network-rg-01/providers/Microsoft.Network/privateDnsZones/scm.azure-api.net/A/dx-d-itn-ai-apim-01" -> null
- name = "dx-d-itn-ai-apim-01" -> null
- records = [
- "10.51.5.36",
] -> null
- resource_group_name = "dx-d-itn-network-rg-01" -> null
- tags = {
- "BusinessUnit" = "DevEx"
- "CostCenter" = "TS000 - Tecnologia e Servizi"
- "CreatedBy" = "Terraform"
- "Environment" = "Dev"
- "ManagementTeam" = "Developer Experience"
- "ModuleName" = "azure_api_management"
- "ModuleSource" = "DX"
- "ModuleVersion" = "2.2.3"
- "Source" = "https://github.com/pagopa/dx/blob/main/infra/resources/dev"
} -> null
- ttl = 3600 -> null
- zone_name = "scm.azure-api.net" -> null
}
# module.ai_gateway.module.apim.azurerm_subnet_network_security_group_association.snet_nsg will be destroyed
# (because azurerm_subnet_network_security_group_association.snet_nsg is not in configuration)
- resource "azurerm_subnet_network_security_group_association" "snet_nsg" {
- id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-network-rg-01/providers/Microsoft.Network/virtualNetworks/dx-d-itn-common-vnet-01/subnets/dx-d-itn-ai-apim-snet-01" -> null
- network_security_group_id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-network-rg-01/providers/Microsoft.Network/networkSecurityGroups/dx-d-itn-ai-apim-nsg-01" -> null
- subnet_id = "/subscriptions/35e6e3b2-4388-470e-a1b9-ad3bc34326d1/resourceGroups/dx-d-itn-network-rg-01/providers/Microsoft.Network/virtualNetworks/dx-d-itn-common-vnet-01/subnets/dx-d-itn-ai-apim-snet-01" -> null
}
Plan: 0 to add, 1 to change, 27 to destroy.
Warning: Reference to undefined provider
on aws.tf line 12, in module "mcp_server":
12: aws.us_east_1 = aws.us-east-1
There is no explicit declaration for local provider name "aws.us_east_1" in
module.mcp_server, so Terraform is assuming you mean to pass a configuration
for "hashicorp/aws".
If you also control the child module, add a required_providers entry named
"aws.us_east_1" with the source address "hashicorp/aws". |
|
Superseded by the following reviewable draft PR stack:
Each PR is based on the previous one; only the final PR activates dev/prod deployment behavior. |
Why
PR #1897 introduced an nx-based
terraform planfor PR review (validate-v2.yaml,@pagopa/dx-tasks'sterraformPlan,@pagopa/nx-terraform-plugin'splanexecutor), replacinginfra_plan.yamlfor the dx repo's own code review. This PR does the equivalent for apply:infra/resources/{dev,prod}now go through the same nx/dx-tasks toolchain instead of the legacy ad-hocinfra_apply.yamlpipeline.Rather than a separate ad-hoc apply pipeline, this integrates Terraform apply into the existing
nx releaseflow (release-v2.yaml), mirroring howinfra/modules/*(publishable Terraform module libraries) already participate innx releasevia anx-release-publishtarget andmodule.json-based versioning.infra_apply.yamland its existing callers (_release-terraform-apply-{dev,prod}-resources.yaml) are left untouched: other teams/repositories still rely on it during the transition. Once this alternative is validated in production for the dx repo, a follow-up rollout can migrate external consumers too.Design notes
infra_apply.yamlalready handles this today.infra_apply.yaml's current behavior.infra/resources/*, the git tag/GitHub Release created by the (unmodified)releasejob's tag-sync step means "approved for deployment via a merged version plan", not "successfully applied" — the actual apply happens later ininfra-apply, gated behind approval. This is an accepted, documented tradeoff rather than a bug.Validation
pnpm nx affected --targets=build,test,lint,format:check,typecheck --uncommittedpasses across all 25 affected projects, including full test suites for@pagopa/dx-tasks,@pagopa/nx-terraform-plugin, andnx-release.Version plans included for
@pagopa/dx-tasks,@pagopa/nx-terraform-plugin, andnx-release.