diff --git a/src/domains/observability/05_app_forwarder.tf b/src/domains/observability/05_app_forwarder.tf new file mode 100644 index 0000000000..404d41777b --- /dev/null +++ b/src/domains/observability/05_app_forwarder.tf @@ -0,0 +1,197 @@ +locals { + + app_forwarder_app_settings = { + # Monitoring + # APPINSIGHTS_INSTRUMENTATIONKEY = azurerm_application_insights.application_insights.instrumentation_key + # APPLICATIONINSIGHTS_CONNECTION_STRING = format("InstrumentationKey=%s", azurerm_application_insights.application_insights.instrumentation_key) + APPINSIGHTS_PROFILERFEATURE_VERSION = "1.0.0" + APPINSIGHTS_SNAPSHOTFEATURE_VERSION = "1.0.0" + APPLICATIONINSIGHTS_CONFIGURATION_CONTENT = "" + ApplicationInsightsAgent_EXTENSION_VERSION = "~3" + DiagnosticServices_EXTENSION_VERSION = "~3" + InstrumentationEngine_EXTENSION_VERSION = "disabled" + SnapshotDebugger_EXTENSION_VERSION = "disabled" + XDT_MicrosoftApplicationInsights_BaseExtensions = "disabled" + XDT_MicrosoftApplicationInsights_Mode = "recommended" + XDT_MicrosoftApplicationInsights_PreemptSdk = "disabled" + WEBSITE_HEALTHCHECK_MAXPINGFAILURES = 10 + TIMEOUT_DELAY = 300 + # Integration with private DNS (see more: https://docs.microsoft.com/en-us/answers/questions/85359/azure-app-service-unable-to-resolve-hostname-of-vi.html) + WEBSITE_ADD_SITENAME_BINDINGS_IN_APPHOST_CONFIG = "1" + WEBSITE_RUN_FROM_PACKAGE = "1" + WEBSITE_VNET_ROUTE_ALL = "1" + WEBSITE_DNS_SERVER = "168.63.129.16" + WEBSITE_ENABLE_SYNC_UPDATE_SITE = true + # Spring Environment + DEFAULT_LOGGING_LEVEL = "INFO" + APP_LOGGING_LEVEL = "INFO" + JAVA_OPTS = "-Djavax.net.debug=ssl:handshake" // mTLS debug + + # Cert configuration + CERTIFICATE_CRT = data.azurerm_key_vault_secret.certificate_crt_app_forwarder[0].value + CERTIFICATE_KEY = data.azurerm_key_vault_secret.certificate_key_app_forwarder[0].value + + WEBSITES_ENABLE_APP_SERVICE_STORAGE = false + WEBSITES_PORT = 8080 + # WEBSITE_SWAP_WARMUP_PING_PATH = "/actuator/health" + # WEBSITE_SWAP_WARMUP_PING_STATUSES = "200" + DOCKER_REGISTRY_SERVER_URL = "https://${data.azurerm_container_registry.acr.login_server}" + DOCKER_REGISTRY_SERVER_USERNAME = data.azurerm_container_registry.acr.admin_username + DOCKER_REGISTRY_SERVER_PASSWORD = data.azurerm_container_registry.acr.admin_password + + # Connection Pool + MAX_CONNECTIONS = 80 + MAX_CONNECTIONS_PER_ROUTE = 40 + CONN_TIMEOUT = 8 + + } + + +} + +// kv shared +data "azurerm_key_vault" "kv_shared" { + name = "pagopa-${var.env_short}-shared-kv" + resource_group_name = "pagopa-${var.env_short}-shared-sec-rg" +} + + +# Subnet to host the node forwarder + +data "azurerm_resource_group" "rg_node_forwarder" { + name = "pagopa-${var.env_short}-node-forwarder-rg" +} + +data "azurerm_subnet" "subnet_node_forwarder" { + name = "pagopa-${var.env_short}-node-forwarder-snet" + virtual_network_name = "pagopa-${var.env_short}-vnet" + resource_group_name = "pagopa-${var.env_short}-vnet-rg" +} + +data "azurerm_subnet" "subnet_apim" { + name = "pagopa-${var.env_short}-apim-snet" + virtual_network_name = "pagopa-${var.env_short}-vnet-integration" + resource_group_name = "pagopa-${var.env_short}-vnet-rg" +} + +data "azurerm_container_registry" "acr" { + name = "pagopa${var.env_short}commonacr" + resource_group_name = "pagopa-${var.env_short}-container-registry-rg" +} + + +module "app_forwarder_app_service" { + count = var.app_forwarder_enabled ? 1 : 0 + + source = "git::https://github.com/pagopa/terraform-azurerm-v3.git//app_service?ref=v8.12.2" + + vnet_integration = false + resource_group_name = data.azurerm_resource_group.rg_node_forwarder.name + location = var.location + + # App service plan vars + plan_name = format("%s-plan-app-forwarder", local.project) + sku_name = "S1" + + + # App service plan + name = format("%s-app-app-forwarder", local.project) + client_cert_enabled = false + always_on = true + docker_image = "${data.azurerm_container_registry.acr.login_server}/pagopanodeforwarder" + docker_image_tag = "latest" + # linux_fx_version = format("DOCKER|%s/pagopanodeforwarder:%s", data.azurerm_container_registry.acr.login_server, "latest") + health_check_path = "/actuator/info" + + app_settings = local.app_forwarder_app_settings + + allowed_subnets = [data.azurerm_subnet.subnet_apim.id] + allowed_ips = [] + + subnet_id = data.azurerm_subnet.subnet_node_forwarder.id + + tags = var.tags +} + +module "app_forwarder_slot_staging" { + count = var.app_forwarder_enabled ? 1 : 0 + + source = "git::https://github.com/pagopa/terraform-azurerm-v3.git//app_service_slot?ref=v8.12.2" + + # App service plan + app_service_id = module.app_forwarder_app_service[0].id + app_service_name = module.app_forwarder_app_service[0].name + + + # App service + name = "staging" + resource_group_name = data.azurerm_resource_group.rg_node_forwarder.name + location = var.location + always_on = true + # linux_fx_version = format("DOCKER|%s/pagopanodeforwarder:%s", module.container_registry.login_server, "latest") + docker_image = "${data.azurerm_container_registry.acr.login_server}/pagopanodeforwarder" + docker_image_tag = "latest" + health_check_path = "/actuator/info" + + + # App settings + app_settings = local.app_forwarder_app_settings + + allowed_subnets = [data.azurerm_subnet.subnet_apim.id] + allowed_ips = [] + subnet_id = data.azurerm_subnet.subnet_node_forwarder.id + + tags = var.tags +} + + +# KV placeholder for CERT and KEY certificate +#tfsec:ignore:azure-keyvault-ensure-secret-expiry tfsec:ignore:azure-keyvault-content-type-for-secret +resource "azurerm_key_vault_secret" "certificate_crt_app_forwarder_s" { + count = var.app_forwarder_enabled ? 1 : 0 + + name = "certificate-crt-app-forwarder" + value = "" + content_type = "text/plain" + + key_vault_id = data.azurerm_key_vault.kv_shared.id + + lifecycle { + ignore_changes = [ + value, + ] + } +} +#tfsec:ignore:azure-keyvault-ensure-secret-expiry tfsec:ignore:azure-keyvault-content-type-for-secret +resource "azurerm_key_vault_secret" "certificate_key_app_forwarder_s" { + count = var.app_forwarder_enabled ? 1 : 0 + + name = "certificate-key-app-forwarder" + value = "" + content_type = "text/plain" + + key_vault_id = data.azurerm_key_vault.kv_shared.id + + + lifecycle { + ignore_changes = [ + value, + ] + } +} + +data "azurerm_key_vault_secret" "certificate_crt_app_forwarder" { + count = var.app_forwarder_enabled ? 1 : 0 + + name = "certificate-crt-app-forwarder" + key_vault_id = data.azurerm_key_vault.kv_shared.id + +} +data "azurerm_key_vault_secret" "certificate_key_app_forwarder" { + count = var.app_forwarder_enabled ? 1 : 0 + + name = "certificate-key-app-forwarder" + key_vault_id = data.azurerm_key_vault.kv_shared.id + +} + diff --git a/src/domains/observability/99_variables.tf b/src/domains/observability/99_variables.tf index 48bac7ed11..3eb91d08b3 100644 --- a/src/domains/observability/99_variables.tf +++ b/src/domains/observability/99_variables.tf @@ -103,4 +103,10 @@ variable "dexp_re_db_linkes_service" { type = object({ enable = bool }) +} + +variable "app_forwarder_enabled" { + type = bool + description = "Enable app_forwarder" + default = false } \ No newline at end of file diff --git a/src/domains/observability/README.md b/src/domains/observability/README.md index 3ba44b0d9d..346a2bf90c 100644 --- a/src/domains/observability/README.md +++ b/src/domains/observability/README.md @@ -12,7 +12,10 @@ ## Modules -No modules. +| Name | Source | Version | +|------|--------|---------| +| [app\_forwarder\_app\_service](#module\_app\_forwarder\_app\_service) | git::https://github.com/pagopa/terraform-azurerm-v3.git//app_service | v8.12.2 | +| [app\_forwarder\_slot\_staging](#module\_app\_forwarder\_slot\_staging) | git::https://github.com/pagopa/terraform-azurerm-v3.git//app_service_slot | v8.12.2 | ## Resources @@ -51,22 +54,32 @@ No modules. | [azurerm_data_factory_trigger_schedule.Trigger_PDND_KPI_TPNP](https://registry.terraform.io/providers/hashicorp/azurerm/3.53.0/docs/resources/data_factory_trigger_schedule) | resource | | [azurerm_data_factory_trigger_schedule.Trigger_PDND_KPI_WAFDR](https://registry.terraform.io/providers/hashicorp/azurerm/3.53.0/docs/resources/data_factory_trigger_schedule) | resource | | [azurerm_data_factory_trigger_schedule.Trigger_PDND_KPI_WPNFDR](https://registry.terraform.io/providers/hashicorp/azurerm/3.53.0/docs/resources/data_factory_trigger_schedule) | resource | +| [azurerm_key_vault_secret.certificate_crt_app_forwarder_s](https://registry.terraform.io/providers/hashicorp/azurerm/3.53.0/docs/resources/key_vault_secret) | resource | +| [azurerm_key_vault_secret.certificate_key_app_forwarder_s](https://registry.terraform.io/providers/hashicorp/azurerm/3.53.0/docs/resources/key_vault_secret) | resource | | [azurerm_kusto_cluster.data_explorer_cluster](https://registry.terraform.io/providers/hashicorp/azurerm/3.53.0/docs/resources/kusto_cluster) | resource | | [azurerm_kusto_database.re_db](https://registry.terraform.io/providers/hashicorp/azurerm/3.53.0/docs/resources/kusto_database) | resource | | [azurerm_kusto_database_principal_assignment.qi_principal_assignment](https://registry.terraform.io/providers/hashicorp/azurerm/3.53.0/docs/resources/kusto_database_principal_assignment) | resource | | [azurerm_kusto_eventhub_data_connection.eventhub_connection_for_re_event](https://registry.terraform.io/providers/hashicorp/azurerm/3.53.0/docs/resources/kusto_eventhub_data_connection) | resource | | [azurerm_client_config.current](https://registry.terraform.io/providers/hashicorp/azurerm/3.53.0/docs/data-sources/client_config) | data source | +| [azurerm_container_registry.acr](https://registry.terraform.io/providers/hashicorp/azurerm/3.53.0/docs/data-sources/container_registry) | data source | | [azurerm_cosmosdb_account.bizevent_cosmos_account](https://registry.terraform.io/providers/hashicorp/azurerm/3.53.0/docs/data-sources/cosmosdb_account) | data source | | [azurerm_data_factory.qi_data_factory](https://registry.terraform.io/providers/hashicorp/azurerm/3.53.0/docs/data-sources/data_factory) | data source | | [azurerm_data_factory.qi_data_factory_cosmos](https://registry.terraform.io/providers/hashicorp/azurerm/3.53.0/docs/data-sources/data_factory) | data source | | [azurerm_eventhub.pagopa-evh-ns03_nodo-dei-pagamenti-re_nodo-dei-pagamenti-re](https://registry.terraform.io/providers/hashicorp/azurerm/3.53.0/docs/data-sources/eventhub) | data source | +| [azurerm_key_vault.kv_shared](https://registry.terraform.io/providers/hashicorp/azurerm/3.53.0/docs/data-sources/key_vault) | data source | +| [azurerm_key_vault_secret.certificate_crt_app_forwarder](https://registry.terraform.io/providers/hashicorp/azurerm/3.53.0/docs/data-sources/key_vault_secret) | data source | +| [azurerm_key_vault_secret.certificate_key_app_forwarder](https://registry.terraform.io/providers/hashicorp/azurerm/3.53.0/docs/data-sources/key_vault_secret) | data source | | [azurerm_resource_group.monitor_rg](https://registry.terraform.io/providers/hashicorp/azurerm/3.53.0/docs/data-sources/resource_group) | data source | +| [azurerm_resource_group.rg_node_forwarder](https://registry.terraform.io/providers/hashicorp/azurerm/3.53.0/docs/data-sources/resource_group) | data source | +| [azurerm_subnet.subnet_apim](https://registry.terraform.io/providers/hashicorp/azurerm/3.53.0/docs/data-sources/subnet) | data source | +| [azurerm_subnet.subnet_node_forwarder](https://registry.terraform.io/providers/hashicorp/azurerm/3.53.0/docs/data-sources/subnet) | data source | | [azurerm_subscription.current](https://registry.terraform.io/providers/hashicorp/azurerm/3.53.0/docs/data-sources/subscription) | data source | ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| [app\_forwarder\_enabled](#input\_app\_forwarder\_enabled) | Enable app\_forwarder | `bool` | `false` | no | | [dexp\_db](#input\_dexp\_db) | n/a |
object({
enable = bool
hot_cache_period = string
soft_delete_period = string
})
| n/a | yes | | [dexp\_params](#input\_dexp\_params) | n/a |
object({
enabled = bool
sku = object({
name = string
capacity = number
})
autoscale = object({
enabled = bool
min_instances = number
max_instances = number
})
public_network_access_enabled = bool
double_encryption_enabled = bool
disk_encryption_enabled = bool
purge_enabled = bool
})
| n/a | yes | | [dexp\_re\_db\_linkes\_service](#input\_dexp\_re\_db\_linkes\_service) | n/a |
object({
enable = bool
})
| n/a | yes | diff --git a/src/domains/observability/env/weu-dev/terraform.tfvars b/src/domains/observability/env/weu-dev/terraform.tfvars index 097a9129cb..91d6471e47 100644 --- a/src/domains/observability/env/weu-dev/terraform.tfvars +++ b/src/domains/observability/env/weu-dev/terraform.tfvars @@ -44,4 +44,6 @@ dexp_db = { dexp_re_db_linkes_service = { enable = true -} \ No newline at end of file +} + +app_forwarder_enabled = true \ No newline at end of file diff --git a/src/domains/observability/env/weu-uat/terraform.tfvars b/src/domains/observability/env/weu-uat/terraform.tfvars index 54b4da31e1..24a9e1c062 100644 --- a/src/domains/observability/env/weu-uat/terraform.tfvars +++ b/src/domains/observability/env/weu-uat/terraform.tfvars @@ -46,3 +46,5 @@ dexp_db = { dexp_re_db_linkes_service = { enable = true } + +app_forwarder_enabled = true \ No newline at end of file diff --git a/src/domains/observability/scripts/certs/dev-certificate.crt b/src/domains/observability/scripts/certs/dev-certificate.crt new file mode 100644 index 0000000000..3e185c74b9 --- /dev/null +++ b/src/domains/observability/scripts/certs/dev-certificate.crt @@ -0,0 +1,7 @@ +-----BEGIN CERTIFICATE----- +########################### +########################### + +########################### +########################### +-----END CERTIFICATE----- \ No newline at end of file diff --git a/src/domains/observability/scripts/certs/dev-private.key b/src/domains/observability/scripts/certs/dev-private.key new file mode 100644 index 0000000000..e200b297a3 --- /dev/null +++ b/src/domains/observability/scripts/certs/dev-private.key @@ -0,0 +1,7 @@ +-----BEGIN PRIVATE KEY----- +########################### +########################### + +########################### +########################### +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/src/domains/observability/scripts/set_kv_secrets.sh b/src/domains/observability/scripts/set_kv_secrets.sh new file mode 100644 index 0000000000..53477a2821 --- /dev/null +++ b/src/domains/observability/scripts/set_kv_secrets.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash + + +# https://pagopa.atlassian.net/wiki/spaces/PPAOP/pages/1049985209/Parametri+Mutua+Autenticazione + +if [ $# -eq 0 ] + then + echo "> sh set_kv_secrets.sh " + exit +fi + +environment=$1 + +pem_certificate="./certs/" +crt_certificate="./certs/$environment-certificate.crt" +pkcs1_private_key="" +pkcs8_private_key="./certs/" +kv_name="pagopa-${environment:0:1}-shared-kv" + + +if [[ "$environment" == "dev" ]]; then # UAT-NEXI + pem_certificate+="pagopajira.stgb2b-issuing.nexi.it.pem" +elif [[ "$environment" == "uat" ]]; then # PROD-NEXI + pem_certificate+="pagopajira.b2b-issuing.nexi.it.pem" +else + echo "PEM Certificate not found" + exit +fi + +pkcs1_private_key="$environment-private.key" + +if [[ ! -f "$pem_certificate" ]]; then + echo "$pem_certificate not exist." +fi + +if [[ ! -f "$pkcs1_private_key" ]]; then + echo "$pkcs1_private_key not exist." +fi + +pkcs8_private_key+="$pkcs1_private_key" + +# convert private key PKCS1 to PKCS8 +openssl pkcs8 -topk8 -nocrypt -in "$pkcs1_private_key" -out "$pkcs8_private_key" + +# extract crt from pem +openssl x509 -outform pem -in "$pem_certificate" -out "$crt_certificate" + +echo "uploading info into azure kv" +az keyvault secret set --vault-name "$kv_name" --name "certificate-crt-app-forwarder" --file "$crt_certificate" +# https://portal.azure.com/?l=en.en-us#@pagopait.onmicrosoft.com/asset/Microsoft_Azure_KeyVault/Secret/https://pagopa-d-shared-kv.vault.azure.net/secrets/certificate-crt-app-forwarder +az keyvault secret set --vault-name "$kv_name" --name "certificate-key-app-forwarder" --file "$pkcs8_private_key" +# https://portal.azure.com/?l=en.en-us#@pagopait.onmicrosoft.com/asset/Microsoft_Azure_KeyVault/Secret/https://pagopa-d-shared-kv.vault.azure.net/secrets/certificate-key-app-forwarder