#amazon-web-services #aws-lambda #boto3
Вопрос:
У меня есть код, который вызывает API AWS boto3. Этот код выполняет несколько действий с использованием клиента iam и клиента ec2:
iam_client = boto3.client('iam')
ec2_client = boto3.client('ec2')
Для всех этих вызовов имя роли и имя профиля совпадают: MyExampleName
- Вызов
iam_client.create_instance_profile
для создания нового профиля экземпляра - Вызов
iam_client.create_role
для создания новой роли - Вызовите
iam_client.attach_role_policy
, чтобы прикрепить политику, управляемую AWS, к новой роли - Вызовите
iam_client.add_role_to_instance_profile
, чтобы добавить новую роль в профиль экземпляра - Вызов
ec2_client.associate_iam_instance_profile
, чтобы связать профиль с экземпляром
Но последний вызов завершается ошибкой с таким сообщением, как это:
ИНФОРМАЦИЯ «НЕ УДАЛОСЬ: Произошла ошибка (значение InvalidParameterValue) при вызове операции AssociateIamInstanceProfile: Значение (MyExampleName) для параметра iamInstanceProfile.имя недопустимо. Неверное имя профиля экземпляра IAM, Идентификатор учетной записи: XXXXXXXXXXXXX, Ресурс: EC2 экземпляр: i-78sd976sd6912»
Я только что создал профиль, так как же получается, что вызов associate_iam_instance_profile говорит, что он недействителен?
Ответ №1:
Более удобным подходом было бы полагаться на boto3
официантов, специально созданных для того, чтобы ждать, пока появятся определенные ресурсы.
waiter = client.get_waiter('instance_profile_exists')
waiter.wait(
InstanceProfileName='string',
WaiterConfig={
'Delay': 123,
'MaxAttempts': 123
}
)
Проблема с вашим подходом заключается в том, что вы полагаетесь на предположение, что ресурс будет создан в течение 60 секунд, что может быть не всегда так. В то время как официанты продолжают опрашивать, пока ресурс не станет доступным.
Чтобы узнать больше о доступных официантах https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/iam.html#IAM.Client.get_waiter
Комментарии:
1. Спасибо! Я попробовал это, но обнаружил, что официант возвращается, а последующий вызов клиента EC2 по- прежнему не удается. На шаге 1, когда я создаю профиль, я получаю ответ, содержащий ARN профиля. Я попытался добавить официанта между моими шагами 4 и 5, но вызов на шаге 5 с помощью клиента EC2 все равно не удался. Возможно, мне следует использовать официанта после шага 1 и до шага 4, но это, похоже, не помогает при вызове EC2 в #5. По-прежнему кажется, что это связано с использованием клиента EC2 в сочетании с клиентом IAM.
2. Кроме того, в примере в документации для create_instance_profile говорится: «Следующая команда создает профиль экземпляра с именем Webserver, который готов к присоединению роли, а затем будет связан с экземпляром EC2 «. Я делаю этот звонок, возвращаю ARN в ответе, затем пытаюсь связать его, но получаю ошибку. Похоже, что эта документация неверна-как будто она не сразу готова к связыванию с экземпляром EC2.
3. Я проголосовал, потому что это добавляет полезную информацию, которую все равно нужно учитывать, даже если это не решило мою проблему.
Ответ №2:
Существует небольшая проблема со временем использования как клиента IAM, так и клиента EC2. Профиль, созданный с помощью iam_client
, может не сразу использоваться пользователем ec2_client
. С некоторой логикой повторных попыток имя, похоже, в конечном итоге работает-на самом деле оно не является недействительным, оно просто еще не найдено:
import time
logger.info('Attaching profile: MyExampleName'))
counter = 0
while counter < 60:
try:
ec2_client.associate_iam_instance_profile(IamInstanceProfile={'Name': 'MyExampleName'},
InstanceId='i-78sd976sd6912')
break
except ClientError as err:
if err.response['Error']['Code'] == 'InvalidParameterValue':
counter = counter 1
logger.info('The ec2 client did not find the profile yet; wait 1 second and then try again')
time.sleep(1)
logger.info('Finally worked!')
В следующих журналах показан реальный пример записей журнала, которые показывают, что клиент EC2 в конечном итоге соответствует клиенту IAM:
INFO "Attaching profile: MyExampleName"
INFO "The profile is not found yet; wait 1 second and then try again"
INFO "The profile is not found yet; wait 1 second and then try again"
INFO "The profile is not found yet; wait 1 second and then try again"
INFO "The profile is not found yet; wait 1 second and then try again"
INFO "The profile is not found yet; wait 1 second and then try again"
INFO "The profile is not found yet; wait 1 second and then try again"
INFO "The profile is not found yet; wait 1 second and then try again"
INFO "The profile is not found yet; wait 1 second and then try again"
INFO "The profile is not found yet; wait 1 second and then try again"
INFO "Finally worked!"
Комментарии:
1. Я все равно поддерживаю это, так как вы на правильном пути