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

利用CloudFormation技巧从账号ID列表生成ARN列表

我之前刚好处理过一模一样的需求,给你分享两个实用的实现方案,看你环境情况选就行:

方案一:使用AWS语言扩展(推荐)

这个方案利用CloudFormation的AWS Language Extensions提供的Fn::Map函数,能直接遍历账号ID列表生成对应的ARN,代码简洁易读,现在大部分AWS区域都支持这个扩展。

完整示例模板

AWSTemplateFormatVersion: '2010-09-09'
# 启用AWS语言扩展,才能使用Fn::Map函数
Transform: AWS::LanguageExtensions

Parameters:
  AccountIds:
    Type: CommaDelimitedList
    Description: 输入需要转换为ARN的AWS账号ID列表(逗号分隔,比如"123456789012,987654321098")
  TargetBucket:
    Type: String
    Description: 示例中要授权的S3桶名称

Resources:
  # 示例:给指定账号授权S3读取权限的桶策略
  AuthorizedBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref TargetBucket
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              # 核心逻辑:用Fn::Map遍历账号ID,逐个生成ARN
              AWS: !Map
                - AccountId  # 遍历过程中每个元素的变量名
                - !Ref AccountIds  # 要遍历的账号ID列表
                - !Sub arn:aws:iam::${AccountId}:root  # 生成ARN的模板
            Action: s3:GetObject
            Resource: !Sub arn:aws:s3:::${TargetBucket}/*

原理说明

!Map(即Fn::Map)是语言扩展提供的遍历函数,它会把AccountIds列表里的每个账号ID代入!Sub模板,自动生成对应的ARN数组,完美适配CloudFormation中需要ARN列表的场景(比如Principal.AWS)。

方案二:兼容旧环境方案(无扩展依赖)

如果你的环境暂时无法启用AWS Language Extensions,可以用Fn::Split+Fn::Join的组合来实现,不过这个方法需要借助一个不会出现在ARN里的临时分隔符:

示例代码片段

# 模板开头无需加Transform
AWSTemplateFormatVersion: '2010-09-09'

Parameters:
  AccountIds:
    Type: CommaDelimitedList
    Description: 输入需要转换为ARN的AWS账号ID列表(逗号分隔)
  TargetBucket:
    Type: String
    Description: 示例中要授权的S3桶名称

Resources:
  AuthorizedBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref TargetBucket
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              AWS: !Split
                - '|SEP|'  # 自定义临时分隔符,确保不会出现在ARN中
                - !Join
                  - '|SEP|'
                  - !Sub
                    - 'arn:aws:iam::${Id}:root'
                    - Id: !Split [",", !Join [",", !Ref AccountIds]]
            Action: s3:GetObject
            Resource: !Sub arn:aws:s3:::${TargetBucket}/*

原理说明

  1. 先用!Join把账号ID列表转成逗号分隔的字符串,再用!Split转回数组(这一步是为了确保处理的是标准数组);
  2. 用!Sub给每个账号ID加上ARN前缀后缀,再用自定义分隔符拼接成字符串;
  3. 最后用!Split按自定义分隔符拆分,得到最终的ARN数组。

不过这个方法不如方案一简洁,而且需要注意临时分隔符不能和ARN内容冲突,所以优先推荐方案一。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:50:44