Azure Terraform:外部数据库产生奇怪的错误

r8xiu3jd  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(94)

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命令,它就不起作用。
这是怎么了?
除此之外,除了我正在使用的方法之外,还有其他方法可以将功能键作为输出吗?

zysjyyx4

zysjyyx41#

看起来问题在于如何在bash循环中返回JSON负载。(您需要将其作为单个JSON对象返回,而不是多个对象)。如果您简化了get_function_key. sh的返回,则可以复制此脚本.如果我们将该脚本更改为:

#!/bin/bash
echo "{\"function_key\": \"BATMAN\"}"
echo "{\"function_key2\": \"BATMAN\"}"

字符串
脚本输出如下所示:

#sh get_function_key.sh
{"function_key": "BATMAN"}
{"function_key2": "BATMAN"}


这将返回与您看到的相同的错误消息:

│   on main.tf line 2, in data "external" "function_key":
│    2:     program    = ["bash", "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


如果您更改脚本以更改返回JSON数据的方式,例如:

#!/bin/bash
echo "{\"function_key1\": \"BATMAN\", \"function_key2\": \"ROBIN\"}"


输出如下:

sh get_function_key.sh 
{"function_key1": "BATMAN", "function_key2": "ROBIN"}


Terraform对您返回的有效负载非常满意,您可以利用它。因此,请修改脚本中构建返回JSON对象的方式-不要像现在这样返回多个对象,构建单个对象。
祝你好运!

相关问题