main.tf
terraform {
required_version = ">= 1.5.5"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=3.69.0"
}
}
}
provider "azurerm" {
features {}
skip_provider_registration = true
subscription_id = "xxxx-xxxxx-xxxxx-xxxxx"
}
provider "azurerm" {
features {}
alias = "sub-fits-55070-dev-01"
skip_provider_registration = true
subscription_id = "xxxx-xxxxx-xxxxx-xxxxx"
}
module "function_app_zis" {
# checkov:skip=CKV_TF_1:Skipped "Ensure Terraform module sources use a commit hash"
providers = {
azurerm = azurerm.sub-fits-55070-dev-01
}
source = "./.."
resource_group_name = "resourcegroup238495723985"
function_app_name = "myfunctionzis238495723985"
location = "westeurope"
use_event_hub_trigger = false
subnet_id = "/subscriptions/xxxx-xxxxx-xxxxx-xxxxx/resourceGroups/rg-network/providers/Microsoft.Network/virtualNetworks/vnet-001/subnets/snet-002"
zip_file_name = "./functionapp/httptrigger/functionapp.zip"
}
resource "azurerm_resource_group" "this" {
provider = azurerm.sub-fits-55070-dev-01
name = "rg-fixture"
location = "westeurope"
}
data "external" "function_key" {
program = ["bash", "${path.module}/get_function_key.sh"]
count = module.function_app_zis.function_app_name != "" ? 1 : 0
depends_on = [module.function_app_zis]
}
resource "azurerm_monitor_action_group" "example" {
provider = azurerm.sub-fits-55070-dev-01
name = "test1mag"
resource_group_name = azurerm_resource_group.this.name
short_name = "auntmary"
email_receiver {
name = "test1email"
email_address = "blabla@test.com"
use_common_alert_schema = true
}
azure_function_receiver {
name = "test1function"
function_app_resource_id = module.function_app_zis.function_app_id
http_trigger_url = "https://${module.function_app_zis.trigger_url}/api/httptrigger?code=${data.external.function_key[0].result["function_key"]}"
function_name = "httptrigger"
use_common_alert_schema = true
}
depends_on = [data.external.function_key]
}
output "function_app_http_trigger_url" {
value = "https://${module.function_app_zis.trigger_url}/api/httptrigger?code=${data.external.function_key[0].result["function_key"]}"
}
get_function_key.sh
#!/bin/bash
APP_NAME="func-myfunctionzis238495723985"
RESOURCE_GROUP="resourcegroup238495723985"
SUBSCRIPTION="sub-fits-55070-dev-01"
FUNCTION_NAME="httptrigger"
# Check if the function app is deployed
for i in {1..30}; do
FUNCTION_KEY=$(az functionapp function keys list --subscription $SUBSCRIPTION --resource-group $RESOURCE_GROUP --name $APP_NAME --function-name $FUNCTION_NAME --query default --output tsv)
if [ "$FUNCTION_KEY" != "" ]; then
echo "{\"function_key\": \"$FUNCTION_KEY\"}"
break
fi
done
Debug Output
Output 1st run:
Error: Unexpected External Program Results
│
│ with data.external.function_key[0],
│ on main.tf line 138, in data "external" "function_key":
│ 138: program = ["bash", "${path.module}/get_function_key.sh"]
│
│ The data source received unexpected results after executing the program.
│
│ Program output must be a JSON encoded map of string keys and string values.
│
│ If the error is unclear, the output can be viewed by enabling Terraform's
│ logging at TRACE level. Terraform documentation on logging:
│ https://www.terraform.io/internals/debugging
│
│ Program: /usr/bin/bash
│ Result Error: unexpected end of JSON input
Output 2nd run:
Error: Unexpected External Program Results
│
│ with data.external.function_key[0],
│ on main.tf line 138, in data "external" "function_key":
│ 138: program = ["bash", "${path.module}/get_function_key.sh"]
│
│ The data source received unexpected results after executing the program.
│
│ Program output must be a JSON encoded map of string keys and string values.
│
│ If the error is unclear, the output can be viewed by enabling Terraform's
│ logging at TRACE level. Terraform documentation on logging:
│ https://www.terraform.io/internals/debugging
│
│ Program: /usr/bin/bash
│ Result Error: invalid character '{' after top-level value
Output 3rd run: no errors
I am deploying a function app in Azure via Azure DevOps / terraform.
As the resource azurerm_linux_function_app has no output for the function key of the function, which is needed in the action group, because otherwise the function is not triggered via the action group, I have to use a trick to get the function key into the action group.
As you can see I try to get the function key with an az query and use this output to get it delivered in the action group.
When I am running this, in the 1st run I am getting the output shown above, which indicates to me that there is no JSON content returned.
In a second run, I added two lines to the shell script:
az login --service-principal -u ... -p ... --tenant ...
az account set --subscription "sub-fits-55070-dev-01"
When I am running this, I get the error message shown above in run 2. This indicates to me, that there is an output, but terraform cannot handle this output properly.
In the third run, I am changing the shell script back to what it was in run 1, which means delete the two lines again that I have added in run 2.
Now, the third run is giving me the correct output and creates the action group.
This behavior is weird, because in the third run I am running exactly the same files that I had already used in run 1. But without the az login command in between, it does not work.
What is wrong here?
Apart from that is there another way to get the function key as an output except the one I am using?