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"
+}