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 = "[email protected]"
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
型
调试输出
第1次运行输出:
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
型
第2次运行输出:
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
型
第3次运行输出:无错误
我正在通过Azure DevOps / terraform在Azure中部署一个函数应用程序。
由于资源azurerm_Linux_function_app没有函数的函数键的输出,这是操作组中所需要的,因为否则函数不会通过操作组触发,我必须使用一个技巧将函数键放入操作组。
正如你所看到的,我尝试用az查询获取功能键,并使用此输出将其传递到操作组中。
当我运行这个时,在第一次运行中,我得到了上面显示的输出,这表明没有返回JSON内容。
在第二次运行时,我在shell脚本中添加了两行:
az login --service-principal -u ... -p ... --tenant ...
az account set --subscription "sub-fits-55070-dev-01"
型
当我运行这个的时候,我在运行2中得到了上面显示的错误消息。这向我表明,有一个输出**,但是terraform不能正确处理这个输出。
在第三次运行中,我将shell脚本更改回运行1时的脚本,这意味着再次删除运行2时添加的两行代码。
现在,第三次运行给了我正确的输出,并创建了操作组。
这种行为很奇怪,因为在第三次运行中,我运行的文件与第一次运行中使用的文件完全相同。但是如果没有az login命令,它就不起作用。
这是怎么了?
除此之外,除了我正在使用的方法之外,还有其他方法可以将功能键作为输出吗?
1条答案
按热度按时间zysjyyx41#
看起来问题在于如何在bash循环中返回JSON负载。(您需要将其作为单个JSON对象返回,而不是多个对象)。如果您简化了get_function_key. sh的返回,则可以复制此脚本.如果我们将该脚本更改为:
字符串
脚本输出如下所示:
型
这将返回与您看到的相同的错误消息:
型
如果您更改脚本以更改返回JSON数据的方式,例如:
型
输出如下:
型
Terraform对您返回的有效负载非常满意,您可以利用它。因此,请修改脚本中构建返回JSON对象的方式-不要像现在这样返回多个对象,构建单个对象。
祝你好运!