ошибка подключения от aws fargete к gcp bigquery с использованием Workload Identity
Я использовал Workload Identity из AWS EC2 в GCP Bigquery, используя назначенную роль в EC2, и все работало нормально.
Однако, когда я использую Workload Identity из AWS Fargete в GCP Bigquery с помощью роли задачи fargate, это не работает.
Как мне настроить идентификатор рабочей нагрузки в этом случае?
Я использовал библиотеки ниже.
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
2 ответа
Я столкнулся с аналогичной проблемой с Google Cloud Storage (GCS).
Как упомянул Питер, получение учетных данных для задачи 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
Объяснение:
я использую Python3.9 с boto3 и google-cloud==2.4.0, однако он должен работать для других версий Google 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 IAM в AWS Fargate отличается от 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 Workload Identity Federation [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)
- Удалять
role_name
из_get_metadata_security_credentials
аргументы функции.
Или, если хотите, вы можете изменить шаг 1 в файле aws.py , оба способа должны подойти.
И это должно быть так.