首页 > 解决方案 > 如何在 AWS IAM 策略上使用 jq?

问题描述

问题- 为什么 jq 生成带有值的行,而不是生成内置的 json 数组?(我试过使用[.[]]没有成功)

代码片段@ jqplay.org - https://jqplay.org/s/IDhVa5KID8

挑战- 生成允许的Action数组( Effect == Allow)。

IAM 政策(输入)

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": "cloudformation:UpdateStack",
            "Resource": "arn:aws:cloudformation:eu-west-1:123456789012:stack/sokker-stack-dev/*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "lambda:UpdateFunctionConfiguration",
                "lambda:InvokeFunction"
            ],
            "Resource": "arn:aws:lambda:eu-west-1:123456789012:function:sokker-api-dev-GetApiKeyValueFunction-MYDISTRIBID",
            "Effect": "Allow"
        },
        {
            "Action": [
                "cloudfront:GetDistribution",
                "cloudfront:UpdateDistribution"
            ],
            "Resource": "arn:aws:cloudfront::*:distribution/MYDISTRIBID",
            "Effect": "Allow"
        },
        {
            "Action": [
                "apigateway:GET",
                "apigateway:HEAD",
                "apigateway:OPTIONS",
                "apigateway:PUT",
                "iam:GetRole",
                "iam:PassRole",
                "lambda:GetFunctionConfiguration"
            ],
            "Resource": "*",
            "Effect": "Allow"
        }
    ]
}

我的解决方案(不够好):

jq '.Statement | map(select(.Effect == "Allow"))[].Action | if type == "string" then . else .[] end' iampolicy.json

我的解决方案的输出:

# Why is it a list of values? Why isn't it a json array?
"cloudformation:UpdateStack"
"lambda:UpdateFunctionConfiguration"
"lambda:InvokeFunction"
"cloudfront:GetDistribution"
"cloudfront:UpdateDistribution"
"apigateway:GET"
"apigateway:HEAD"
"apigateway:OPTIONS"
"apigateway:PUT"
"iam:GetRole"
"iam:PassRole"
"lambda:GetFunctionConfiguration"

期望的输出:

[
  "cloudformation:UpdateStack",
  "lambda:UpdateFunctionConfiguration",
  "lambda:InvokeFunction",
  "cloudfront:GetDistribution",
  "cloudfront:UpdateDistribution",
  "apigateway:GET",
  "apigateway:HEAD",
  "apigateway:OPTIONS",
  "apigateway:PUT",
  "iam:GetRole",
  "iam:PassRole",
  "lambda:GetFunctionConfiguration"
]

标签: arraysamazon-web-servicesstreamjqamazon-iam

解决方案


jq 管道的最后一部分是:

| .[]

这会导致您不想要的流。因此,一种解决方案是将整个表达式括在方括号中;几个更好的选择之一是:

.Statement
| [.[]
   | select(.Effect == "Allow")
   | .Action
   | if type == "string" then . else .[] end ]

推荐阅读