8
votes

I am trying to define a trust relationship policy document between a role and a user in cloudformation (yaml).

For specifying the ARN of the user in the role's AssumeRolePolicyDocument, I want to reference the ARN from the actual cloudformation resource, instead of having to construct the ARN string.

But, it doesn't work. When I use !Ref rUser, I get an error when creating the cloudformation stack "invalid principal in policy".

When I just paste the ARN string as the value, it works. Is it because !Ref rUser returns a user object type and does not evaluate to a string? If so, how can I reference the ARN from the resource?

Code:

  rUser:
    Type: "AWS::IAM::User"
    Properties:
      UserName: "my_user"

  rRole:
    DependsOn: rRole
    Type: "AWS::IAM::Role"
    Properties:
      RoleName: "my_role"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          -
            Effect: "Allow"
            Principal:
              AWS:
                # this does not work, gives error "Invalid Principal in policy"
                - !Ref rUser
                # this does work (just hard coding the ARN string):
                # - "arn:aws:iam::111111111111:user/my_user"
            Action:
              - "sts:AssumeRole"
1

1 Answers

17
votes

Just figured it out ... quite simple using the GetAtt function:

  rRole:
    DependsOn: rRole
    Type: "AWS::IAM::Role"
    Properties:
      RoleName: "my_role"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          -
            Effect: "Allow"
            Principal:
              AWS:
                - !GetAtt rExternalUser.Arn  # use the GetAtt function
            Action:
              - "sts:AssumeRole"