How to allow both explicit role ARNs and wildcard roles (or even all roles in account) in IAM principal cloudformation template mapping?

Viewed 263

I have a role that I want to give AssumeRole permissions to depending on what stage is being deployed to. This 90% works, but I'm trying to wildcard one part and it's not working as I need it to.

In my mappings I have something like this:

  Mappings:
    TestRoleMapping:
      us-east-1:
        beta: ['arn:aws:iam::11111111111:role/somePrefix-blah-TestInvocationRole', 'arn:aws:iam::2222222222:role/TestInvocationRole']
        prod: ..... etc

Then I use the mapping here:

  Resources:
    SomeReadRole:
      Type: AWS::IAM::Role
      Properties:
        RoleName: { Fn::Sub: "${ApplicationName}-read-role" }
        AssumeRolePolicyDocument:
          Statement:
            - Action: [ 'sts:AssumeRole' ]
              Effect: Allow
              Principal:
                AWS: !FindInMap
                  - TestRoleMapping
                  - !Ref 'AWS::Region'
                  - !Ref Stage
          Version: '2012-10-17'
        Policies:
          - PolicyDocument:
              Statement:
                - Action: [ 's3:Get*' ]
                  Effect: Allow
                  Resource: '*'
              Version: '2012-10-17'
            PolicyName: "lambdaPolicy"

When I deploy this, it works fine since I am using all hardcoded roles. However, I want to allow any role in account 11111111111 to have permissions or (even better) any role that ends in "TestInvocationRole". I've tried replacing the string in the mapping with 'arn:aws:iam::11111111111:role/*-TestInvocationRole' or just 'arn:aws:iam::11111111111:role/*' but it says the principal is invalid. I had read that we could put wildcards in any segment of the ARN, but I'm guessing I'm misusing it in this context.

How can I get the role to give permissions to both hardcoded roles and wildcarded roles?

2 Answers

Since, apparently, the Principal itself can't have any wildcards in it, I ended up trying something like this:

        AssumeRolePolicyDocument:
          Statement:
            - Action: [ 'sts:AssumeRole' ]
              Effect: Allow
              Principal:
                AWS: '*'
              Condition:
                StringLike: { "aws:PrincipalArn" : !FindInMap [ TestRoleMapping, !Ref 'AWS::Region', !Ref Stage ] }

and included the wildcards in the role mapping as I had originally intended:

  Mappings:
    TestRoleMapping:
      us-east-1:
        beta: ['arn:aws:iam::11111111111:role/somePrefix-*-TestInvocationRole', 'arn:aws:iam::2222222222:role/TestInvocationRole']
        prod: ....

It seems to work. However, I get warnings in the IAM console about the Principal being "*" and I'm not sure if it's best practice. Still open to better ideas.

Related