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

CloudFormation:IAM角色策略Map键的变量替换问题

问题

定义了包含AWSAccountId、OidcProvider等参数的AWS IAM角色CloudFormation模板,在AssumeRolePolicyDocument的Condition/StringEquals部分尝试用!Sub替换Map键中的变量时触发报错,此前尝试!Join和UserData均无效,求助如何在Map键中完成变量替换。

原模板代码:

AWSTemplateFormatVersion: "2010-09-09"

Parameters:
  AWSAccountId:
    Type: String

  OidcProvider:
    Type: String

  AppNamespace:
    Type: String
 
  AppServiceAccountName:
    Type: String


Resources:
  CloudWatchRole:
    Type: "AWS::IAM::Role"
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          -
            Effect: "Allow"
            Principal:
              Federated:
                - !Join ["", [ "arn:aws:iam::", !Ref AWSAccountId, ":oidc-provider/", !Ref OidcProvider ] ]
            Action:
              - "sts:AssumeRoleWithWebIdentity"
            Condition:
              StringEquals:
                !Sub ${OidcProvider}:sub: "system:serviceaccount:${AppNamespace}:${AppServiceAccountName}"

报错信息:

An error occurred (ValidationError) when calling the CreateStack operation: 
Template format error[/Resources/CloudWatchRole/Properties/AssumeRolePolicyDocument/
Statement/0/Condition/StringEquals] map keys must be strings; received a map instead
解决方案

问题出在CloudFormation的函数解析逻辑:直接在Map键的位置使用!Sub时,函数本身会被解析为一个Map对象,而非预期的字符串键,导致类型校验失败。

解决方法是通过!Sub的多行字符串形式,将整个StringEquals的JSON结构作为模板字符串进行变量替换,确保最终生成的是合法的键值对Map。修正后的模板如下:

AWSTemplateFormatVersion: "2010-09-09"

Parameters:
  AWSAccountId:
    Type: String

  OidcProvider:
    Type: String

  AppNamespace:
    Type: String
 
  AppServiceAccountName:
    Type: String


Resources:
  CloudWatchRole:
    Type: "AWS::IAM::Role"
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          -
            Effect: "Allow"
            Principal:
              Federated:
                - !Join ["", [ "arn:aws:iam::", !Ref AWSAccountId, ":oidc-provider/", !Ref OidcProvider ] ]
            Action:
              - "sts:AssumeRoleWithWebIdentity"
            Condition:
              !Sub
                - |
                  {
                    "${OidcProvider}:sub": "system:serviceaccount:${AppNamespace}:${AppServiceAccountName}"
                  }
                - OidcProvider: !Ref OidcProvider
                  AppNamespace: !Ref AppNamespace
                  AppServiceAccountName: !Ref AppServiceAccountName

关键说明

  • 用!Sub的多行模板字符串形式,将Condition的StringEquals部分整体作为JSON字符串进行变量替换,这样CloudFormation会将替换后的结果解析为合法的Map结构。
  • 这种方式避免了直接在Map键位置使用函数导致的类型错误,同时完整保留了变量替换的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 21:10:59