🐛 Типичные ошибки: AWS CLI и Boto3

⚡ Топ-3 ошибки

  • Хардкод ключей — никогда не писать access_key в коде; используй ~/.aws/credentials
  • Неверный регион — S3 бакет создаётся в одном регионе, boto3 подключается к другому
  • An error occurred (InvalidClientTokenId) — ключи неверные или просроченные; перегенерировать через IAM

Ошибка 1: Хардкод IAM Access Keys в коде

Симптом: Ключи прямо в Python-файле или .env-файле, закоммиченном в git.
# bad_example.py — ОПАСНО
import boto3
s3 = boto3.client(
    's3',
    aws_access_key_id='AKIAIOSFODNN7EXAMPLE',  # нельзя!
    aws_secret_access_key='wJalrXUtnFEMI...'   # нельзя!
)
Решение: Настроить aws configure один раз. Boto3 автоматически подхватит ключи из ~/.aws/credentials:
# good_example.py
import boto3
s3 = boto3.client('s3')  # ключи берутся из ~/.aws/credentials
Добавить в .gitignore:
# .gitignore
.aws/
*.pem
.env
*credentials*

Ошибка 2: Unable to locate credentials

botocore.exceptions.NoCredentialsError: Unable to locate credentials
Причина: aws configure не выполнялся, или файл ~/.aws/credentials отсутствует/пуст.
Решение:
# Терминал
aws configure
# Ввести Access Key ID, Secret Access Key, регион, формат

# Проверка
aws configure list
aws s3 ls  # не должно быть ошибки

Ошибка 3: InvalidClientTokenId — неверные ключи

botocore.exceptions.ClientError: An error occurred (InvalidClientTokenId)
when calling the ListBuckets operation: The security token included
in the request is invalid.
Причины:
  • Ключи введены с опечаткой при aws configure
  • Ключи деактивированы или удалены в IAM консоли
  • Используется Secret Key от другого Access Key ID
Решение: Перейти в AWS IAM Console → Users → выбрать пользователя → Security credentials → создать новые Access Keys. Затем:
# Терминал — перенастроить credentials
aws configure

Ошибка 4: Неверный регион для S3 бакета

botocore.exceptions.ClientError: An error occurred (IllegalLocationConstraintException)
when calling the CreateBucket operation: The unspecified location constraint
is incompatible for the region specific endpoint...
Причина: Для региона eu-central-1 нужен CreateBucketConfiguration, а для us-east-1 — нет. Путаница или копирование кода из примера без адаптации.
Решение:
# s3_create_bucket.py
import boto3

s3 = boto3.client('s3', region_name='eu-central-1')

# Для eu-central-1 и любого региона кроме us-east-1:
s3.create_bucket(
    Bucket='my-unique-bucket-name',
    CreateBucketConfiguration={
        'LocationConstraint': 'eu-central-1'
    }
)

# Для us-east-1 — без CreateBucketConfiguration:
# s3.create_bucket(Bucket='my-bucket')

Ошибка 5: Access Denied — недостаточно прав IAM

botocore.exceptions.ClientError: An error occurred (AccessDenied)
when calling the PutObject operation: Access Denied
Причина: IAM-пользователю не назначена политика с нужными разрешениями (например, s3:PutObject).
Решение: В IAM Console → Users → выбрать пользователя → Permissions → Add permissions → добавить нужную политику (например, AmazonS3FullAccess для учебы или более гранулярную политику для продакшена). Затем обновить credentials если нужно.

Ошибка 6: Имя бакета уже занято

botocore.exceptions.ClientError: An error occurred (BucketAlreadyExists)
when calling the CreateBucket operation: The requested bucket name
is not available. The bucket namespace is shared by all users of the system.
Причина: Имена S3 бакетов глобально уникальны — занято другим аккаунтом AWS в любой точке мира.
Решение: Использовать уникальные имена. Хорошая практика — включать ID аккаунта или дату:
# s3_naming.py
import boto3
import boto3.session

# Получить ID аккаунта для уникального имени
sts = boto3.client('sts')
account_id = sts.get_caller_identity()['Account']

bucket_name = f'my-project-{account_id}-eu'
print(f'Создаём бакет: {bucket_name}')

Ошибка 7: EC2 инстанс не доступен по SSH

Симптом: ssh: connect to host X.X.X.X port 22: Connection timed out
Причины:
  • Security Group не открывает порт 22
  • Public IP не назначен (Auto-assign Public IP не включено)
  • Subnet не публичная (нет Internet Gateway в Route Table)
  • Инстанс ещё загружается (подождать 1–2 минуты)
Решение:
  1. Проверить Security Group: правило для порта 22 с вашим IP (My IP в консоли)
  2. Проверить наличие Public IP в описании инстанса
  3. Убедиться, что Route Table subnet содержит маршрут через Internet Gateway (0.0.0.0/0 → igw-xxx)
# Терминал — проверить состояние инстанса
aws ec2 describe-instances \
  --instance-ids i-xxxxxxxxxxxxxxxxx \
  --query 'Reservations[*].Instances[*].[State.Name,PublicIpAddress]' \
  --output table

Ошибка 8: User Data скрипт не выполнился

Симптом: Docker не установлен после запуска инстанса с User Data.
Диагностика: User Data выполняется при первом запуске. Логи:
# На EC2 инстансе (через SSH)
cat /var/log/cloud-init-output.log
cat /var/log/cloud-init.log
Частые причины:
  • Скрипт не начинается с #!/bin/bash
  • Ошибка в скрипте — следующие команды не выполняются
  • Инстанс был запущен без User Data, затем остановлен и перезапущен (User Data выполняется только при первом старте)