theillien
theillien

Reputation: 1390

user is not authorized to assume IAM Role

I have a bash script which pulls information from a CloudFormation stack and places it into a Python script. The Python script is intended to connect to a Redshift database, create a table, then import data from a file downloaded from an S3 bucket.

The first part works:

endpoint=$(aws cloudformation describe-stacks --stack-name=BallotOnlineRS --region=us-west-2 \
            --query 'Stacks[0].Outputs[?OutputKey==`RedshiftClusterEndpointAddress`].OutputValue' \
            --output text)

role=$(aws cloudformation describe-stack-resources --stack-name=BallotOnlineRS --region=us-west-2 \
            --logical-resource-id RawDataBucketAccessRole |grep 'PhysicalResourceId' |cut -d: -f2 |sed 's/^ //; s/,//; s/"//g')

sed -i "s/ENDPOINT/${endpoint}/; s/ROLE/${role}/" /tmp/ballotonline_data.py

This results in the the necessary strings going where they need to:

HOST = 'ballotonliners-redshiftcluster-xxxxxxxxxxxx.cgsdneukfjtv.us-west-2.redshift.amazonaws.com'

ARN_CREDENTIALS = 'arn:aws:iam::xxxxxxxxxxx:role/BallotOnlineRS-RawDataBucketAccessRole-xxxxxxxxxxxx

However, when I execute the Python script, I get the following error from sqlalchemy:

sqlalchemy.exc.InternalError: (psycopg2.errors.InternalError_) User arn:aws:redshift:us-west-2:xxxxxxxxxxx:dbuser:ballotonliners-redshiftcluster-1qb2hxkta10t9/admin is not authorized to assume IAM Role arn:aws:iam::xxxxxxxxxxx:role/BallotOnlineRS-RawDataBucketAccessRole-1U56NHFY528VW
DETAIL:
  -----------------------------------------------
  error:  User arn:aws:redshift:us-west-2:xxxxxxxxxxx:dbuser:ballotonliners-redshiftcluster-xxxxxxxxxxxx/admin is not authorized to assume IAM Role arn:aws:iam::xxxxxxxxxxx:role/BallotOnlineRS-RawDataBucketAccessRole-xxxxxxxxxxxx
  code:      8001
  context:   IAM Role=arn:aws:iam::xxxxxxxxxxx:role/BallotOnlineRS-RawDataBucketAccessRole-xxxxxxxxxxxx
  query:     76
  location:  xen_aws_credentials_mgr.cpp:272
  process:   padbmaster [pid=13823]
  -----------------------------------------------

The admin user mentioned in the error is created when the Redshift stack is created and if I access the database through the Redshift UI by logging into the Query Editor, I get no error using the same account. The difference in that situation is that I'm logging in with the username:password rather than, I'm guessing, assuming a role. Specifically, the one in the error.

The Redshift stack is built using a template provided by Thorntech. This also is successful when executed.

Any thoughts on what the issue is?

EDIT: I found what should be an identical issue on the AWS Developer forum that indicates that rather than using the physical resource ID, I should be using the logical ID. In this case, instead of BallotOnlineRS-RawDataBucketAccessRole-xxxxxxxxxxxx I should just use RawDataBucketAccessRole. However, that results in the same error with difference being that the logical ID replaces the physical ID.

EDIT2: In response to John Rotenstein's question regarding associating the role, here is the section that defines the cluster and its relevant components:

Resources:
  RedshiftCluster: 
    Type: AWS::Redshift::Cluster
    Properties: 
      ClusterSubnetGroupName: !Ref RedshiftClusterSubnetGroup
      ClusterType: !If [ SingleNode, single-node, multi-node ]  
      NumberOfNodes: !If [ SingleNode, !Ref 'AWS::NoValue', !Ref RedshiftNodeCount ] #'
      DBName: !Sub ${DatabaseName}
      IamRoles:
        - !GetAtt RawDataBucketAccessRole.Arn
      MasterUserPassword: !Ref MasterUserPassword
      MasterUsername: !Ref MasterUsername
      PubliclyAccessible: true
      NodeType: dc2.large
      Port: 5439
      VpcSecurityGroupIds: 
        - !Sub ${RedshiftSecurityGroup}
      PreferredMaintenanceWindow: Sun:09:15-Sun:09:45
  DataBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub ${DataBucketName}
  RawDataBucketAccessRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement: 
          - 
            Effect: Allow
            Principal:
              Service:
                - redshift.amazonaws.com
            Action:
              - sts:AssumeRole
  RawDataBucketRolePolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: RawDataBucketRolePolicy
      PolicyDocument: 
        Version: 2012-10-17
        Statement:
          - 
            Effect: Allow
            Action: s3:ListAllMyBuckets
            Resource: arn:aws:s3:::*
          - 
            Effect: Allow
            Action: 
              - 's3:Get*'
              - 's3:List*'
            Resource: '*'
          - 
            Effect: Allow
            Action: cloudwatch:*
            Resource: "*"
      Roles:
        - !Ref RawDataBucketAccessRole  

Does it matter that the cluster is defined prior to the role? I suspect it doesn't since the role is listed under the stack's Resources tab in the CF UI.

EDIT3: I found another, similar issue but for a product. The OP states that he found the solution. Being that he was using the wrong role to authenticate with. When I looked into that avenue for my issue, it does not appear to apply since I only have the one role.

Upvotes: 1

Views: 4936

Answers (1)

theillien
theillien

Reputation: 1390

I reached a point where I was throwing things at the wall to see what would stick. Eventually I got it to work. What I don't know is, which of the final two changes that I made at one time solved the problem (or why): adding the Path: property to the IAM::Role definition or placing the policy inline with the role definition and removing the external policy definition. What I ended up with is (compare this to what I've placed in the body of the question above)

  RawDataBucketAccessRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - 
            Effect: Allow
            Principal:
              Service:
                - 'redshift.amazonaws.com'
            Action:
              - 'sts:AssumeRole'
      Path: '/'
      RoleName: RawDataBucketAccessRole
      Policies:
        - 
          PolicyName: RawDataBucketRolePolicy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - 
                Effect: Allow
                Action:
                  - 's3:Get*'
                  - 's3:List*'
                Resource: '*'

This allows the admin user (defined in the MasterUsername parameter) to assume the role and access the S3 bucket.

Upvotes: 1

Related Questions