diff --git a/src/domains/citizen-auth-app/01_network.tf b/src/domains/citizen-auth-app/01_network.tf index 9b111fcfd..e921d7acd 100644 --- a/src/domains/citizen-auth-app/01_network.tf +++ b/src/domains/citizen-auth-app/01_network.tf @@ -93,3 +93,35 @@ data "azurerm_subnet" "appgateway_snet" { virtual_network_name = local.vnet_common_name resource_group_name = local.vnet_common_resource_group_name } + +## session_manager subnet +data "azurerm_resource_group" "italy_north_common_rg" { + name = format("%s-itn-common-rg-001", local.product) +} + +data "azurerm_virtual_network" "common_vnet_italy_north" { + name = format("%s-itn-common-vnet-001", local.product) + resource_group_name = data.azurerm_resource_group.italy_north_common_rg.name +} + +module "session_manager_snet" { + source = "git::https://github.com/pagopa/terraform-azurerm-v3.git//subnet?ref=v8.4.0" + name = format("%s-session-manager-snet", local.common_session_manager_project) + address_prefixes = var.cidr_subnet_session_manager + resource_group_name = data.azurerm_resource_group.italy_north_common_rg.name + virtual_network_name = data.azurerm_virtual_network.common_vnet_italy_north.name + + private_endpoint_network_policies_enabled = true + + service_endpoints = [ + "Microsoft.Web", + ] + + delegation = { + name = "default" + service_delegation = { + name = "Microsoft.Web/serverFarms" + actions = ["Microsoft.Network/virtualNetworks/subnets/action"] + } + } +} diff --git a/src/domains/citizen-auth-app/04_function_lollipop.tf b/src/domains/citizen-auth-app/04_function_lollipop.tf index 046952dc7..355514cbe 100644 --- a/src/domains/citizen-auth-app/04_function_lollipop.tf +++ b/src/domains/citizen-auth-app/04_function_lollipop.tf @@ -127,6 +127,7 @@ module "function_lollipop" { data.azurerm_subnet.apim_v2_snet.id, data.azurerm_subnet.app_backend_l1_snet.id, data.azurerm_subnet.app_backend_l2_snet.id, + module.session_manager_snet.id, ] # Action groups for alerts diff --git a/src/domains/citizen-auth-app/04_redis.tf b/src/domains/citizen-auth-app/04_redis.tf index 3970800b3..037811667 100644 --- a/src/domains/citizen-auth-app/04_redis.tf +++ b/src/domains/citizen-auth-app/04_redis.tf @@ -1,6 +1,16 @@ - -# Redis Common +# Citizen-auth domain Redis Common data "azurerm_redis_cache" "redis_common" { name = format("%s-%s-%s-redis-std-v6", local.product, var.location_short, var.domain) resource_group_name = data.azurerm_resource_group.data_rg.name } + +### IO-core domain Redis Common +data "azurerm_resource_group" "core_domain_common_rg" { + name = format("%s-rg-common", local.product) +} + +data "azurerm_redis_cache" "core_domain_redis_common" { + name = format("%s-redis-common", local.product) + resource_group_name = data.azurerm_resource_group.core_domain_common_rg.name +} +### diff --git a/src/domains/citizen-auth-app/07_function_fast_login.tf b/src/domains/citizen-auth-app/07_function_fast_login.tf index d9fd994e4..849bc9d80 100644 --- a/src/domains/citizen-auth-app/07_function_fast_login.tf +++ b/src/domains/citizen-auth-app/07_function_fast_login.tf @@ -141,6 +141,7 @@ module "function_fast_login" { data.azurerm_subnet.app_backend_l1_snet.id, data.azurerm_subnet.app_backend_l2_snet.id, data.azurerm_subnet.ioweb_profile_snet.id, + module.session_manager_snet.id, ] # Action groups for alerts diff --git a/src/domains/citizen-auth-app/08_session_manager.tf b/src/domains/citizen-auth-app/08_session_manager.tf new file mode 100644 index 000000000..2c2c8dd19 --- /dev/null +++ b/src/domains/citizen-auth-app/08_session_manager.tf @@ -0,0 +1,214 @@ +resource "azurerm_resource_group" "session_manager_rg" { + name = format("%s-session-manager-rg", local.common_session_manager_project) + location = var.session_manager_location + + tags = var.tags +} + +################################# +## Session Manager App service ## +################################# +locals { + app_settings_common = { + WEBSITES_ENABLE_APP_SERVICE_STORAGE = false + WEBSITES_PORT = 8080 + + WEBSITE_NODE_DEFAULT_VERSION = "20.12.2" + WEBSITE_RUN_FROM_PACKAGE = "1" + WEBSITE_VNET_ROUTE_ALL = "1" + + // ENVIRONMENT + NODE_ENV = "production" + + FETCH_KEEPALIVE_ENABLED = "true" + // see https://github.com/MicrosoftDocs/azure-docs/issues/29600#issuecomment-607990556 + // and https://docs.microsoft.com/it-it/azure/app-service/app-service-web-nodejs-best-practices-and-troubleshoot-guide#scenarios-and-recommendationstroubleshooting + // FETCH_KEEPALIVE_SOCKET_ACTIVE_TTL should not exceed 120000 (app service socket timeout) + FETCH_KEEPALIVE_SOCKET_ACTIVE_TTL = "110000" + // (FETCH_KEEPALIVE_MAX_SOCKETS * number_of_node_processes) should not exceed 160 (max sockets per VM) + FETCH_KEEPALIVE_MAX_SOCKETS = "128" + FETCH_KEEPALIVE_MAX_FREE_SOCKETS = "10" + FETCH_KEEPALIVE_FREE_SOCKET_TIMEOUT = "30000" + FETCH_KEEPALIVE_TIMEOUT = "60000" + + # REDIS AUTHENTICATION + REDIS_URL = data.azurerm_redis_cache.core_domain_redis_common.hostname + REDIS_PORT = data.azurerm_redis_cache.core_domain_redis_common.ssl_port + REDIS_PASSWORD = data.azurerm_redis_cache.core_domain_redis_common.primary_access_key + } +} + +module "session_manager" { + source = "git::https://github.com/pagopa/terraform-azurerm-v3.git//app_service?ref=v8.4.0" + + # App service plan + plan_type = "internal" + plan_name = format("%s-plan-session-manager", local.common_session_manager_project) + sku_name = var.session_manager_plan_sku_name + + # App service + name = format("%s-session-manager", local.common_session_manager_project) + resource_group_name = azurerm_resource_group.session_manager_rg.name + location = azurerm_resource_group.session_manager_rg.location + + always_on = true + node_version = "20-lts" + app_command_line = "npm run start" + health_check_path = "/healthcheck" + health_check_maxpingfailures = 3 + + app_settings = local.app_settings_common + + allowed_subnets = [ + data.azurerm_subnet.apim_v2_snet.id, + data.azurerm_subnet.appgateway_snet.id + // TODO: add proxy subnet + ] + allowed_ips = [] + + subnet_id = module.session_manager_snet.id + vnet_integration = true + + tags = var.tags +} + +## staging slot +module "session_manager_staging" { + source = "git::https://github.com/pagopa/terraform-azurerm-v3.git//app_service_slot?ref=v8.4.0" + + app_service_id = module.session_manager.id + app_service_name = module.session_manager.name + + name = format("%s-session-manager-staging", local.common_session_manager_project) + resource_group_name = azurerm_resource_group.session_manager_rg.name + location = azurerm_resource_group.session_manager_rg.location + + always_on = true + node_version = "20-lts" + app_command_line = "npm run start" + health_check_path = "/healthcheck" + + app_settings = local.app_settings_common + + allowed_subnets = [ + data.azurerm_subnet.apim_v2_snet.id, + data.azurerm_subnet.appgateway_snet.id + // TODO: add proxy subnet + ] + allowed_ips = [] + + subnet_id = module.session_manager_snet.id + vnet_integration = true + + tags = var.tags +} + +## autoscaling +resource "azurerm_monitor_autoscale_setting" "session_manager_autoscale_setting" { + name = format("%s-autoscale", module.session_manager.name) + resource_group_name = azurerm_resource_group.session_manager_rg.name + location = azurerm_resource_group.session_manager_rg.location + target_resource_id = module.session_manager.plan_id + + profile { + name = "default" + + capacity { + default = var.session_manager_autoscale_settings.autoscale_default + minimum = var.session_manager_autoscale_settings.autoscale_minimum + maximum = var.session_manager_autoscale_settings.autoscale_maximum + } + + # Increase rules + + rule { + metric_trigger { + metric_name = "Requests" + metric_resource_id = module.session_manager.id + metric_namespace = "microsoft.web/sites" + time_grain = "PT1M" + statistic = "Average" + time_window = "PT1M" + time_aggregation = "Average" + operator = "GreaterThan" + threshold = 4000 + divide_by_instance_count = false + } + + scale_action { + direction = "Increase" + type = "ChangeCount" + value = "2" + cooldown = "PT1M" + } + } + + rule { + metric_trigger { + metric_name = "CpuPercentage" + metric_resource_id = module.session_manager.plan_id + metric_namespace = "microsoft.web/serverfarms" + time_grain = "PT1M" + statistic = "Average" + time_window = "PT1M" + time_aggregation = "Average" + operator = "GreaterThan" + threshold = 40 + divide_by_instance_count = false + } + + scale_action { + direction = "Increase" + type = "ChangeCount" + value = "2" + cooldown = "PT1M" + } + } + + # Decrease rules + + rule { + metric_trigger { + metric_name = "Requests" + metric_resource_id = module.session_manager.id + metric_namespace = "microsoft.web/sites" + time_grain = "PT1M" + statistic = "Average" + time_window = "PT15M" + time_aggregation = "Average" + operator = "LessThan" + threshold = 1500 + divide_by_instance_count = false + } + + scale_action { + direction = "Decrease" + type = "ChangeCount" + value = "1" + cooldown = "PT30M" + } + } + + rule { + metric_trigger { + metric_name = "CpuPercentage" + metric_resource_id = module.session_manager.plan_id + metric_namespace = "microsoft.web/serverfarms" + time_grain = "PT1M" + statistic = "Average" + time_window = "PT15M" + time_aggregation = "Average" + operator = "LessThan" + threshold = 15 + divide_by_instance_count = false + } + + scale_action { + direction = "Decrease" + type = "ChangeCount" + value = "1" + cooldown = "PT30M" + } + } + } +} diff --git a/src/domains/citizen-auth-app/99_locals.tf b/src/domains/citizen-auth-app/99_locals.tf index 3eebc2361..622795391 100644 --- a/src/domains/citizen-auth-app/99_locals.tf +++ b/src/domains/citizen-auth-app/99_locals.tf @@ -3,6 +3,8 @@ locals { product = "${var.prefix}-${var.env_short}" common_project = "${var.prefix}-${var.env_short}-${var.location_short}" + common_session_manager_project = "${var.prefix}-${var.env_short}-${var.session_manager_location_short}" + monitor_action_group_slack_name = "SlackPagoPA" monitor_action_group_email_name = "EmailPagoPA" diff --git a/src/domains/citizen-auth-app/99_variables.tf b/src/domains/citizen-auth-app/99_variables.tf index 16721f0cc..d8e9e4a30 100644 --- a/src/domains/citizen-auth-app/99_variables.tf +++ b/src/domains/citizen-auth-app/99_variables.tf @@ -55,6 +55,16 @@ variable "location_string" { description = "One of West Europe, North Europe" } +variable "session_manager_location" { + type = string + description = "Due to capacity issues, session_manager will be created on northitaly" +} + +variable "session_manager_location_short" { + type = string + default = "itn" +} + variable "instance" { type = string description = "One of beta, prod01, prod02" @@ -217,3 +227,25 @@ variable "function_fastlogin_autoscale_default" { default = 1 } +#################### +# Session manager ## +#################### +variable "cidr_subnet_session_manager" { + type = list(string) + description = "Session manager app service address space." +} + +variable "session_manager_plan_sku_name" { + description = "App service plan sku name" + type = string + default = "P1v3" +} + +variable "session_manager_autoscale_settings" { + type = object({ + autoscale_minimum = number + autoscale_maximum = number + autoscale_default = number + }) +} +#################### diff --git a/src/domains/citizen-auth-app/README.md b/src/domains/citizen-auth-app/README.md index 9d641c69a..4f1c76977 100644 --- a/src/domains/citizen-auth-app/README.md +++ b/src/domains/citizen-auth-app/README.md @@ -20,6 +20,9 @@ | [function\_lollipop](#module\_function\_lollipop) | git::https://github.com/pagopa/terraform-azurerm-v3.git//function_app | v5.2.0 | | [function\_lollipop\_staging\_slot](#module\_function\_lollipop\_staging\_slot) | git::https://github.com/pagopa/terraform-azurerm-v3.git//function_app_slot | v5.2.0 | | [lollipop\_snet](#module\_lollipop\_snet) | git::https://github.com/pagopa/terraform-azurerm-v3.git//subnet | v4.1.15 | +| [session\_manager](#module\_session\_manager) | git::https://github.com/pagopa/terraform-azurerm-v3.git//app_service | v8.4.0 | +| [session\_manager\_snet](#module\_session\_manager\_snet) | git::https://github.com/pagopa/terraform-azurerm-v3.git//subnet | v8.4.0 | +| [session\_manager\_staging](#module\_session\_manager\_staging) | git::https://github.com/pagopa/terraform-azurerm-v3.git//app_service_slot | v8.4.0 | ## Resources @@ -27,11 +30,13 @@ |------|------| | [azurerm_monitor_autoscale_setting.function_fast_login](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/monitor_autoscale_setting) | resource | | [azurerm_monitor_autoscale_setting.function_lollipop](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/monitor_autoscale_setting) | resource | +| [azurerm_monitor_autoscale_setting.session_manager_autoscale_setting](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/monitor_autoscale_setting) | resource | | [azurerm_monitor_scheduled_query_rules_alert_v2.alert_function_lollipop_HandlePubKeyRevoke_failure](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/monitor_scheduled_query_rules_alert_v2) | resource | | [azurerm_monitor_scheduled_query_rules_alert_v2.samlresponse_missing_detection_alert](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/monitor_scheduled_query_rules_alert_v2) | resource | | [azurerm_private_dns_a_record.ingress](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_dns_a_record) | resource | | [azurerm_resource_group.fast_login_rg](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | resource | | [azurerm_resource_group.lollipop_rg](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | resource | +| [azurerm_resource_group.session_manager_rg](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | resource | | [azuread_group.adgroup_admin](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/group) | data source | | [azuread_group.adgroup_developers](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/group) | data source | | [azuread_group.adgroup_externals](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/group) | data source | @@ -59,8 +64,11 @@ | [azurerm_private_dns_zone.privatelink_mongo_cosmos_azure_com](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/private_dns_zone) | data source | | [azurerm_private_dns_zone.privatelink_queue_core_windows_net](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/private_dns_zone) | data source | | [azurerm_private_dns_zone.privatelink_table_core_windows_net](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/private_dns_zone) | data source | +| [azurerm_redis_cache.core_domain_redis_common](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/redis_cache) | data source | | [azurerm_redis_cache.redis_common](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/redis_cache) | data source | +| [azurerm_resource_group.core_domain_common_rg](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resource_group) | data source | | [azurerm_resource_group.data_rg](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resource_group) | data source | +| [azurerm_resource_group.italy_north_common_rg](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resource_group) | data source | | [azurerm_resource_group.monitor_rg](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resource_group) | data source | | [azurerm_storage_account.immutable_lv_audit_logs_storage](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/storage_account) | data source | | [azurerm_storage_account.lollipop_assertion_storage](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/storage_account) | data source | @@ -72,6 +80,7 @@ | [azurerm_subnet.ioweb_profile_snet](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/subnet) | data source | | [azurerm_subnet.private_endpoints_subnet](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/subnet) | data source | | [azurerm_subscription.current](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/subscription) | data source | +| [azurerm_virtual_network.common_vnet_italy_north](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/virtual_network) | data source | | [azurerm_virtual_network.vnet](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/virtual_network) | data source | | [azurerm_virtual_network.vnet_common](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/virtual_network) | data source | @@ -82,6 +91,7 @@ | [application\_insights\_name](#input\_application\_insights\_name) | Specifies the name of the Application Insights. | `string` | n/a | yes | | [cidr\_subnet\_fnfastlogin](#input\_cidr\_subnet\_fnfastlogin) | Function Lollipop address space. | `list(string)` | n/a | yes | | [cidr\_subnet\_fnlollipop](#input\_cidr\_subnet\_fnlollipop) | Function Lollipop address space. | `list(string)` | n/a | yes | +| [cidr\_subnet\_session\_manager](#input\_cidr\_subnet\_session\_manager) | Session manager app service address space. | `list(string)` | n/a | yes | | [domain](#input\_domain) | n/a | `string` | n/a | yes | | [enable\_azdoa](#input\_enable\_azdoa) | Specifies Azure Devops Agent enabling | `bool` | `true` | no | | [env](#input\_env) | n/a | `string` | n/a | yes | @@ -110,6 +120,10 @@ | [monitor\_resource\_group\_name](#input\_monitor\_resource\_group\_name) | Monitor resource group name | `string` | n/a | yes | | [prefix](#input\_prefix) | n/a | `string` | n/a | yes | | [reloader\_helm](#input\_reloader\_helm) | reloader helm chart configuration |
object({| n/a | yes | +| [session\_manager\_autoscale\_settings](#input\_session\_manager\_autoscale\_settings) | n/a |
chart_version = string,
image_name = string,
image_tag = string
})
object({| n/a | yes | +| [session\_manager\_location](#input\_session\_manager\_location) | Due to capacity issues, session\_manager will be created on northitaly | `string` | n/a | yes | +| [session\_manager\_location\_short](#input\_session\_manager\_location\_short) | n/a | `string` | `"itn"` | no | +| [session\_manager\_plan\_sku\_name](#input\_session\_manager\_plan\_sku\_name) | App service plan sku name | `string` | `"P1v3"` | no | | [tags](#input\_tags) | n/a | `map(any)` |
autoscale_minimum = number
autoscale_maximum = number
autoscale_default = number
})
{| no | | [tls\_cert\_check\_helm](#input\_tls\_cert\_check\_helm) | tls cert helm chart configuration |
"CreatedBy": "Terraform"
}
object({| n/a | yes | diff --git a/src/domains/citizen-auth-app/env/weu-beta/terraform.tfvars b/src/domains/citizen-auth-app/env/weu-beta/terraform.tfvars index 96bb25306..1ad0432f5 100644 --- a/src/domains/citizen-auth-app/env/weu-beta/terraform.tfvars +++ b/src/domains/citizen-auth-app/env/weu-beta/terraform.tfvars @@ -1,11 +1,12 @@ -prefix = "io" -env_short = "p" -env = "prod" -domain = "citizen-auth" -location = "westeurope" -location_short = "weu" -location_string = "West Europe" -instance = "beta" +prefix = "io" +env_short = "p" +env = "prod" +domain = "citizen-auth" +location = "westeurope" +location_short = "weu" +location_string = "West Europe" +session_manager_location = "italynorth" +instance = "beta" tags = { CreatedBy = "Terraform" @@ -41,6 +42,13 @@ tls_cert_check_helm = { ### Aks -ingress_load_balancer_ip = "10.10.0.254" -cidr_subnet_fnlollipop = ["127.0.0.1/32"] -cidr_subnet_fnfastlogin = ["127.0.0.2/32"] +ingress_load_balancer_ip = "10.10.0.254" +cidr_subnet_fnlollipop = ["127.0.0.1/32"] +cidr_subnet_fnfastlogin = ["127.0.0.2/32"] +cidr_subnet_session_manager = ["127.0.0.3/32"] + +session_manager_autoscale_settings = { + autoscale_minimum = 1 + autoscale_default = 2 + autoscale_maximum = 10 +} diff --git a/src/domains/citizen-auth-app/env/weu-prod01/terraform.tfvars b/src/domains/citizen-auth-app/env/weu-prod01/terraform.tfvars index 5c51557fd..9c46a4a5e 100644 --- a/src/domains/citizen-auth-app/env/weu-prod01/terraform.tfvars +++ b/src/domains/citizen-auth-app/env/weu-prod01/terraform.tfvars @@ -1,13 +1,14 @@ -prefix = "io" -env_short = "p" -env = "prod" -domain = "citizen-auth" -location = "westeurope" -location_short = "weu" -location_string = "West Europe" -instance = "prod01" -lollipop_enabled = true -fastlogin_enabled = true +prefix = "io" +env_short = "p" +env = "prod" +domain = "citizen-auth" +location = "westeurope" +location_short = "weu" +location_string = "West Europe" +session_manager_location = "italynorth" +instance = "prod01" +lollipop_enabled = true +fastlogin_enabled = true tags = { CreatedBy = "Terraform" @@ -61,3 +62,11 @@ function_fastlogin_sku_size = "P1v3" function_fastlogin_autoscale_minimum = 2 function_fastlogin_autoscale_maximum = 20 function_fastlogin_autoscale_default = 10 + +# Session manager +cidr_subnet_session_manager = ["10.20.0.0/26"] +session_manager_autoscale_settings = { + autoscale_minimum = 1 + autoscale_default = 2 + autoscale_maximum = 10 +}
chart_version = string,
image_name = string,
image_tag = string
})