我通过在EC2上使用分配的角色,使用了从AWS EC2到GCP Bigquery的Workload Identity,效果很好。
然而,当我通过使用fargate任务角色将Workload Identity从AWS Fargete使用到GCP Bigquery时,它不起作用。
在这种情况下,我应该如何设置工作负载标识?
我使用了下面的库。
implementation(platform("com.google.cloud:libraries-bom:20.9.0"))
implementation("com.google.cloud:google-cloud-bigquery")
Stacktrace在下方有消息
com.google.cloud.bigquery.BigQueryException: Failed to retrieve AWS IAM role.
at com.google.cloud.bigquery.spi.v2.HttpBigQueryRpc.translate(HttpBigQueryRpc.java:115) ~[google-cloud-bigquery-1.137.1.jar!/:1.137.1]
…
at java.base/java.lang.Thread.run(Unknown Source) ~[na:na]
Caused by: java.io.IOException: Failed to retrieve AWS IAM role.
at com.google.auth.oauth2.AwsCredentials.retrieveResource(AwsCredentials.java:217) ~[google-auth-library-oauth2-http-0.26.0.jar!/:na]
…
at com.google.cloud.bigquery.spi.v2.HttpBigQueryRpc.getDataset(HttpBigQueryRpc.java:126) ~[google-cloud-bigquery-1.137.1.jar!/:1.137.1]
... 113 common frames omitted
Caused by: java.net.ConnectException: Invalid argument (connect failed)
at java.base/java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:na]
at com.google.auth.oauth2.AwsCredentials.retrieveResource(AwsCredentials.java:214) ~[google-auth-library-oauth2-http-0.26.0.jar!/:na]
... 132 common frames omitted
我在谷歌云存储(GCS(方面也遇到过类似的问题。
正如Peter所提到的,在AWS Farage任务上检索凭据与在EC2实例上运行代码不同,因此Google SDK无法组成正确的AWS凭据以与Google Workload Identity Federation交换。
我想出了一个变通办法,省去了在"…"中编辑核心文件的麻烦/google/auth/aws.py";通过做两件事:
- 使用boto3获取会话凭据
import boto3
task_credentials = boto3.Session().get_credentials().get_frozen_credentials()
- 设置相关环境变量
from google.auth.aws import environment_vars
os.environ[environment_vars.AWS_ACCESS_KEY_ID] = task_credentials.access_key
os.environ[environment_vars.AWS_SECRET_ACCESS_KEY] = task_credentials.secret_key
os.environ[environment_vars.AWS_SESSION_TOKEN] = task_credentials.token
解释:
我使用的是带有boto3和谷歌云==2.4.0的Python3.9,但如果函数中有以下代码,它应该适用于其他版本的谷歌SDK_get_security_credentials";在类别下";凭证";在";google.auth.aws";包装:
# Check environment variables for permanent credentials first.
# https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html
env_aws_access_key_id = os.environ.get(environment_vars.AWS_ACCESS_KEY_ID)
env_aws_secret_access_key = os.environ.get(
environment_vars.AWS_SECRET_ACCESS_KEY
)
# This is normally not available for permanent credentials.
env_aws_session_token = os.environ.get(environment_vars.AWS_SESSION_TOKEN)
if env_aws_access_key_id and env_aws_secret_access_key:
return {
"access_key_id": env_aws_access_key_id,
"secret_access_key": env_aws_secret_access_key,
"security_token": env_aws_session_token,
}
注意事项:
当在ECS任务中运行代码时,所使用的凭据是临时的(ECS承担任务的角色(,因此您不能像通常建议的那样通过AWS STS生成临时凭据
为什么会出现问题?好吧,由于任务是用临时凭据运行的,它会过期&刷新为了解决这个问题,您可以设置一个后台功能,该功能将每隔5分钟左右再次执行该操作(没有遇到临时凭据过期的问题(。
我遇到了同样的问题,但对于Python代码,无论如何,我认为应该是一样的。您得到的是,在AWS Fargate获得AWS IAM角色与AWS EC2不同,在EC2中,您可以从实例元数据中获得它们,如下所示:
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/s3access
在AWS Faragte:
curl 169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
因此,要绕过这一点,需要做以下工作:
- 将GCP工作负载标识联合身份验证凭据文件内容[wif_cred_file]更改如下:
wif_cred_file["credential_source"]["url"]=f"http://169.254.170.2{AWS_CONTAINER_CREDENTIALS_RELATIVE_URI}"
- 在";python3.8/site packages/google/auth/aws.py";库中的文件[尝试在Java中找到类似的文件],我更新了以下代码:
- 注释此行:
# role_name = self._get_metadata_role_name(request)
- 从
_get_metadata_security_credentials
函数参数中删除role_name
或者,如果您愿意,可以在aws.py文件中更改步骤1,这两种方法都应该可以。
应该就是这样。