У меня есть скрипт 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, войдя в редактор запросов, я не получаю ошибку при использовании той же учетной записи. Разница в этой ситуации заключается в том, что я вхожу в систему с именем пользователя: паролем, а не, как мне кажется, принимаю на себя роль. В частности, тот, который в ошибке.
Стек Redshift построен с использованием шаблона , предоставленного Thorntech . Это также успешно при выполнении.
Есть мысли по поводу проблемы?
EDIT:
На форуме разработчиков AWS я обнаружил, что должно быть идентичное, что указывает на то, что вместо использования идентификатора физического ресурса я должен использовать логический идентификатор. В этом случае вместо BallotOnlineRS-RawDataBucketAccessRole-xxxxxxxxxxxx
я должен просто использовать RawDataBucketAccessRole
. Однако это приводит к той же ошибке с разницей в том, что логический идентификатор заменяет физический идентификатор.
EDIT2:
В ответ на вопрос Джона Ротенштейна относительно связывания роли, вот раздел, который определяет кластер и его соответствующие компоненты:
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.
EDIT3:
Я нашел другую, похожую проблему , но для продукта. ОП утверждает, что он нашел решение. То, что он использовал неверную роль для аутентификации. Когда я посмотрел на этот путь для моей проблемы, он, похоже, не подходил, поскольку у меня только одна роль.