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

如何用yq为CloudFormation添加带!Sub函数简写的托管策略ARN?

用yq批量给CloudFormation YAML中的Lambda/ECS角色添加托管策略(保留!Sub简写)

核心问题解决思路

yq默认会把CloudFormation的简写标签(比如!Sub)解析成完整的Fn::Sub嵌套结构,要保留简写格式,得用yq的标签指定语法。同时要覆盖两种场景:角色已有ManagedPolicyArns数组,或者完全没有这个字段。

适用yq版本

确保你用的是mikefarah/yq v4.18+(当前主流的yq版本),旧版本语法差异极大。

具体命令

单文件处理

假设要添加的策略是!Sub "arn:aws:iam::${AWS::AccountId}:policy/YourManagedPolicy",执行以下命令:

yq eval '
(.Resources[] | select(
  .Type == "AWS::IAM::Role" and
  (.Properties.AssumeRolePolicyDocument.Statement[].Principal.Service[] == "lambda.amazonaws.com" or
   .Properties.AssumeRolePolicyDocument.Statement[].Principal.Service[] == "ecs-tasks.amazonaws.com")
)) |= (
  .Properties.ManagedPolicyArns += [{"!Sub": "arn:aws:iam::${AWS::AccountId}:policy/YourManagedPolicy"}] |
  .Properties.ManagedPolicyArns |= unique  # 可选:去重,避免重复添加同一策略
)' your-template.yaml -i

批量处理目录下所有YAML文件

for file in *.yaml; do
  yq eval '
    (.Resources[] | select(
      .Type == "AWS::IAM::Role" and
      (.Properties.AssumeRolePolicyDocument.Statement[].Principal.Service[] == "lambda.amazonaws.com" or
       .Properties.AssumeRolePolicyDocument.Statement[].Principal.Service[] == "ecs-tasks.amazonaws.com")
    )) |= (
      .Properties.ManagedPolicyArns += [{"!Sub": "arn:aws:iam::${AWS::AccountId}:policy/YourManagedPolicy"}] |
      .Properties.ManagedPolicyArns |= unique
    )' "$file" -i
done

命令解释

  1. 定位目标角色:

    • 筛选所有Type为AWS::IAM::Role的资源
    • 进一步匹配信任策略(AssumeRolePolicyDocument)中包含Lambda或ECS任务服务主体的角色
  2. 处理ManagedPolicyArns字段:

    • += []:如果字段已存在则追加新策略,不存在则自动创建数组并添加
    • {"!Sub": "..."}:用这种键值对形式告诉yq保留!Sub简写标签,而非转成Fn::Sub嵌套结构
    • unique:可选操作,防止多次执行命令时重复添加同一策略

效果对比

处理前(无ManagedPolicyArns的角色)

Resources:
  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole

处理后

Resources:
  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - !Sub "arn:aws:iam::${AWS::AccountId}:policy/YourManagedPolicy"

错误情况(未用正确语法时)

如果直接写!Sub "...",yq会输出嵌套结构:

ManagedPolicyArns:
  - Fn::Sub: "arn:aws:iam::${AWS::AccountId}:policy/YourManagedPolicy"

用{"!Sub": "..."}就能避免这个问题。

注意事项

  • 执行命令前一定要备份文件,或者先不加-i参数(直接输出到控制台)验证结果
  • 如果角色的信任策略中Principal.Service是单个值(不是数组),把[]去掉即可(比如.Principal.Service == "lambda.amazonaws.com")
  • 可根据实际需求修改策略ARN和匹配的服务主体

内容的提问来源于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 14:45:40