本文介绍了使用带有 CommaDelimitedList 参数的 Cloudformation Join 函数来构建 IAM ARN的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试构建存储桶策略,以允许对 CloudFormation 中的集中式帐户的操作对一系列共享相同模式的其他帐户中的 IAM 角色进行操作 - 即:

I have been trying to build out a Bucket Policy to allow actions on a centralised account in CloudFormation to IAM Roles in a series of other accounts that share the same pattern - I.E:

arn:aws:iam::111111111111:role/my-role

arn:aws:iam::222222222222:role/my-role

我发现了以下示例,它让我很接近,但还不够接近:https://stackoverflow.com/a/50060983/1736704

I have found the following example, which gets me close, but not quite close enough:https://stackoverflow.com/a/50060983/1736704

下面是一个有效的代码示例:

Below is an Example of code that works:

Parameters:
  MyAccounts:
    Type: CommaDelimitedList
    Default: '111111111111,222222222222'
  MyBucket:
    Type: String
    Default: my-bucket

Resources:
  MyBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref MyBucket
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Sid: MyRoleAllow
            Effect: Allow
            Principal:
              AWS: !Split
                - ','
                - !Sub
                  - 'arn:aws:iam::${inner}:role/my-role'
                  - inner: !Join
                    - ':role/my-role,arn:aws:iam::'
                    - Ref: 'MyAccounts'
            Action:
              - s3:PutObject
            Resource: !Sub arn:aws:s3:::${MyBucket}/*

我希望能够做的是将角色名称作为参数.当我尝试这样做时,无论我如何构造 !Join 函数,都会出错.

What I would like to be able to do is make the role name a parameter. When I attempt to do that, no matter how I structure the !Join function, I get errors.

如果我修改上面的代码并且将my-role作为一个名为RoleName的字符串参数,并展开!Join,它会返回一个错误.不起作用的完整修改代码:

If I modify the above code and have my-role as a string parameter called RoleName, and expand the !Join, it returns an error. The full modified code that doesn't work:

Parameters:
  MyAccounts:
    Type: CommaDelimitedList
    Default: '111111111111,222222222222'
  RoleName
    Type: String
    Default: my-role
  MyBucket:
    Type: String
    Default: my-bucket

Resources:
  MyBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref MyBucket
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Sid: MyRoleAllow
            Effect: Allow
            Principal:
              AWS: !Split
                - ','
                - !Sub
                  - 'arn:aws:iam::${inner}:role/my-role'
                  - inner: !Join
                    - ''
                    - - ':role/'
                      - !Ref 'RoleName'
                      - ',arn:aws:iam::'
                      - Ref: 'Accounts'
            Action:
              - s3:PutObject
            Resource: !Sub arn:aws:s3:::${MyBucket}/*

这是我收到的错误消息:模板错误:每个 Fn::Join 对象都需要两个参数,(1) 一个字符串分隔符和 (2) 要加入的字符串列表或返回字符串列表的函数(例如 Fn::GetAZs)加入.

This is the error message I am getting:Template error: every Fn::Join object requires two parameters, (1) a string delimiter and (2) a list of strings to be joined or a function that returns a list of strings (such as Fn::GetAZs) to be joined.

在修改后的代码中,是 Ref: 'Accounts' 导致了问题,但我很困惑为什么,因为它在原始代码中有效.

In the modified code, it is the Ref: 'Accounts' that is causing the issue, but I am confused why, because it works in the original code.


我想使用的输入是:


The inputs I would like to use are:

Parameters:
  MyAccounts:
    Type: CommaDelimitedList
    Default: '111111111111,222222222222'
  RoleName
    Type: String
    Default: my-role
  MyBucket:
    Type: String
    Default: my-bucket

我的预期输出(S3 存储桶策略)如下所示:

My expected output (a S3 Bucket Policy) would look like:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "MyRoleAllow",
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::111111111111:role/my-role",
                    "arn:aws:iam::222222222222:role/my-role"
                ]
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::my-bucket/*"
        }
    ]
}

谁能告诉我我想要实现的目标是否可行?如果是这样,我该如何修改我的代码以使其正常工作?

Can anyone tell me if what I am trying to achieve is possible? If so, how can I modify my code to get it to work?

谢谢

推荐答案

我认为没有明显的方法可以做到这一点.在原Join中:

I think there is no obvious way of doing this. In the original Join:

              - inner: !Join
                - ':role/my-role,arn:aws:iam::'
                - Ref: 'MyAccounts'

':role/my-role,arn:aws:iam::' 部分是 Join 的分隔符.来自文档:

the part ':role/my-role,arn:aws:iam::' is Join's delimiter. From the docs:

对于 Fn::Join 分隔符,您不能使用任何函数.您必须指定一个字符串值.

在新的 join 中,您使用的是空的 分隔符.您必须使用 ':role/my-role,arn:aws:iam::' 作为分隔符,它不能是空字符串 ''.

In your new join you are using empty delimiter. You must use ':role/my-role,arn:aws:iam::' as delimiter, it can't be empty string ''.

理想情况下,您将使用:

Ideally you would use:

              - inner: !Join
                - !Sub ':role/${RoleName},arn:aws:iam::'
                - Ref: 'MyAccounts'

但这也不会起作用,因为 delimiter not 是一个字符串.

but this will also not work due to the delimiter not being a string.

我认为解决此问题的最佳方法是使用基本的查找和替换 ,特别是如果您想在多个模板中使用这种角色和帐户组合模式.

I think the best workaround to this issue would be to use basic find-and-replace macro, especially if you want to use this pattern of role and accounts combo in multiple templates.

这篇关于使用带有 CommaDelimitedList 参数的 Cloudformation Join 函数来构建 IAM ARN的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-23 03:11
查看更多