我正在尝试使用 cloudformation 在 AWS Glue/Athena 中创建表。但是,我在 Cloudformation Events 面板中遇到以下错误:
未导入的账户不支持跨账户访问 雅典娜目录到胶水。请参考文档: https://docs.aws.amazon.com/athena/latest/ug/glue-upgrade.html (服务:AWSGlue;状态代码:400;错误代码: 访问拒绝异常;请求 ID:
;代理:空)
(我已经删除了Request-ID)
我点击了该链接,这是有关如何升级以在 Athena 中使用 Glue 数据目录的信息。我认为这不是我面临的实际问题。但是,我确保 IAM 权限按照指南正确,但最后一步显示“在 Athena 控制台中选择升级”,但该步骤不存在。我只能假设这意味着这已经完成了,因为我已经在 Athena 中使用了 Glue
在 AWS 中,我有一个主帐户(我在控制台中使用它,具有非常广泛的权限)和一个用户帐户(我管理和控制 IAM 权限,主要用于通过 AWS-CLI、boto3 等进行编程访问)。 ..).
我的主(控制台)帐户创建了当前在 Glue/Athena 中的所有内容。但是,我的本地(用户)帐户可以访问 Glue 中的所有内容(例如
{"Effect":"Allow", "Action":["glue:*","athena:*","s3:*"], "Resource":"*"}
)。我通过几种方式测试了这一点
从我的本地帐户,我可以列出胶水目录:
>aws athena list-data-catalogs
{
"DataCatalogsSummary": [
{
"CatalogName": "AwsDataCatalog",
"Type": "GLUE"
}
]
}
我还可以列出我尝试访问的数据库中的所有表:
aws glue get-tables --database-name <DBNAME>
我能够使用 cli 创建一个虚拟表:
aws glue create-table --database-name [[DBNAME]] --table-input "Name:TestTable"
(再次,我删除了数据库名称):
通过谷歌搜索上述错误,可以找到有关如何设置跨帐户访问的说明,我通过确保以下内容位于我的 Glue 目录设置权限中(经过适当审查)来完成此操作:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::<ACCOUNTID>:user/<Local Username>"
]
},
"Action": "glue:*",
"Resource": [
"arn:aws:glue:us-east-1:<ACCOUNTID>:catalog",
"arn:aws:glue:us-east-1:<ACCOUNTID>:database/*",
"arn:aws:glue:us-east-1:<ACCOUNTID>:table/*"
]
}
]
}
联系 AWS 支持后,我找到了解决方案,因此我将其发布在这里,以防其他人将来遇到此问题。 CatalogId 是 AccountID,而不是 Athena 控制台中显示的目录名称。解决方案是将模板中的
CatalogId
替换为!Sub '${AccountId}'
。例如:
GlueTable:
Type: AWS::Glue::Table
Properties:
CatalogId: !Sub '${AWS::AccountId}'
DatabaseName: !Sub 'db_{BucketName}'
TableInput:
Name: 'tbl_{LocalName}'
Description: !Sub 'Glue Table for {LocalName}'
....
我在使用boto3时遇到了这个错误。使用 AWS 账户 ID 对我有用。这就是我的函数最终的样子。
def create_catalog_database():
# Create a Glue client
session = boto3.session.Session()
client = session.client(
service_name='glue',
region_name=os.getenv("AWS_REGION")
)
try:
response = client.create_database(
CatalogId=ACCOUNT_ID,
DatabaseInput={
"Name": CATALOG_DB
}
)
except client.exceptions.AlreadyExistsException:
logging.info(f"Database {DEST_BUCKET_ARN} already exits!")
response = None
return response