如何使用 jq 从 terraform 状态文件中提取特定字段?

Ant*_*ong 2 select json jq terraform

这是 terraform 状态文件的简化 json 文件(我们称之为 dev.ftstate)

{
  "version": 4,
  "terraform_version": "0.12.9",
  "serial": 2,
  "lineage": "ba56cc3e-71fd-1488-e6fb-3136f4630e70",
  "outputs": {},
  "resources": [
    {
      "module": "module.rds.module.reports_cpu_warning",
      "mode": "managed",
      "type": "datadog_monitor",
      "name": "alert",
      "each": "list",
      "provider": "module.rds.provider.datadog",
      "instances": []
    },
    {
      "module": "module.rds.module.reports_lag_warning",
      "mode": "managed",
      "type": "datadog_monitor",
      "name": "alert",
      "each": "list",
      "provider": "module.rds.provider.datadog",
      "instances": []
    },
    {
      "module": "module.rds.module.cross_region_replica_lag_alert",
      "mode": "managed",
      "type": "datadog_monitor",
      "name": "alert",
      "each": "list",
      "provider": "module.rds.provider.datadog",
      "instances": []
    },
    {
      "module": "module.rds",
      "mode": "managed",
      "type": "aws_db_instance",
      "name": "master",
      "provider": "provider.aws",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "address": "dev-database.123456.us-east-8.rds.amazonaws.com",
            "allocated_storage": 10,            
            "password": "",
            "performance_insights_enabled": false,
            "tags": {
              "env": "development"
            },
            "timeouts": {
              "create": "6h",
              "delete": "6h",
              "update": "6h"
            },
            "timezone": "",
            "username": "admin",
            "vpc_security_group_ids": [
              "sg-1234"
            ]
          },
          "private": ""
        }
      ]
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

module.rds内部有很多同级模块instances。我取出其中许多来创建原始数据的简化版本。关键要点:不要假设数组索引在所有情况下都是恒定的。

我想提取password上面示例中的字段。

我的第一次尝试是使用相等检查来提取相关模块

` jq '.resources[].module == "module.rds"' dev.tfstate`
Run Code Online (Sandbox Code Playgroud)

但它实际上只是生成了一个布尔值列表。我没有看到任何关于内置函数的提及,例如 手册filter中的内容jq

然后我尝试访问该字段:

> jq '.resources[].module[].attributes[].password?' dev.tfstate
Run Code Online (Sandbox Code Playgroud)

然后它抛出以下错误

jq: error (at dev.tfstate:1116): Cannot iterate over string ("module.rds")
Run Code Online (Sandbox Code Playgroud)

那么提取价值的最佳方式是什么?希望它只能关注模块password中的属性module.rds

编辑:

我的目的是检测密码是否留在状态文件中。我想确保密码仅存储在 AWS 秘密管理器中。

use*_*693 5

你可以像这样提取你想要的模块。

\n\n
jq \'.resources[] | select(.module == "module.rds")\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

我不确定我是否理解解决方案其余部分的要求。因此,这可能不仅不是做你想做的事情的最佳方式,而且可能不是最好的方式。它可能根本不做你想做的事!

\n\n

如果您知道密码在哪里,则可以执行此操作。

\n\n
jq \'.resources[] | select(.module == "module.rds") | .instances[].attributes.password\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果您不知道密码的确切位置,这是一种查找密码的方法。

\n\n
jq \'.resources[] | select(.module == "module.rds") | .. | .password? | values\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

根据“递归下降”标题下的手册..|.a?,将“在 \xe2\x80\x9cbelow\xe2\x80\x9d 下找到的任何对象中查找对象键 \xe2\x80\x9ca\xe2\x80\x9d 的所有值。 ”

\n\n

values过滤掉空结果。

\n