I am trying to decide the Azure Web application stack based on the input using lookup function, however I am getting below error saying to have only one stack in the application_stack block. However the expectation is java_version line should return null. When I try null for java_version it works fine. There is something wrong in my lookup function syntax ?
terraform plan
╷
│ Error: Invalid combination of arguments
│
│ with azurerm_windows_function_app.example,
│ on functionapp.tf line 67, in resource "azurerm_windows_function_app" "example":
│ 67: application_stack {
│
│ "site_config.0.application_stack.0.powershell_core_version": only one of
│ `site_config.0.application_stack.0.dotnet_version,site_config.0.application_stack.0.java_version,site_config.0.application_stack.0.node_version,site_config.0.application_stack.0.powershell_core_version,site_config.0.application_stack.0.use_custom_runtime`
│ can be specified, but `site_config.0.application_stack.0.java_version,site_config.0.application_stack.0.node_version` were specified.
I want to create a web app with node stack version. Below is the terraform code
variable "applicationstack" {
type = string
default = "node"
}
variable "stack_version" {
type = map
default ={
node = "~14"
java = "8"
}
}
resource "azurerm_resource_group" "example" {
name = "eus-s-test-rg-01"
location = "eastus"
}
resource "azurerm_storage_account" "example" {
name = "eusperftestjs01"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
account_tier = "Standard"
account_replication_type = "LRS"
}
resource "azurerm_service_plan" "example" {
name = "example-app-service-plan"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
os_type = "Windows"
sku_name = "Y1"
}
resource "azurerm_windows_function_app" "example" {
name = "eus-perf-test-js-01"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
storage_account_name = azurerm_storage_account.example.name
storage_account_access_key = azurerm_storage_account.example.primary_access_key
service_plan_id = azurerm_service_plan.example.id
site_config {
application_stack {
node_version = lookup(var.stack_version,var.applicationstack,null)
java_version = lookup(var.stack_version,var.applicationstack,null)
}
}
}
To expand my answer a bit: in both node_version
and java_version
arguments you are using the same lookup:
lookup(var.stack_version,var.applicationstack,null)
From the terraform docs for lookup
built-in function:
lookup
retrieves the value of a single element from a map, given its key.
In other words, you are effectively doing this:
lookup({node="~14", java="8"}, "node", null)
Since the key node
is there in both situations, it will always return a non-null value or "~14"
in your case.
You could try using the ternary operator in terraform for this [1]. The code would have to be changed slightly:
application_stack {
node_version = var.applicationstack == "node" ? var.stack_version.node : null
java_version = var.applicationstack == "node" ? null : var.stack_version.java
}
The other way to fix it, knowing that the two only possible values for keys are node
and java
, you could do something like:
application_stack {
node_version = lookup(var.stack_version, "node", null)
java_version = lookup(var.stack_version, "java", null)
}
However, if you were to use this approach, you would have to assign a different value to the stack_version
variable since the default value has both of the keys. For example, in a terraform.tfvars
file:
stack_version = {
node = "~14"
}
or if you want to deploy a Java-based app:
stack_version = {
java = "8"
}
[1] https://developer.hashicorp.com/terraform/language/expressions/conditionals