如何在 AWS IAM 策略上使用 jq?

How to use jq on an AWS IAM policy?

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

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

挑战 - 生成一组允许的动作 (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"
]

您的 jq 管道的最后一部分是:

| .[]

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

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

好吧,这很愚蠢,用 [] 包围我的最终输出就成功了

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