首页 > 解决方案 > 用户无权担任 IAM 角色

问题描述

我有一个 bash 脚本,它从 CloudFormation 堆栈中提取信息并将其放入 Python 脚本中。Python 脚本旨在连接到 Redshift 数据库、创建表,然后从从 S3 存储桶下载的文件中导入数据。

第一部分工作:

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

这导致必要的字符串去他们需要的地方:

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

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

但是,当我执行 Python 脚本时,我收到以下错误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]
  -----------------------------------------------

错误中提到的admin用户是在创建 Redshift 堆栈时创建的,如果我通过登录查询编辑器通过 Redshift UI 访问数据库,则使用同一帐户不会出错。这种情况的不同之处在于我使用用户名:密码登录,而不是,我猜,假设一个角色。具体来说,错误中的那个。

Redshift 堆栈是使用Thorntech 提供的模板构建的。这在执行时也是成功的。

有什么想法吗?

编辑:我在AWS 开发人员论坛 上发现了一个相同的问题,表明我应该使用逻辑 ID,而不是使用物理资源 ID。在这种情况下,BallotOnlineRS-RawDataBucketAccessRole-xxxxxxxxxxxx我应该只使用RawDataBucketAccessRole. 但是,这会导致相同的错误,不同之处在于逻辑 ID 替换了物理 ID。

EDIT2: 针对 John Rotenstein 关于关联角色的问题,这里是定义集群及其相关组件的部分:

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  

在角色之前定义集群是否重要?我怀疑它没有,因为该角色列在 CF UI 中堆栈的资源选项卡下。

EDIT3: 我发现了另一个类似的问题,但是是针对产品的。OP声明他找到了解决方案。因为他使用了错误的角色进行身份验证。当我为我的问题寻找这条途径时,它似乎并不适用,因为我只有一个角色。

标签: pythonsqlalchemyamazon-redshiftamazon-cloudformation

解决方案


我达到了一个点,我正在向墙上扔东西,看看会粘住什么。最终我得到了它的工作。我不知道的是,我一次进行的最后两项更改中的哪一项解决了问题(或为什么):将Path:属性添加到IAM::Role定义中或将策略与角色定义内联并删除外部策略定义。我最终得到的是(将其与我在上述问题正文中放置的内容进行比较)

  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: '*'

这允许admin用户(在MasterUsername参数中定义)承担角色并访问 S3 存储桶。


推荐阅读