AWS Elasticsearch Service 角色权限

unc*_*eat 5 python amazon-web-services elasticsearch aws-lambda amazon-elasticsearch

我正在尝试从作为附加了 AmazonESFullAccess 策略的角色运行的 Python Lambda 脚本将文档提交到 Elasticsearch 索引。我正在使用 python elasticsearch 库创建请求,并使用 aws_requests_auth 库对它们进行签名。

cred = boto3.session.Session().get_credentials()
es_host = '<elasticsearch-server>'

auth = AWSRequestsAuth(
    aws_access_key=cred.access_key,
    aws_secret_access_key=cred.secret_key,
    aws_host=es_host,
    aws_region='us-east-1',
    aws_service='es')

ES_CLIENT = Elasticsearch(
    host=es_host,
    port=80,
    connection_class=RequestsHttpConnection,
    http_auth=auth)
Run Code Online (Sandbox Code Playgroud)

然后发送批量创建请求,如下所示:

ES_CLIENT.bulk(
    index='test_index',
    body=docs)
Run Code Online (Sandbox Code Playgroud)

由于以下原因,此操作失败:

TransportError(403, u'{"message": "请求中包含的安全令牌无效。" }'): AuthorizationException ...

尽管使用管理员用户访问密钥运行时相同的代码可以工作。

为什么当以具有“完全 ES 访问权限”的角色运行时这些请求会失败?

Sha*_*ler 3

因为 Elasticsearch 是 AWS 的一个独立实体,但有一个版本是由 AWS 托管的,所以 Elasticsearch 似乎并没有像您期望的那样对待 IAM。AWS 有一些尝试,但并不能完全与仅使用access_key 和 Secret_key。它还需要会话令牌。

答案是使用cred.token以及访问密钥和秘密密钥,然后将其传递到您的 AWSRequestsAuth 对象中:

auth = AWSRequestsAuth(
    aws_access_key=cred.access_key,
    aws_secret_access_key=cred.secret_key,
    aws_token=cred.token,
    aws_host=es_host,
    aws_region='us-east-1',
    aws_service='es')
Run Code Online (Sandbox Code Playgroud)