Terraform 循环外部输入

terraform loop external input

通过数据源动态导入数据库(通过ansible单独创建)。

命令输出是 terraform 应该接受的列表形式 for_each

data "azurerm_sql_server" "sql_server" {
  name         = "sql-server-mon-test"
  resource_group_name = "ex-net-rg" 
}

data "external" "databases_ids" {
  program = ["sh", "${path.module}/db_id.sh"]
  query = {
    db_rg   = data.azurerm_sql_server.sql_server.resource_group_name
    server_name      = data.azurerm_sql_server.sql_server.name
  }
}

data "azurerm_sql_database" "database" {
  for_each            = toset(data.external.databases_ids.result["name_of_db"])
  name                = each.key
  server_name         = data.azurerm_sql_server.sql_server.name
  resource_group_name = data.azurerm_sql_server.sql_server.resource_group_name
}

Bash代码:

eval "$(jq -r '@sh "export DB_RG=\(.db_rg) SERVER_NAME=\(.server_name)"')"

if [[ -z $DB_RG || -z $SERVER_NAME ]]; then
echo "Required variables DB_RG & SERVER_NAME not set" 1>&2
exit 1
fi

name_of_db=$(az sql db list --resource-group $DB_RG --server $SERVER_NAME --query [*].name 2>/dev/null)

jq -n --arg name_of_db"$name_of_db" '{"name_of_db":$name_of_db}'

unset DB_RG SERVER_NAME name_of_db

exit 0

错误:

 Error: Invalid function argument
 on main.tf line 37, in data "azurerm_sql_database" "database":
      37:   for_each            = toset(data.external.databases_ids.result["name_of_db"])
      data.external.databases_ids.result["name_of_db"] is "\"db1\""

Invalid value for "v" parameter: cannot convert string to set of any single
type.*

az 命令输出示例:

az sql db list --resource-group ex-net-rg  --server sql-server-mon-test --query [*].name
[
  "db1",
  "db2",
  "master"
]

编辑 1:更多调试: Bash 脚本输出:

    {
  "name_of_db": "[\n  \"db1\",\n  \"db2\",\n  \"master\"\n]"
}

在 terraform 代码中添加了本地块以填充状态文件:

locals {
database_name =(jsondecode(data.external.databases_ids.result["name_of_db"]))
}

生成的 tfstate 文件:

"query": {
          "db_rg": "ex-net-rg",
          "server_name": "sql-server-mon-test"
        },
        "result": {
          "name_of_db": "[\n  \"db1\",\n  \"db2\",\n  \"master\"\n]"
        },

您应该在此处添加 jsondecode

for_each            = toset(jsondecode(data.external.databases_ids.result["name_of_db"]))