You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用yq为CloudFormation中IAM角色添加唯一ManagedPolicyArns

解决CloudFormation IAM角色ManagedPolicyArns去重追加问题

我需要给多个CloudFormation.yaml文件里的多个IAM角色添加指定的ManagedPolicyArns,要求只给没有该策略的角色追加,绝对不能重复添加。使用yq v4.27.3版本,试了两个脚本要么重复添加策略,要么完全无法添加,求正确实现方式。


执行命令

yq --from-file add_policy.yq cloudformation.yaml

示例CloudFormation文件(cloudformation.yaml)

AWSTemplateFormatVersion: "2010-09-09"
Parameters:
  MyPrefix:
    Description: MyPrefix
    Type: String
Resources:
  MyRole:
    Type: AWS::IAM::Role
    Properties:
      ManagedPolicyArns:
        - Fn::ImportValue: !Sub "${MyPrefix}-my-policy-arn"
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ecs-tasks.amazonaws.com
                - lambda.amazonaws.com
            Action:
              - sts:AssumeRole
              - sts:TagSession
      Path: /

之前脚本的问题

1. 会重复添加的脚本

判断逻辑错误,未正确识别带!Sub标签的Fn::ImportValue结构,导致误判策略不存在:

( .Resources[] |= 
    select(
        (.Properties.AssumeRolePolicyDocument.Statement[].Principal.Service.[] == "ecs-tasks.amazonaws.com" 
            or .Properties.AssumeRolePolicyDocument.Statement[].Principal.Service.[] == "lambda.amazonaws.com")
        and (.Properties.ManagedPolicyArns | contains([{"Fn::ImportValue": "${MyPrefix}-my-policy-arn"}]) | not ) )
    .Properties.ManagedPolicyArns += {"Fn::ImportValue": "${MyPrefix}-my-policy-arn" | . tag = "!Sub" }
)

2. 完全无法添加的脚本

遍历和判断逻辑错误,直接用.Properties.ManagedPolicyArns[]."Fn::ImportValue"无法匹配带标签的节点,导致所有角色都被误判为已存在策略:

( .Resources[] |= 
    select(
        (.Properties.AssumeRolePolicyDocument.Statement[].Principal.Service.[] == "ecs-tasks.amazonaws.com" 
            or .Properties.AssumeRolePolicyDocument.Statement[].Principal.Service.[] == "lambda.amazonaws.com")
        and (.Properties.ManagedPolicyArns[]."Fn::ImportValue" | contains("${MyPrefix}-my-policy-arn" | . tag = "!Sub") | not) )
    .Properties.ManagedPolicyArns += {"Fn::ImportValue": "${MyPrefix}-my-policy-arn" | . tag = "!Sub" }
)

正确的add_policy.yq脚本

要正确识别带!Sub标签的策略节点,需结合标签匹配和值判断逻辑,脚本如下:

# 定义要添加的目标策略节点
$targetPolicy = {"Fn::ImportValue": "${MyPrefix}-my-policy-arn"} | . tag = "!Sub"

.Resources[] |= 
  # 筛选符合条件的IAM角色:类型为IAM角色且信任策略包含指定服务主体
  select(
    .Type == "AWS::IAM::Role" and
    (.Properties.AssumeRolePolicyDocument.Statement[] | any(
      .Principal.Service[] == "ecs-tasks.amazonaws.com" or 
      .Principal.Service[] == "lambda.amazonaws.com"
    ))
  ) | 
  # 仅当ManagedPolicyArns中不存在目标策略时才追加
  (
    if (.Properties.ManagedPolicyArns | any(
      . tag == "!Sub" and ."Fn::ImportValue" == "${MyPrefix}-my-policy-arn"
    ) | not) then
      .Properties.ManagedPolicyArns += $targetPolicy
    else
      . # 不做任何操作
    end
  )

脚本逻辑说明

  • 先用变量$targetPolicy定义目标策略节点,避免重复编写
  • 先筛选类型为AWS::IAM::Role且信任策略包含ecs-tasks.amazonaws.com或lambda.amazonaws.com的角色,缩小处理范围
  • 判断逻辑:检查ManagedPolicyArns数组中是否存在标签为!Sub且Fn::ImportValue值为${MyPrefix}-my-policy-arn的节点,不存在才追加
  • 使用any()函数遍历数组,确保只要有一个匹配就不执行添加操作,彻底避免重复

测试结果

  • 对已存在目标策略的角色:执行脚本后无变化,不会重复添加
  • 对不存在目标策略的符合条件角色:自动追加指定策略节点

内容的提问来源于stack exchange,提问作者Chip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 16:24:44