Использование функции Cloudformation Join с параметром CommaDelimitedList для создания ARN-объектов IAM - PullRequest
2 голосов
/ 30 марта 2020

Я пытался создать политику Bucket, чтобы разрешить действия с централизованной учетной записью в CloudFormation для ролей IAM в ряде других учетных записей, использующих тот же шаблон - IE:

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

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

Я нашел следующий пример, который приближает меня, но не совсем близко: { ссылка }

Ниже приведен пример кода, который работает:

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, я получаю ошибки.

Если я изменяю приведенный выше код и в качестве строкового параметра RoleName указываю my-role, а затем раскрываю !Join возвращает ошибку. Полный измененный код, который не работает:

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}/*

Это сообщение об ошибке, которое я получаю: 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', что вызывая проблему, но я запутался почему, потому что он работает в исходном коде.

Редактировать:
Входные данные, которые я хотел бы использовать:

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

Мой ожидаемый вывод (S3 Bucket Policy) будет выглядеть так:

{
    "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/*"
        }
    ]
}

Может кто-нибудь сказать мне, возможно ли то, что я пытаюсь достичь? Если да, как я могу изменить свой код, чтобы он заработал?

Спасибо

1 Ответ

1 голос
/ 31 марта 2020

Я думаю, что нет очевидного способа сделать это. В оригинале Join:

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

часть ':role/my-role,arn:aws:iam::' является разделителем Join * . Из документов:

Для разделителя Fn :: Join нельзя использовать какие-либо функции. Вы должны указать строковое значение .

В вашем новом join вы используете пустой разделитель . Вы должны использовать ':role/my-role,arn:aws:iam::' в качестве разделителя, это не может быть пустой строкой ''.

В идеале вы должны использовать:

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

, но это также не будет работать из-за delimiter не , являющийся строкой.

Я думаю, что лучшим решением этой проблемы было бы использование basi c find-and-replace macro , особенно если вы хотите использовать эту комбинацию ролей и учетных записей в нескольких шаблонах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...