diff --git a/infra/modules/azure_app_service_exposed/README.md b/infra/modules/azure_app_service_exposed/README.md index bc34027b6..359a25963 100644 --- a/infra/modules/azure_app_service_exposed/README.md +++ b/infra/modules/azure_app_service_exposed/README.md @@ -40,6 +40,7 @@ This module is used to create an Azure App Service, allowing it to be configured | [resource\_group\_name](#input\_resource\_group\_name) | Resource group to deploy resources to | `string` | n/a | yes | | [slot\_app\_settings](#input\_slot\_app\_settings) | Staging slot application settings | `map(string)` | `{}` | no | | [stack](#input\_stack) | n/a | `string` | `"node"` | no | +| [startup\_command](#input\_startup\_command) | (Optional) The PM2 file used as PM2 process entry point | `string` | `""` | no | | [sticky\_app\_setting\_names](#input\_sticky\_app\_setting\_names) | (Optional) A list of application setting names that are not swapped between slots | `list(string)` | `[]` | no | | [tags](#input\_tags) | Resources tags | `map(any)` | n/a | yes | | [tier](#input\_tier) | Resource tiers depending on workload. Allowed values are 'xs', 's', 'm', 'l', 'xl'. Legacy values 'premium', 'standard', 'test' are also supported for backward compatibility. | `string` | `"l"` | no | diff --git a/infra/modules/azure_app_service_exposed/app_service.tf b/infra/modules/azure_app_service_exposed/app_service.tf index ff6b63d04..72ef7d8d2 100644 --- a/infra/modules/azure_app_service_exposed/app_service.tf +++ b/infra/modules/azure_app_service_exposed/app_service.tf @@ -19,7 +19,7 @@ resource "azurerm_linux_web_app" "this" { health_check_path = var.health_check_path health_check_eviction_time_in_min = 2 - app_command_line = local.app_service.command_line + app_command_line = local.app_service.startup_command application_stack { node_version = var.stack == "node" ? "${var.node_version}-lts" : null diff --git a/infra/modules/azure_app_service_exposed/app_service_slot.tf b/infra/modules/azure_app_service_exposed/app_service_slot.tf index 9f43de138..de8454456 100644 --- a/infra/modules/azure_app_service_exposed/app_service_slot.tf +++ b/infra/modules/azure_app_service_exposed/app_service_slot.tf @@ -19,7 +19,7 @@ resource "azurerm_linux_web_app_slot" "this" { health_check_path = var.health_check_path health_check_eviction_time_in_min = 2 - app_command_line = local.app_service.command_line + app_command_line = local.app_service.startup_command application_stack { node_version = var.stack == "node" ? "${var.node_version}-lts" : null diff --git a/infra/modules/azure_app_service_exposed/locals.tf b/infra/modules/azure_app_service_exposed/locals.tf index 013bf37e5..64b044d6e 100644 --- a/infra/modules/azure_app_service_exposed/locals.tf +++ b/infra/modules/azure_app_service_exposed/locals.tf @@ -9,7 +9,10 @@ locals { zone_balancing_enabled = local.tier != "s" && local.tier != "xs" is_slot_enabled = local.tier == "s" || local.tier == "xs" ? 0 : 1 always_on = local.tier == "xs" ? false : true - command_line = var.pm2_startup_file_name == null ? null : "pm2 start ${var.pm2_startup_file_name} -i max --no-daemon" + startup_command = (var.stack == "node" + ? (var.startup_command == "" ? "pm2 start index.js -i max --no-daemon" : var.startup_command) + : (var.stack == "java" && var.startup_command == "" ? null : var.startup_command) + ) } application_insights = { diff --git a/infra/modules/azure_app_service_exposed/tests/appservice.tftest.hcl b/infra/modules/azure_app_service_exposed/tests/appservice.tftest.hcl index d0d6e0e96..e0eb3795a 100644 --- a/infra/modules/azure_app_service_exposed/tests/appservice.tftest.hcl +++ b/infra/modules/azure_app_service_exposed/tests/appservice.tftest.hcl @@ -79,3 +79,248 @@ run "app_service_is_correct_plan" { error_message = "The App Service should have Always On enabled" } } + +run "app_service_node_default_startup_command" { + command = plan + + plan_options { + target = [ + azurerm_linux_web_app.this, + azurerm_linux_web_app_slot.this, + ] + } + + variables { + environment = { + prefix = "dx" + env_short = "d" + location = "italynorth" + domain = "modules" + app_name = "test" + instance_number = "01" + } + + tags = {} + + resource_group_name = run.setup_tests.resource_group_name + tier = "m" + + app_settings = {} + slot_app_settings = {} + + health_check_path = "/health" + } + + assert { + condition = azurerm_linux_web_app.this.site_config[0].application_stack[0].node_version != null + error_message = "Node version is null" + } + + assert { + condition = azurerm_linux_web_app_slot.this[0].site_config[0].application_stack[0].node_version != null + error_message = "Node version is null on staging slot" + } + + assert { + condition = strcontains(azurerm_linux_web_app.this.site_config[0].app_command_line, "pm2 start") + error_message = "PM2 is not set as default for Node.js" + } + + assert { + condition = strcontains(azurerm_linux_web_app_slot.this[0].site_config[0].app_command_line, "pm2 start") + error_message = "PM2 is not set as default for Node.js on staging slot" + } +} + +run "app_service_node_custom_startup_command" { + command = plan + + plan_options { + target = [ + azurerm_linux_web_app.this, + azurerm_linux_web_app_slot.this, + ] + } + + variables { + environment = { + prefix = "dx" + env_short = "d" + location = "italynorth" + domain = "modules" + app_name = "test" + instance_number = "01" + } + + tags = {} + + resource_group_name = run.setup_tests.resource_group_name + tier = "m" + + app_settings = {} + slot_app_settings = {} + + health_check_path = "/health" + + startup_command = "custom command" + } + + assert { + condition = azurerm_linux_web_app.this.site_config[0].application_stack[0].node_version != null + error_message = "Node version is null" + } + + assert { + condition = azurerm_linux_web_app.this.site_config[0].app_command_line == "custom command" + error_message = "Startup command override doesn't work on Node.js stack" + } +} + +run "app_service_java_default_startup_command" { + command = plan + + plan_options { + target = [ + azurerm_linux_web_app.this, + azurerm_linux_web_app_slot.this, + ] + } + + variables { + environment = { + prefix = "dx" + env_short = "d" + location = "italynorth" + domain = "modules" + app_name = "test" + instance_number = "01" + } + + tags = {} + + resource_group_name = run.setup_tests.resource_group_name + tier = "m" + + app_settings = {} + slot_app_settings = {} + + health_check_path = "/health" + + stack = "java" + } + + assert { + condition = azurerm_linux_web_app.this.site_config[0].application_stack[0].java_version != null + error_message = "Java version is null" + } + + assert { + condition = azurerm_linux_web_app_slot.this[0].site_config[0].application_stack[0].java_version != null + error_message = "Java version is null on staging slot" + } + + assert { + condition = azurerm_linux_web_app.this.site_config[0].application_stack[0].java_server != null + error_message = "Java server is null" + } + + assert { + condition = azurerm_linux_web_app_slot.this[0].site_config[0].application_stack[0].java_server != null + error_message = "Java server is null on staging slot" + } + + assert { + condition = azurerm_linux_web_app.this.site_config[0].application_stack[0].java_server_version != null + error_message = "Java server version is null" + } + + assert { + condition = azurerm_linux_web_app_slot.this[0].site_config[0].application_stack[0].java_server_version != null + error_message = "Java server version is null on staging slot" + } + + assert { + condition = azurerm_linux_web_app.this.site_config[0].app_command_line == null + error_message = "Default startup command value is not null on Java stack" + } + + assert { + condition = azurerm_linux_web_app_slot.this[0].site_config[0].app_command_line == null + error_message = "Default startup command value is not null on Java stack on staging slot" + } +} + +run "app_service_java_custom_startup_command" { + command = plan + + plan_options { + target = [ + azurerm_linux_web_app.this, + azurerm_linux_web_app_slot.this, + ] + } + + variables { + environment = { + prefix = "dx" + env_short = "d" + location = "italynorth" + domain = "modules" + app_name = "test" + instance_number = "01" + } + + tags = {} + + resource_group_name = run.setup_tests.resource_group_name + tier = "m" + + app_settings = {} + slot_app_settings = {} + + health_check_path = "/health" + + stack = "java" + startup_command = "custom command" + } + + assert { + condition = azurerm_linux_web_app.this.site_config[0].application_stack[0].java_version != null + error_message = "Java version is null" + } + + assert { + condition = azurerm_linux_web_app_slot.this[0].site_config[0].application_stack[0].java_version != null + error_message = "Java version is null on staging slot" + } + + assert { + condition = azurerm_linux_web_app.this.site_config[0].application_stack[0].java_server != null + error_message = "Java server is null" + } + + assert { + condition = azurerm_linux_web_app_slot.this[0].site_config[0].application_stack[0].java_server != null + error_message = "Java server is null on staging slot" + } + + assert { + condition = azurerm_linux_web_app.this.site_config[0].application_stack[0].java_server_version != null + error_message = "Java server version is null" + } + + assert { + condition = azurerm_linux_web_app_slot.this[0].site_config[0].application_stack[0].java_server_version != null + error_message = "Java server version is null on staging slot" + } + + assert { + condition = azurerm_linux_web_app.this.site_config[0].app_command_line != null + error_message = "Startup command override doesn't work on Java stack" + } + + assert { + condition = azurerm_linux_web_app_slot.this[0].site_config[0].app_command_line != null + error_message = "Startup command override doesn't work on Java stack on staging slot" + } +} diff --git a/infra/modules/azure_app_service_exposed/variables.tf b/infra/modules/azure_app_service_exposed/variables.tf index a798df332..54b96b217 100644 --- a/infra/modules/azure_app_service_exposed/variables.tf +++ b/infra/modules/azure_app_service_exposed/variables.tf @@ -104,3 +104,9 @@ variable "pm2_startup_file_name" { default = null description = "(Optional) Use this variable to enable PM2. The specified file is used as PM2 process entry point" } + +variable "startup_command" { + type = string + default = "" + description = "(Optional) The PM2 file used as PM2 process entry point" +}