首页 > 解决方案 > 如何将 python ElasticSearch 包与 ECS 实例角色一起使用而不是传递凭据?

问题描述

我已经构建了一个在不同时间查询 ElasticSearch 的应用程序。现在我正在将应用程序移动到托管在 ECS 上,我想将我的查询切换为基于实例角色权限而不是我作为环境变量传递的凭据。

根据文档,如果我没有将凭据传递给 Boto3,我应该使用我的实例角色。但是为了使用 python 中的ElasticSearch h 包发送我的查询,我必须传递凭据。有没有办法使用实例角色来做到这一点?

这里的示例代码给了我希望,我只需要传入 `boto3.Session().get_credentials() 函数来检索实例角色凭据。但事实证明,正如我的 aws 管理员所解释的那样,实例角色实际上没有凭据(aws_key、aws_secret_key)。结果,我的代码似乎生成了一个在云上无效的 AWS 密钥,并且只为我的查询返回空值。

有人告诉我,唯一的选择是使用ES Boto3 客户端而不是传递凭据……但是在这个客户端上使用 ES 并不像使用 ElasticSearch python 包接口那么友好。

有没有办法让它在 ElasticSearch 包可以在不传递凭据且仅依赖实例角色权限的情况下查询 ES 的情况下工作?

到目前为止,这是我的代码:

if os.environ.get('LOCAL_DEV')==1:
  AWS_KEY = os.environ['AWS_ACCESS_KEY']
  AWS_SECRET_KEY = os.environ['AWS_SECRET_KEY']
else:
  credentials = boto3.Session().get_credentials() #fails to use instance role
  AWS_KEY=credentials.access_key
  AWS_SECRET_KEY=credentials.secret_key

# It pulls my environment variables when running locally, and when running on the cluster, I need it to use the Instance Role
  
#### below is how I initialize and query with the ElasticSearch package


import elasticsearch as es
from requests_aws4auth import AWS4Auth
from constants import AWS_KEY, AWS_SECRET_KEY

awsauth = AWS4Auth(AWS_KEY, AWS_SECRET_KEY, 'us-west-2', 'es') 
#requires a credential input
host ='search-xxx.xxx.xxxxxxx.xxxx.amazonaws.com'
e_s = es.Elasticsearch(
            hosts=[{'host': host, 'port': 443}],
            http_auth=awsauth,
            use_ssl=True,
            verify_certs=True,
            connection_class=es.RequestsHttpConnection
            )

   res = e_s.search(index='foo', body='bar')
   res = res['hits']['hits']


对此的任何帮助将不胜感激

标签: pythonamazon-web-serviceselasticsearchboto3amazon-ecs

解决方案


我最终做的是使用基于 InstanceRole 权限的 boto3 提取临时凭证。由于这些是临时凭证,因此需要轮换。然而,它奏效了!我被难住了,直到我发现需要在 AWS4Auth 命令中使用临时令牌

temp_access=boto3.Session(region_name='foo-region').get_credentials().access_key
temp_secret=boto3.Session(region_name='foo-region').get_credentials().secret_key
temp_token=boto3.Session(region_name='foo-region').get_credentials().token

########
from requests_aws4auth import AWS4Auth
awsauth=AWS4Auth(temp_access, temp_secret, 'us-west-2', 'es', session_token=temp_token)

es.Elasticsearch(hosts=[{'host':host, 'port':443}],
                 http_auth=awsauth, 
                 use_ssl=True, 
                 verify_certs=True, 
                 connection_class=es.RequestsHttpConnection)

这篇文章很有帮助


推荐阅读