Как работать с S3-совместимым объектным хранилищем через AWS CLI: загрузка, синхронизация и права доступа 

Валерий Волков

Время прочтения 38 минут

Чтобы подключить AWS CLI к S3-совместимому Object Storage стороннего провайдера, нужны четыре основных параметра:

  • Access Key;
  • Secret Key;
  • endpoint;
  • регион.

Лучше сразу создать отдельный профиль: aws configure --profile storage

Проверить подключение можно безопасной командой чтения:

    aws s3 ls \
--endpoint-url https://s3.example-provider.com \
--profile storage

Создать bucket:

    aws s3 mb s3://my-bucket \
--endpoint-url https://s3.example-provider.com \
--profile storage

Загрузить файл:

    aws s3 cp ./file.txt s3://my-bucket/file.txt \
--endpoint-url https://s3.example-provider.com \
--profile storage

Скачать его обратно:

    aws s3 cp s3://my-bucket/file.txt ./file.txt \
--endpoint-url https://s3.example-provider.com \
--profile storage

Синхронизировать каталог:

    aws s3 sync ./data s3://my-bucket/data/ \
--endpoint-url https://s3.example-provider.com \
--profile storage

Перед использованием --delete сначала проверьте результат через --dryrun:

    aws s3 sync ./data s3://my-bucket/data/ \
--delete \
--dryrun \
--endpoint-url https://s3.example-provider.com \
--profile storage

Если AWS CLI возвращает ошибку, проверяйте по порядку: endpoint, профиль и credentials, регион, системное время, права policy и addressing style.

Для production не храните Secret Key прямо в скриптах, используйте отдельные service accounts с минимальными правами и заранее продумайте ротацию ключей.

Что такое S3-совместимое Object Storage и чем оно отличается от обычного диска

Добро пожаловать!

Сегодня разберем одну из тех технологий, которые часто используют буквально каждый день, но при этом не всегда до конца понимают, что именно происходит под капотом.

Речь про S3-совместимое объектное хранилище.

На первый взгляд всё выглядит очень знакомо: есть файлы, есть что-то похожее на папки, можно загружать данные, скачивать их обратно и даже синхронизировать целые каталоги.

Из-за этого возникает естественная мысль: «Ну то есть это просто удаленный диск?»

Не совсем.

Object Storage устроено иначе, чем обычная файловая система, сетевой диск или раздел на VPS. И это различие важно, потому что именно оно объясняет почти всё остальное: почему здесь появляются bucket, object key, endpoint, подписи запросов и отдельные правила доступа.

В этой статье мы будем работать через AWS CLI, но подключаться не обязательно к S3 от Amazon . Наша задача шире — понять, как использовать S3-совместимое хранилище стороннего провайдера через собственный endpoint.

То есть в итоге мы научимся:

  • Подключаться к хранилищу через AWS CLI;
  • Работать с отдельными профилями;
  • Создавать и просматривать bucket;
  • Загружать и скачивать объекты;
  • Синхронизировать каталоги;
  • Управлять доступом;
  • Диагностировать ошибки вроде AccessDenied и SignatureDoesNotMatch.

Но прежде чем переходить к командам, стоит нормально разобраться с самой моделью хранения.

Почему Object Storage — не файловая система

Обычная файловая система строится вокруг каталогов, файлов и иерархии.

Например: /home/user/photos/cat.jpg

Тут есть:

  • Каталог /home;
  • Внутри него подкаталог user;
  • Затем photos;
  • И уже там файл cat.jpg.

Файловая система действительно знает, что каталоги существуют как отдельные сущности.

У объектного хранилища логика другая.

В S3-подобной модели данные хранятся как объекты, а каждый объект имеет уникальный ключ.

Например: photos/cat.jpg может выглядеть как путь, но технически это всего лишь строка, которая является ключом объекта.

То есть объектное хранилище не обязано воспринимать photos/ как настоящую директорию.

Это скорее префикс.

Именно поэтому можно встретить объект backup/2026/09/database.sql, даже если никакие отдельные каталоги backup, 2026 или 09 заранее не создавались.

Для человека интерфейс может показывать это как папки, потому что так удобнее воспринимать структуру. Но на уровне API чаще всего речь идет просто о ключах с общими префиксами.

Это одна из главных особенностей Object Storage.

Отсюда вытекают и другие отличия.

Например, обычный диск удобно использовать для:

  • Файлов, к которым приложение обращается постоянно;
  • Баз данных;
  • Системных каталогов;
  • Рабочих директорий;
  • Файлов с частыми мелкими изменениями.

Object Storage чаще используют для:

  • Резервных копий;
  • Архивов;
  • Изображений;
  • Видео;
  • Документов;
  • Статических файлов;
  • Логов;
  • Больших наборов данных.

Почему?

Потому что модель «объект целиком по ключу» отлично подходит для хранения данных, которые нужно надежно положить, получить и раздать через API. Как следствие, удобнее делать stateless-инфраструктуру, когда приложение не использует для данных локальные каталоги, а использует S3-сервис. Это облегчает горизонтальное масштабирование и упрощает микросервисную архитектуру.

Но она не пытается вести себя как локальная файловая система со всеми её привычными операциями.

А можно подключить S3 как обычную файловую систему?

Технически — да. Для этого существуют инструменты вроде s3fs, которые позволяют смонтировать S3-совместимое хранилище в Linux и обращаться к объектам через привычный путь в файловой системе.

Но важно понимать, что настоящий файловый диск из S3 при этом не появляется. s3fs работает через FUSE и преобразует файловые операции в запросы к S3 API. Поэтому привычные для локальной файловой системы действия могут работать иначе, медленнее или требовать дополнительных запросов к Object Storage.

Из-за этого такой вариант обычно не используют как полноценную замену локальному диску для баз данных, активно изменяемых файлов или приложений, которые рассчитывают на обычную POSIX-файловую систему. Он встречается скорее в legacy-сценариях, миграциях и случаях, когда существующее приложение трудно быстро переделать под нативную работу с S3 API.

Для новых приложений обычно надежнее работать с Object Storage как с объектным хранилищем: обращаться к bucket и object key через S3 API, AWS CLI или SDK.

Что такое bucket, object и key

Чтобы дальше не путаться, разберем три основных термина.

Bucket

Bucket — это верхнеуровневый контейнер для объектов.

Например: my-backups или site-media

Можно условно представить bucket как отдельное пространство хранения.

Но bucket — не просто обычная папка.

На его уровне могут задаваться:

  • Правила доступа;
  • Регион;
  • versioning;
  • lifecycle;
  • Политики;
  • Ограничения;
  • Настройки публичности.

Набор возможностей зависит от конкретного S3-совместимого провайдера.

Object

Object — это собственно данные, которые мы загрузили.

Например: report.pdf или database.sql.gz

Объект обычно состоит не только из содержимого файла, но и из метаданных.

То есть S3 хранит не просто «набор байтов», а объект с дополнительной информацией.

Key

Key — это уникальное имя объекта внутри bucket.

Например: backups/db.sql или images/2026/avatar.png

Ключ может выглядеть как обычный путь, но это всё равно строка.

Именно по ключу объект находится внутри bucket.

Если у нас есть:

    Bucket: my-backups
Key: daily/postgres.sql.gz

то условный адрес объекта можно представить как: s3://my-backups/daily/postgres.sql.gz

Эта запись часто встречается в AWS CLI.

Например:

    aws s3 cp backup.sql.gz s3://my-backups/daily/backup.sql.gz

Здесь my-backups — bucket, а daily/backup.sql.gz — key.

Именно это понимание потом сильно помогает при sync, cp --recursive и работе с префиксами.

Что означает «S3-compatible»

Теперь самое интересное.

S3 — это сервис Amazon Simple Storage Service.

Со временем его API стал настолько распространенным, что множество других облачных провайдеров начали реализовывать совместимый интерфейс.

Отсюда и появилось выражение: S3-compatible Object Storage.

То есть стороннее хранилище старается поддерживать API и модель взаимодействия, совместимые с Amazon S3.

Благодаря этому один и тот же клиент может работать с разными провайдерами.

Например, AWS CLI изначально создан для AWS, но при правильной настройке может отправлять запросы и в другое S3-совместимое хранилище.

Это удобно, потому что не нужно осваивать отдельную утилиту под каждого провайдера.

Можно использовать привычные команды:

aws s3 ls

aws s3 cp

aws s3 sync

и просто указать другой endpoint.

Но слово compatible не означает: «Это 100% точная копия Amazon S3 со всеми функциями и поведением».

У разных провайдеров могут отличаться:

  • Поддержка ACL;
  • bucket policy;
  • versioning;
  • object lock;
  • lifecycle rules;
  • Регионы;
  • Ограничения имен;
  • Способ формирования адресов;
  • Некоторые API-возможности.

Поэтому S3-compatible — это скорее совместимость на уровне основного API и популярных операций, а не обещание полной идентичности.

Это особенно важно при переносе сложной инфраструктуры между провайдерами.

Простой cp обычно работает без проблем.

А вот редкие настройки вроде специфических bucket policies могут вести себя иначе.

Почему у стороннего провайдера свой endpoint

У Amazon S3 есть собственные адреса API.

У стороннего провайдера инфраструктура другая, поэтому запросы должны идти уже на его серверы.

Для этого используется endpoint.

Endpoint — это адрес API, к которому подключается клиент.

Например: https://s3.example-provider.com или https://object-storage.example.net

И вот здесь появляется ключевое различие между обычной работой с AWS и S3-compatible хранилищем.

Если выполнить: aws s3 ls без дополнительной настройки, AWS CLI по умолчанию ориентируется на инфраструктуру Amazon.

А нам нужно сказать: «Используй тот же S3 API, но отправляй запросы вот сюда».

Для этого применяется: --endpoint-url

Например:

    aws s3 ls \
--endpoint-url https://s3.example-provider.com

Именно endpoint определяет, куда физически уйдет API-запрос.

При этом Access Key и Secret Key определяют уже другую вещь — кто именно отправляет запрос.

Это важно разделять.

Условно:

Что За что отвечает 
Endpoint Куда отправляется запрос 
Access Key Какая учетная запись используется 
Secret Key Чем подписывается запрос 
Region Как формируется часть запроса и подписи 
Bucket С каким контейнером работаем 
Key С каким объектом внутри bucket работаем 

Именно из-за этого ошибка endpoint и ошибка ключей выглядят по-разному.

Если endpoint вообще недоступен, AWS CLI не сможет установить соединение.

Если endpoint правильный, но ключи неверны, запрос уже дойдет до сервера, а тот ответит ошибкой авторизации.

Дальше как раз разберем, как AWS CLI формирует такие запросы, зачем нужны Access Key и Secret Key, что такое Signature Version 4 и почему даже системное время сервера может неожиданно повлиять на авторизацию.

Как AWS CLI подключается к S3-совместимому хранилищу

Снаружи всё выглядит просто: мы вводим команду вроде: aws s3 ls и получаем список bucket.

Но между вводом команды и ответом сервера происходит несколько важных вещей. CLI должен понять, куда отправить запрос, какими учетными данными его подписать, какой регион учитывать и где вообще взять все эти параметры.

Именно поэтому при работе со сторонним S3-совместимым хранилищем чаще всего возникают не проблемы с самой командой cp или sync, а ошибки в endpoint, ключах или подписи запроса.

Зачем нужен собственный endpoint

У AWS CLI есть естественное ожидание: если ничего не уточнять, он будет работать с инфраструктурой Amazon.

Но сторонний провайдер — это другая инфраструктура, другой API-адрес и, возможно, другой регион.

Поэтому нужно явно указать endpoint.

Например: https://s3.example-provider.com

Endpoint — это адрес, куда AWS CLI отправляет S3-запросы.

Если использовать:

    aws s3 ls \
--endpoint-url https://s3.example-provider.com

CLI не меняет саму логику S3-команды. Он просто перенаправляет запрос на другой сервер.

Это и есть одна из сильных сторон S3-совместимости: клиент остается тем же, меняется только точка подключения.

Endpoint особенно важно не путать с адресом конкретного bucket.

Обычно endpoint — это адрес API сервиса, а bucket уже указывается отдельно: s3://my-bucket

В зависимости от провайдера запрос может затем формироваться в одном из вариантов: https://s3.example.com/my-bucket/object.txt или https://my-bucket.s3.example.com/object.txt

К этому различию мы еще вернемся, когда будем разбирать path-style и virtual-hosted-style запросы.

Как работают Access Key и Secret Key

Endpoint отвечает на вопрос: Куда отправить запрос?

Но хранилище еще должно понять, кто именно обращается к API.

Для этого используются две связанные учетные величины:

  • Access Key ID;
  • Secret Access Key.

Access Key можно условно представить как идентификатор учетной записи или сервисного пользователя.

Он не является секретом в том же смысле, что пароль, но всё равно не стоит разбрасывать его без необходимости.

Secret Key — уже чувствительный секрет.

Именно он используется для формирования криптографической подписи запроса.

При этом AWS CLI не отправляет Secret Key в открытом виде вместе с запросом.

Вместо этого он использует его как входные данные для вычисления подписи.

Сервер со своей стороны знает соответствующий секрет и может проверить, что подпись корректна.

Это важно, потому что схема не сводится к: логин + пароль в привычном веб-смысле.

Здесь каждый API-запрос подписывается.

Условно можно представить это так: «Я — пользователь с Access Key X. Вот запрос, который я отправляю. А вот криптографическая подпись, которая доказывает, что этот запрос сформирован обладателем правильного Secret Key».

Именно поэтому потеря Secret Key критична.

Если он утек, злоумышленник потенциально сможет подписывать запросы от имени вашей учетной записи до тех пор, пока ключ не будет отозван или заменен.

Что такое Signature Version 4

В большинстве современных S3-совместимых систем используется AWS Signature Version 4, или сокращенно SigV4.

Это механизм подписи API-запросов.

AWS CLI берет несколько элементов запроса:

  • HTTP-метод;
  • Путь;
  • query-параметры;
  • Заголовки;
  • Время;
  • Регион;
  • Имя сервиса;
  • Хэш содержимого.

Из этого формируется каноническое представление запроса.

Затем на основе Secret Key вычисляется подпись.

В итоге сервер получает не просто GET /bucket/file.txt, а подписанный запрос с дополнительными заголовками авторизации.

Смысл SigV4 в том, что сервер может проверить сразу несколько вещей:

  • Кто отправил запрос;
  • Не изменился ли запрос по дороге;
  • Соответствует ли подпись конкретному региону и сервису;
  • Не слишком ли старый запрос.

Именно поэтому ошибка в seemingly unrelated параметре может привести к: SignatureDoesNotMatch

Например, если endpoint правильный, а регион в конфигурации не совпадает с тем, который ожидает S3-провайдер, подпись может формироваться иначе.

То же самое может произойти, если клиент и сервер по-разному интерпретируют путь или host.

Это одна из причин, почему S3-compatible не всегда означает полное отсутствие нюансов.

Почему системное время влияет на авторизацию

Вот один из тех фактов, которые легко не учитывать.

Подписанный запрос содержит время.

Это сделано специально: сервер не должен принимать один и тот же корректно подписанный запрос бесконечно долго.

Поэтому если системные часы сильно отстают или спешат, сервер может решить, что запрос слишком старый или вообще пришел «из будущего».

Тогда можно получить ошибки вроде RequestTimeTooSkewed или похожие проблемы с подписью.

На нормальном VPS время обычно синхронизируется автоматически через NTP или systemd-timesyncd.

Проверить состояние можно через: timedatectl

Нас интересуют строки вроде:

    System clock synchronized: yes
NTP service: active

Если время действительно сильно отличается, сначала стоит исправить синхронизацию, а уже потом искать проблему в ключах.

Это особенно полезный диагностический принцип: если ключи выглядят правильными, endpoint отвечает, а подпись всё равно не сходится — проверьте время и регион.

Где AWS CLI хранит настройки и credentials

AWS CLI обычно разделяет конфигурацию и секретные данные на два файла в домашнем каталоге пользователя.

Основные пути: ~/.aws/credentials и ~/.aws/config

В credentials обычно находятся Access Key и Secret Key.

Например:

    [storage]
aws_access_key_id = ACCESS_KEY
aws_secret_access_key = SECRET_KEY

А в config — параметры профиля:

    [profile storage]
region = us-east-1
output = json

Это разделение удобно, потому что credentials можно защищать строже, а конфигурацию — менять отдельно.

Но есть важный нюанс: endpoint стороннего S3-провайдера не всегда хранится там автоматически после обычного aws configure.

Поэтому на практике чаще делают одно из двух:

  • Каждый раз передают --endpoint-url;
  • Либо настраивают endpoint через поддерживаемую конфигурацию конкретной версии AWS CLI.

Для учебной статьи мы сначала будем использовать явный --endpoint-url, потому что так нагляднее: видно, куда именно уходит запрос.

И еще один важный момент.

Файлы: ~/.aws/credentials и ~/.aws/config относятся к конкретному Linux-пользователю.

Если AWS CLI запускается от другого пользователя, например через sudo, он может искать уже: /root/.aws/, а не /home/ubuntu/.aws/

Из-за этого иногда возникает странная ситуация:

aws s3 ls

→ работает

sudo aws s3 ls

→ credentials не найдены

Проблема не в S3, а в том, что команда запущена в другом пользовательском окружении.

Мини-таблица команд

Задача Команда 
Проверить установленную версию AWS CLI aws --version 
Посмотреть текущую конфигурацию aws configure list 
Посмотреть доступные профили aws configure list-profiles 
Проверить конкретный профиль aws configure list --profile storage 
Проверить системное время timedatectl 
Посмотреть каталог конфигурации ls -la ~/.aws/ 

На этом этапе уже понятно, что подключение к S3 — это не просто «передать URL и пароль».

AWS CLI должен собрать несколько частей вместе: endpoint, credentials, регион, время и правила подписи.

Следующим шагом установим сам AWS CLI, создадим отдельный профиль для нашего хранилища и подготовим конфигурацию так, чтобы не смешивать ключи разных сервисов.

Устанавливаем AWS CLI и создаем отдельный профиль

Здесь важно не просто установить AWS CLI, а сразу настроить его так, чтобы работа с S3-совместимым хранилищем не смешивалась с другими учетными данными.

Это особенно полезно, если на одном сервере или рабочем компьютере позже будут одновременно использоваться:

  • Amazon S3;
  • Стороннее S3-совместимое хранилище;
  • Отдельное backup-хранилище;
  • Тестовый и production-аккаунты.

Вместо одной общей конфигурации для всего удобнее создать отдельный профиль.

Почему профиль удобнее глобальной конфигурации

AWS CLI умеет работать с несколькими наборами настроек.

Каждый такой набор называется profile.

Например:

default

storage

backup

production

У каждого профиля могут быть свои:

  • Access Key;
  • Secret Key;
  • регион;
  • формат вывода;
  • дополнительные параметры.

Это позволяет явно говорить AWS CLI: используй именно этот набор credentials.

Например: aws s3 ls --profile storage или aws s3 ls --profile backup

Так намного сложнее случайно отправить команду не в то хранилище или использовать не те ключи.

Без профилей всё чаще сводится к одному глобальному набору параметров: default

А потом при появлении второго провайдера начинается путаница: какие ключи сейчас активны, какой регион выбран и почему вчера команда работала, а сегодня внезапно получает AccessDenied.

Поэтому для нашего S3-совместимого хранилища сразу создадим отдельный профиль: storage

Какие параметры нужно получить у провайдера

До настройки AWS CLI нужно получить несколько значений из панели облачного провайдера.

Обычно понадобятся:

Параметр Для чего нужен 
Access Key ID Идентифицирует учетную запись или сервисного пользователя 
Secret Access Key Используется для подписи запросов 
Endpoint Адрес S3 API конкретного провайдера 
Region Регион, который участвует в конфигурации и подписи 
Bucket name Понадобится позже для работы с конкретным bucket 

Названия полей в панели могут немного отличаться.

Например, вместо Access Key ID может использоваться: Access Key или S3 Access Key

То же самое относится к endpoint.

Он может выглядеть примерно так: https://s3.example-provider.com или включать регион: https://s3.eu.example-provider.com

Здесь важно брать значения именно из документации или панели вашего провайдера, а не копировать endpoint из чужой статьи.

S3 API совместим, а адрес инфраструктуры у каждого сервиса свой.

Где хранятся credentials и config

После настройки профиля AWS CLI создаст или обновит каталог: ~/.aws/

Внутри обычно находятся два файла.

Первый: ~/.aws/credentials

В нем хранятся ключи.

Например:

    [storage]
aws_access_key_id = ACCESS_KEY
aws_secret_access_key = SECRET_KEY

Второй: ~/.aws/config

В нем находятся остальные параметры профиля.

Например:

    [profile storage]
region = us-east-1
output = json

Обратите внимание на небольшое отличие синтаксиса.

В credentials профиль называется: [storage]

А в config: [profile storage]

Это нормальный формат AWS CLI.

Проверить созданные файлы можно так: ls -la ~/.aws/

Но выводить содержимое credentials в терминал без необходимости не стоит.

Почему ключи нельзя вставлять в скрипты 

Secret Access Key нужно воспринимать примерно как пароль к API.

Если он утечет, злоумышленник может использовать его для подписания запросов от имени вашей учетной записи.

А последствия уже зависят от выданных прав.

Если ключ имеет широкий доступ, с его помощью потенциально можно:

  • Читать объекты;
  • Загружать новые;
  • Перезаписывать существующие;
  • Удалять данные;
  • Просматривать buckets;
  • Менять часть настроек, если это разрешено политиками.

Поэтому плохой вариант выглядит так:

aws configure set aws_secret_access_key VERY_SECRET_KEY

если команда потом остается в shell history, логах автоматизации или документации.

Еще хуже:

    aws s3 sync ./backup s3://my-bucket \
--some-secret-parameter VERY_SECRET_KEY

если секрет передается прямо в командной строке.

AWS CLI как раз и позволяет хранить credentials отдельно, чтобы не повторять их в каждой команде.

Практика: устанавливаем AWS CLI и создаем профиль

На Ubuntu сначала проверим, установлен ли AWS CLI: aws --version

Если команда не найдена, можно установить пакет:

sudo apt update

sudo apt install -y awscli

После установки снова проверяем: aws --version

Теперь создадим отдельный профиль: aws configure --profile storage

AWS CLI последовательно попросит:

    AWS Access Key ID:
AWS Secret Access Key:
Default region name:
Default output format:

Например:

    AWS Access Key ID: ACCESS_KEY
AWS Secret Access Key: SECRET_KEY
Default region name: us-east-1
Default output format: json

Endpoint здесь пока не указываем.

В следующих командах будем передавать его явно через: --endpoint-url

Так структура подключения будет максимально прозрачной.

После настройки проверим профиль: aws configure list --profile storage

И список всех профилей: aws configure list-profiles

Команды из главы

Задача Команда 
Проверить AWS CLI aws --version 
Установить AWS CLI sudo apt install -y awscli 
Создать профиль aws configure --profile storage 
Проверить профиль aws configure list --profile storage 
Посмотреть профили aws configure list-profiles 
Посмотреть каталог конфигурации ls -la ~/.aws/ 

Теперь у нас есть отдельный профиль с credentials, но мы еще не доказали, что endpoint и ключи действительно работают вместе.

Проверяем подключение через собственный endpoint

Профиль уже создан, ключи сохранены, а AWS CLI знает, под каким именем использовать этот набор credentials.

Теперь пора проверить самое главное: может ли клиент действительно подключиться к S3-совместимому хранилищу конкретного провайдера.

И здесь лучше не начинать сразу с загрузки файлов, удаления объектов или создания bucket. Сначала логичнее выполнить безопасный запрос на чтение и убедиться, что endpoint, профиль и подпись работают вместе.

Почему сначала лучше выполнить безопасный read-only запрос

Если настройка еще не проверена, первая команда должна по возможности ничего не менять.

Например, вместо aws s3 mb s3://my-bucket лучше начать с обычного просмотра: aws s3 ls

Почему это полезно?

Потому что мы сразу отделяем две задачи:

  • Подключение и авторизация;
  • Изменение данных.

Если read-only запрос проходит, значит базовая цепочка уже работает:

  • endpoint доступен;
  • DNS разрешается;
  • TLS-соединение устанавливается;
  • Access Key распознается;
  • Secret Key подходит для подписи;
  • регион и формат запроса не вызывают конфликт;
  • профиль действительно читается AWS CLI.

А если запрос падает, мы еще ничего не успели создать, удалить или перезаписать.

Для инфраструктурных инструментов это хороший общий принцип: сначала проверяем доступ минимально опасной операцией, потом переходим к изменениям.

Как понять, что endpoint и ключи работают

Теперь добавим собственный endpoint.

Допустим, провайдер выдал адрес:

https://s3.example-provider.com

Проверим список доступных bucket:

    aws s3 ls \
--endpoint-url https://s3.example-provider.com \
--profile storage

Если в аккаунте уже есть bucket, вывод может выглядеть примерно так:

    2026-09-15 12:31:42 backups
2026-09-15 12:33:18 site-media

Если bucket пока нет, команда может просто вернуть пустой результат без ошибки.

И это тоже успешное подключение.

Пустой список означает, что AWS CLI дошел до хранилища и успешно выполнил запрос, но показывать пока нечего.

Теперь можно проверить конкретный bucket:

    aws s3 ls s3://my-bucket \
--endpoint-url https://s3.example-provider.com \
--profile storage

Если внутри уже есть объекты, увидим их имена, размеры и даты.

Например:

    2026-09-15 13:02:10      14321 report.pdf
2026-09-15 13:03:54    2849012 backup.sql.gz

Если используется структура с префиксами, AWS CLI может показывать что-то похожее на каталоги: PRE backups/ и PRE images/

Но, как мы уже разбирали выше, это не обязательно реальные директории. CLI просто группирует ключи по префиксам, чтобы человеку было удобнее.

Есть еще один полезный способ проверки — использовать низкоуровневую команду S3 API:

    aws s3api list-buckets \
--endpoint-url https://s3.example-provider.com \
--profile storage

В отличие от aws s3, набор s3api ближе к прямым API-операциям S3 и обычно возвращает структурированный JSON.

Например:

    {
"Buckets": [
{
"Name": "backups"
}
]
}

Для повседневной работы aws s3 удобнее, а s3api особенно полезен для диагностики и более тонких настроек.

Чем ошибка соединения отличается от ошибки авторизации

Вот здесь начинается действительно полезная диагностика.

Не все ошибки AWS CLI означают «неверный пароль».

Допустим, получаем: Could not connect to the endpoint URL или EndpointConnectionError

Это означает, что клиент вообще не смог нормально подключиться к endpoint.

Причины могут быть сетевыми:

  • Неправильно указан URL;
  • endpoint не существует;
  • DNS не разрешается;
  • Порт недоступен;
  • firewall блокирует соединение;
  • TLS-сертификат не проходит проверку;
  • У сервиса временная проблема.

То есть до проверки Access Key дело может даже не дойти.

Можно проверить сам адрес отдельно:

curl -I https://s3.example-provider.com

Здесь не обязательно ожидать 200 OK: S3 endpoint может вернуть 403, 400 или XML-ошибку без подписи.

Главное — понять, отвечает ли сервер вообще.

Совсем другая ситуация: InvalidAccessKeyId

Здесь endpoint уже доступен, запрос дошел до S3-сервиса, но указанный Access Key не был принят.

Возможные причины:

  • Опечатка в ключе;
  • Ключ удален;
  • Используется ключ от другого аккаунта;
  • Ключ относится к другому S3-провайдеру;
  • Выбран не тот профиль.

А SignatureDoesNotMatch означает, что сервер получил запрос и Access Key распознал, но вычисленная подпись не совпала.

Тогда проверяем уже:

  • Secret Key;
  • Регион;
  • Системное время;
  • Endpoint;
  • Способ формирования host/path;
  • Особенности конкретного S3-compatible сервиса.

Еще одна ошибка: AccessDenied

Она часто означает уже более интересную вещь: аутентификация прошла, но у пользователя нет права на конкретное действие.

Например, сервисному пользователю разрешено читать объекты из одного bucket, но запрещено выполнять ListAllMyBuckets.

В таком случае команда aws s3 ls может получить AccessDenied, а: aws s3 ls s3://allowed-bucket — успешно заработать.

И это важный нюанс: ошибка просмотра всех bucket не всегда означает, что credentials вообще не работают.

Права могли быть специально ограничены.

Именно поэтому при диагностике полезно знать, какие разрешения выдал провайдер или администратор.

Мини-таблица команд

Что проверяем Команда 
Список доступных bucket aws s3 ls --endpoint-url https://s3.example-provider.com --profile storage 
Содержимое конкретного bucket aws s3 ls s3://my-bucket --endpoint-url https://s3.example-provider.com --profile storage 
Список bucket через API aws s3api list-buckets --endpoint-url https://s3.example-provider.com --profile storage 
Доступность endpoint curl -I https://s3.example-provider.com 
Используемый профиль aws configure list --profile storage 

На этом этапе у нас уже есть доказательство, что профиль и endpoint работают вместе.

Теперь можно переходить от безопасных запросов к изменениям и создать первый bucket. 

Создаем bucket

С понятием bucket мы уже разобрались в начале статьи, поэтому повторять его устройство здесь не будем. На этом этапе нас интересует уже практическая часть: как создать bucket через AWS CLI и какие параметры могут повлиять на результат.

На первый взгляд операция простая, но именно при создании bucket часто всплывают особенности конкретного S3-совместимого провайдера — прежде всего регион и правила уникальности имени.

Как регион влияет на создание bucket

У разных S3-совместимых сервисов работа с регионами может отличаться.

Один провайдер может использовать единственный регион для всего Object Storage, другой — несколько отдельных регионов с собственными endpoint.

Например:

https://s3.eu.example-provider.com
https://s3.us.example-provider.com

Регион может участвовать не только в размещении данных, но и в формировании подписи SigV4.

Поэтому если профиль настроен с одним значением: region = us-east-1, а endpoint ожидает другое, часть операций может завершаться ошибкой.

Особенно часто это проявляется именно при создании bucket.

В некоторых реализациях S3 достаточно обычной команды:

    aws s3 mb s3://my-bucket \
--endpoint-url https://s3.example-provider.com \
--profile storage

А в других случаях может потребоваться явное указание региона через параметры API.

Например:

    aws s3api create-bucket \
--bucket my-bucket \
--create-bucket-configuration LocationConstraint=eu-1 \
--endpoint-url https://s3.example-provider.com \
--profile storage

Точное значение LocationConstraint нужно брать из документации конкретного провайдера.

То есть если aws s3 mb возвращает ошибку, не стоит сразу подозревать ключи. Возможно, endpoint и авторизация работают, а сервис просто ожидает другой региональный параметр.

Почему требования к уникальности имени зависят от провайдера

Еще один нюанс — область уникальности имени bucket.

В Amazon S3 имена bucket существуют в общем namespace соответствующего сервиса, поэтому простое имя вроде: backup, почти наверняка уже занято.

У стороннего S3-совместимого провайдера правила могут быть другими.

Имя может требоваться уникальным:

  • Глобально;
  • Только внутри региона;
  • Внутри проекта;
  • Внутри аккаунта;
  • Внутри конкретного endpoint.

Поэтому безопаснее сразу выбирать более специфичные названия.

Например: company-project-prod-backups или site-media-eu-2026 вместо: data или backup

Так меньше шанс столкнуться с конфликтом, а назначение bucket будет понятно даже спустя несколько месяцев.

Есть и еще одна практическая причина не относиться к имени как к случайной подписи: оно может участвовать в URL объекта и использоваться в скриптах, политиках доступа и автоматизации.

Поэтому лучше выбрать нормальное имя сразу, чем потом строить миграцию только потому, что первый bucket назывался test123.

Практика

Допустим, используем:

Профиль: storage

    Endpoint: https://s3.example-provider.com
Bucket: my-bucket

Создаем bucket:

    aws s3 mb s3://my-bucket \
--endpoint-url https://s3.example-provider.com \
--profile storage

После этого проверим список доступных bucket:

    aws s3 ls \
--endpoint-url https://s3.example-provider.com \
--profile storage

И содержимое нового bucket:

    aws s3 ls s3://my-bucket \
--endpoint-url https://s3.example-provider.com \
--profile storage

Пустой вывод здесь нормален: bucket существует, но объектов внутри пока нет.

Дополнительно можно проверить сам bucket через S3 API:

    aws s3api head-bucket \
--bucket my-bucket \
--endpoint-url https://s3.example-provider.com \
--profile storage

Если команда завершается без ошибки, bucket существует и учетная запись имеет к нему доступ.

Мини-таблица команд

Задача Команда 
Создать bucket aws s3 mb s3://my-bucket --endpoint-url https://s3.example-provider.com --profile storage 
Посмотреть список bucket aws s3 ls --endpoint-url https://s3.example-provider.com --profile storage 
Посмотреть содержимое bucket aws s3 ls s3://my-bucket --endpoint-url https://s3.example-provider.com --profile storage 
Проверить bucket через API aws s3api head-bucket --bucket my-bucket --endpoint-url https://s3.example-provider.com --profile storage 

Теперь хранилище уже готово принимать данные. Следующий шаг — загрузить первый объект, скачать его обратно и посмотреть, как AWS CLI работает с отдельными файлами и целыми каталогами.

Загружаем и скачиваем файлы

На этом этапе AWS CLI начинает ощущаться почти как обычная работа с файлами: есть cp, можно указывать источник и назначение, загружать отдельные объекты или целые каталоги.

Но внутри S3 логика всё же отличается от обычной файловой системы, и это особенно заметно на уровне ключей объектов.

Как object key заменяет привычный путь к файлу

Допустим, мы хотим загрузить файл: report.pdf

в bucket: my-bucket

и логически разместить его в: docs/2026/report.pdf

Для AWS CLI это будет выглядеть так: s3://my-bucket/docs/2026/report.pdf

Но важно помнить: docs/2026/report.pdf — это не путь в привычном смысле, а ключ объекта.

То есть хранилище не обязано отдельно создавать:

docs/

2026/

как реальные каталоги.

Оно просто сохраняет объект с ключом: docs/2026/report.pdf

И уже AWS CLI или веб-интерфейс провайдера может визуально показывать такие префиксы как папки.

Это особенно удобно, потому что структуру можно формировать сразу при загрузке.

Например, объект можно положить как: backups/postgresql/2026-09-15.sql.gz, даже если раньше никаких backups или postgresql не существовало.

Что происходит при загрузке объекта

Когда выполняется команда загрузки, AWS CLI читает локальный файл и отправляет его в S3 API.

Хранилище получает:

  • содержимое объекта;
  • bucket назначения;
  • key;
  • метаданные;
  • параметры запроса.

После этого объект становится доступен по своему ключу.

Например, локальный файл: ./report.pdf можно загрузить как: s3://my-bucket/reports/report.pdf

При этом локальное имя и ключ вообще не обязаны совпадать.

Например: ./final-report-v7.pdf можно сохранить как: s3://my-bucket/reports/report.pdf

То есть при загрузке мы фактически задаем новое имя объекта внутри S3.

Это полезно в автоматизации, где локальный временный файл может иметь техническое имя, а в Object Storage получать нормальный постоянный key.

Что будет, если загрузить объект с тем же ключом

Здесь тоже есть важное отличие от восприятия S3 как «сетевого диска».

Если в bucket уже существует: s3://my-bucket/report.pdf и мы снова загружаем объект с тем же ключом, старый объект обычно будет заменен новым содержимым.

То есть key должен быть уникальным внутри bucket.

Если versioning у bucket не включен, предыдущую версию после перезаписи обычно уже нельзя получить обычным способом.

Если versioning поддерживается и активирован, старые версии могут сохраняться отдельно.

Поэтому команда: aws s3 cp report.pdf s3://my-bucket/report.pdf … может быть не просто «загрузкой», а фактически перезаписью уже существующего объекта.

Для backup-сценариев это особенно важно.

Например, если каждый день писать резервную копию под одним и тем же ключом: backup.sql.gz, то в bucket может оставаться только последняя версия.

Если нужно хранить историю, лучше использовать уникальные ключи:

backups/2026-09-15.sql.gz

backups/2026-09-16.sql.gz

backups/2026-09-17.sql.gz

или включать versioning, если провайдер его поддерживает.

Чем одиночная загрузка отличается от рекурсивной

Для одного файла всё просто: источник и назначение указываются явно.

Например:

file.txt

→ s3://my-bucket/file.txt

Но часто нужно перенести целый каталог.

Допустим:

Если использовать рекурсивное копирование, AWS CLI пройдет по каталогу и создаст соответствующие object key.

Например:

index.html

css/style.css

images/logo.png

могут превратиться в:

s3://my-bucket/site/index.html

s3://my-bucket/site/css/style.css

s3://my-bucket/site/images/logo.png

Важно понимать, что cp --recursive просто копирует весь выбранный набор объектов.

Он не пытается полноценно сравнивать две стороны и приводить их к одному состоянию.

Для этого существует уже другая команда — sync, которую разберем в следующей главе.

Практика

Допустим, используем:

    Bucket: my-bucket
Endpoint: https://s3.example-provider.com
Profile: storage

Загрузить один файл:

    aws s3 cp ./report.pdf s3://my-bucket/report.pdf \
--endpoint-url https://s3.example-provider.com \
--profile storage

Загрузить его под другим ключом:

    aws s3 cp ./report.pdf s3://my-bucket/reports/2026/report.pdf \
--endpoint-url https://s3.example-provider.com \
--profile storage

Скачать объект обратно:

    aws s3 cp s3://my-bucket/report.pdf ./downloaded-report.pdf \
--endpoint-url https://s3.example-provider.com \
--profile storage

Посмотреть содержимое bucket:

    aws s3 ls s3://my-bucket \
--endpoint-url https://s3.example-provider.com \
--profile storage

А для загрузки всего каталога:

    aws s3 cp ./data s3://my-bucket/data/ \
--recursive \
--endpoint-url https://s3.example-provider.com \
--profile storage

Далее у нас как обычно идёт удобная подборка команд. 

Мини-таблица команд

Задача Команда 
Загрузить файл aws s3 cp ./file.txt s3://my-bucket/file.txt --endpoint-url ... --profile storage 
Скачать файл aws s3 cp s3://my-bucket/file.txt ./file.txt --endpoint-url ... --profile storage 
Загрузить под другим ключом aws s3 cp ./file.txt s3://my-bucket/archive/file.txt --endpoint-url ... --profile storage 
Загрузить каталог aws s3 cp ./data s3://my-bucket/data/ --recursive --endpoint-url ... --profile storage 
Посмотреть содержимое aws s3 ls s3://my-bucket --endpoint-url ... --profile storage 

Теперь мы умеем работать с отдельными файлами и целыми каталогами.

Синхронизируем каталоги через aws s3 sync

Обычная загрузка через cp хорошо подходит, когда нужно перенести конкретный файл или просто отправить весь каталог целиком.

Но если локальный каталог и bucket уже существуют и регулярно меняются, каждый раз копировать всё подряд не очень удобно.

Для таких задач в AWS CLI есть команда: aws s3 sync

Она сравнивает источник и назначение и старается передавать только те файлы, которые действительно нужно обновить.

Именно поэтому sync часто используют для:

  • Резервных копий;
  • Статических сайтов;
  • Архивов;
  • Выгрузки логов;
  • Синхронизации рабочих каталогов.

Далее перейдем к сравнению.

Чем sync отличается от cp --recursive

На первый взгляд команды похожи.

Например: aws s3 cp ./data s3://my-bucket/data/ --recursive и aws s3 sync ./data s3://my-bucket/data/ — обе способны отправить целый каталог в S3.

Но логика у них разная.

cp --recursive действует ближе к обычному копированию: проходит по выбранному каталогу и копирует объекты.

sync пытается привести источник и назначение к более похожему состоянию, сравнивая содержимое и пропуская то, что считает уже актуальным.

Это особенно заметно при повторном запуске.

Допустим, у нас есть:

После первой синхронизации все три файла попали в bucket.

Затем мы изменили только: index.html

При следующем sync AWS CLI обычно не будет повторно отправлять весь каталог. Он передаст только измененный объект.

Для больших наборов данных это экономит:

  • Время;
  • Сетевой трафик;
  • Количество операций;
  • Иногда и деньги, если провайдер тарифицирует запросы или исходящий трафик.

Идём дальше.

Как AWS CLI определяет измененные файлы

Вот здесь есть важное НО.

aws s3 sync не выполняет полное побайтовое сравнение каждого локального файла с каждым объектом перед каждой операцией.

Это было бы слишком дорого.

CLI использует метаданные, в первую очередь размер и время изменения, а точное поведение зависит от направления синхронизации и используемых параметров.

Поэтому sync лучше воспринимать не как систему контроля версий и не как криптографическую проверку идентичности, а как практический механизм синхронизации.

Например, если локальный файл report.pdf не изменился по размеру и временным характеристикам, AWS CLI может считать, что повторная загрузка не нужна.

Для обычных backup- и deployment-сценариев этого чаще всего достаточно.

Но если требуется гарантированная проверка целостности, уже нужны дополнительные механизмы: checksums, versioning или отдельная логика приложения.

Есть и еще один полезный момент.

При синхронизации S3 → локальная система AWS CLI также сравнивает доступные метаданные и скачивает только то, что считает новым или измененным.

Поэтому одна и та же команда работает в обе стороны.

Что делает --delete

По умолчанию sync добавляет и обновляет нужные объекты, но не удаляет лишние данные на стороне назначения.

Представим, что локально было:

Мы синхронизировали каталог с S3.

Потом локально удалили: old.js и снова выполнили обычный: aws s3 sync ./site s3://my-bucket/site/

Объект: site/old.js в bucket может остаться.

Это сделано намеренно: обычная синхронизация не должна без дополнительного указания удалять данные.

Если же добавить: --delete

AWS CLI удалит на стороне назначения те файлы или объекты, которых больше нет в источнике.

То есть: aws s3 sync ./site s3://my-bucket/site/ --delete уже означает примерно: сделай содержимое назначения максимально похожим на источник, включая удаление лишнего.

Это очень полезно для зеркалирования.

Но одновременно и значительно опаснее.

Почему перед --delete полезен --dryrun

Флаг --delete — как раз тот случай, когда сначала лучше посмотреть, что собирается сделать команда.

Для этого есть: --dryrun

Он показывает планируемые операции, но не выполняет их.

Например:

    aws s3 sync ./site s3://my-bucket/site/ \
--delete \
--dryrun

AWS CLI может вывести примерно:

    (dryrun) upload: ./index.html to s3://my-bucket/site/index.html
(dryrun) delete: s3://my-bucket/site/old.js

И вот здесь можно спокойно проверить:

  • Правильный ли bucket выбран;
  • Правильный ли префикс указан;
  • Не удалится ли что-то нужное;
  • Не перепутаны ли источник и назначение.

Особенно важно это в автоматизации.

Ошибка вроде: s3://my-bucket/ вместо: s3://my-bucket/site/ в сочетании с --delete может затронуть намного больше объектов, чем ожидалось.

Поэтому для production-сценария хорошее правило: сначала sync --dryrun, потом — реальный sync.

Практика

Локальный каталог → S3:

    aws s3 sync ./data s3://my-bucket/data/ \
--endpoint-url https://s3.example-provider.com \
--profile storage

S3 → локальный каталог:

    aws s3 sync s3://my-bucket/data/ ./data \
--endpoint-url https://s3.example-provider.com \
--profile storage

Посмотреть предполагаемые изменения:

    aws s3 sync ./data s3://my-bucket/data/ \
--dryrun \
--endpoint-url https://s3.example-provider.com \
--profile storage

Проверить, что произойдет при удалении лишних объектов:

    aws s3 sync ./data s3://my-bucket/data/ \
--delete \
--dryrun \
--endpoint-url https://s3.example-provider.com \
--profile storage

И только после проверки выполнить реальную синхронизацию:

    aws s3 sync ./data s3://my-bucket/data/ \
--delete \
--endpoint-url https://s3.example-provider.com \
--profile storage

Дальше снова мини-таблица полезных команд. 

Мини-таблица команд

Задача Команда 
Локально → S3 aws s3 sync ./data s3://my-bucket/data/ --endpoint-url ... --profile storage 
S3 → локально aws s3 sync s3://my-bucket/data/ ./data --endpoint-url ... --profile storage 
Посмотреть изменения без выполнения aws s3 sync ./data s3://my-bucket/data/ --dryrun --endpoint-url ... --profile storage 
Проверить удаление лишних объектов aws s3 sync ./data s3://my-bucket/data/ --delete --dryrun --endpoint-url ... --profile storage 
Выполнить зеркальную синхронизацию aws s3 sync ./data s3://my-bucket/data/ --delete --endpoint-url ... --profile storage 

Теперь AWS CLI умеет не просто копировать отдельные файлы, а поддерживать целые каталоги в актуальном состоянии.

Следующий логичный шаг — разобраться с несколькими профилями, потому что один и тот же AWS CLI вполне может одновременно работать с несколькими S3-совместимыми хранилищами и разными наборами ключей.

Работаем с несколькими хранилищами через профили

До этого мы использовали один профиль: storage

Для одного S3-совместимого хранилища этого достаточно.

Но в реальной работе довольно быстро появляется второй набор credentials, затем третий — и вот уже один и тот же AWS CLI должен уметь обращаться к разным провайдерам, регионам и аккаунтам.

Например:

  • default
  • backup-storage
  • archive-storage
  • production-storage
  • aws

И вот здесь profiles становятся способом не перепутать, какими ключами и куда именно отправляется команда.

Зачем отдельный профиль каждому хранилищу

Представим, что у нас есть два S3-compatible сервиса.

Первый используется для резервных копий: https://s3.backup-provider.example

Второй — для медиа: https://s3.media-provider.example

У каждого:

  • Свой Access Key;
  • Свой Secret Key;
  • Возможно, свой регион;
  • Собственный endpoint;
  • Отдельные права.

Если хранить всё в одном default, приходится постоянно менять настройки.

Это неудобно и опасно.

Гораздо логичнее создать: backup-storage и media-storage

Тогда команда сама по себе уже становится более понятной: aws s3 ls --profile backup-storage или aws s3 ls --profile media-storage

То есть профиль превращается в явный контекст выполнения.

Это особенно полезно при командах, которые изменяют данные.

Например, разница между: aws s3 sync ./backup s3://prod-backups/ --delete и той же командой с явно указанным: --profile backup-storage может быть весьма существенной.

Чем больше хранилищ, тем полезнее избегать неявного поведения.

Как AWS CLI выбирает credentials

AWS CLI умеет получать учетные данные из нескольких источников.

И здесь важно понимать, что они имеют приоритет.

Упрощенно можно считать, что CLI ищет credentials примерно так:

  • Явно переданные параметры и окружение;
  • Выбранный профиль;
  • Стандартный default;
  • Другие доступные механизмы credentials, если они настроены.

Для обычной работы с профилями нас особенно интересует: ~/.aws/credentials

Например:

    [backup-storage]
aws_access_key_id = BACKUP_ACCESS_KEY
aws_secret_access_key = BACKUP_SECRET_KEY
[media-storage]
aws_access_key_id = MEDIA_ACCESS_KEY
aws_secret_access_key = MEDIA_SECRET_KEY

А в ~/.aws/config можно хранить связанные параметры:

    [profile backup-storage]
region = us-east-1
output = json
[profile media-storage]
region = eu-1
output = json

Теперь при aws s3 ls --profile backup-storage AWS CLI понимает, какой набор credentials использовать.

Проверить, откуда именно профиль получает значения, можно так: aws configure list --profile backup-storage

Это полезно, когда внезапно кажется, что CLI использует «не те ключи».

Иногда причина оказывается вовсе не в файле credentials, а в переменной окружения, которая имеет более высокий приоритет.

Когда удобнее --profile, а когда переменные окружения

Для ручной работы --profile обычно очень удобен.

Например:

    aws s3 ls \
--endpoint-url https://s3.example-provider.com \
--profile storage

Преимущество очевидное: из самой команды видно, какой профиль используется.

Это особенно полезно:

  • В терминале;
  • При администрировании нескольких хранилищ;
  • В статьях и документации;
  • При ручной диагностике.

Но в автоматизации профили подходят не всегда.

Например, внутри CI/CD контейнер может вообще не иметь постоянного: ~/.aws/credentials

Тогда credentials часто передаются через переменные окружения:

    AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_DEFAULT_REGION

AWS CLI подхватывает их автоматически.

Это удобно для:

  • CI/CD;
  • Временных окружений;
  • Контейнеров;
  • Systemd-сервисов;
  • Секретов из Vault или secret manager.

То есть выбор зависит от сценария.

Для человека: --profile обычно удобнее.

Для автоматизированного процесса — переменные окружения или специализированный secret storage могут быть безопаснее и гибче.

Но здесь есть важный нюанс: переменные окружения легко случайно сделать глобальными для сессии.

Например, если выполнить:

export AWS_ACCESS_KEY_ID=...

export AWS_SECRET_ACCESS_KEY=...

а потом забыть об этом, следующая команда может использовать эти значения даже тогда, когда вы ожидаете другой профиль.

Именно поэтому при странном поведении стоит проверить: env | grep ^AWS_

Если там остались старые credentials, они могут влиять на результат.

Почему не стоит смешивать ключи разных провайдеров

S3-compatible API выглядит одинаково, поэтому возникает ощущение, что ключи тоже взаимозаменяемы.

Но это не так.

Access Key и Secret Key создаются конкретным сервисом и действуют в пределах его системы авторизации.

Например, credentials от: Provider A не должны работать на: Provider B.

Даже если оба поддерживают aws s3 и Signature Version 4.

Если случайно использовать: endpoint Provider B, вместе с credentials Provider A, можно получить InvalidAccessKeyId или другую ошибку авторизации.

Еще хуже, если у двух профилей похожие имена и приходится вспоминать, какой из них production.

Поэтому профили лучше называть по назначению, а не:

  • test1
  • test2
  • new
  • storage2

Гораздо понятнее:

  • prod-backups
  • stage-backups
  • media-storage
  • archive-storage

И здесь работает тот же принцип, что и с именами bucket: хороший naming сегодня экономит время через полгода.

Мини-таблица команд

Задача Команда 
Создать новый профиль aws configure --profile backup-storage 
Посмотреть все профили aws configure list-profiles 
Проверить конкретный профиль aws configure list --profile backup-storage 
Использовать профиль в S3-команде aws s3 ls --profile backup-storage --endpoint-url ... 
Проверить AWS-переменные окружения env | grep ^AWS_ 
Указать профиль на время текущей shell-сессии export AWS_PROFILE=backup-storage 

Профили особенно полезны, когда один AWS CLI используется как универсальный клиент для нескольких S3-совместимых сервисов.

Управляем доступом к bucket и объектам

До этого момента мы в основном говорили о том, как подключиться к хранилищу и как отправлять туда команды.

Теперь пора разобраться с другим важным вопросом: Если Access Key работает, что именно он вообще имеет право делать?

И вот здесь начинается отдельный слой логики.

Потому что наличие рабочей пары: Access Key и  Secret Key, еще не означает, что пользователь автоматически может:

  • Читать все bucket;
  • Загружать файлы куда угодно;
  • Удалять объекты;
  • Менять политики;
  • Делать данные публичными.

Credentials подтверждают личность, а права доступа определяют допустимые действия.

Почему Access Key не означает полный доступ

Представим, что мы создали отдельного сервисного пользователя для резервных копий.

Ему нужно всего несколько возможностей:

  • Посмотреть содержимое конкретного bucket;
  • Загрузить новый backup;
  • Скачать backup при восстановлении.

Но удалять весь bucket, менять его политику или работать с чужими хранилищами ему совершенно не обязательно.

Поэтому хорошая схема выглядит не так:

Access Key

→ полный доступ ко всему Object Storage

а скорее так:

Access Key

→ конкретный пользователь

→ конкретная policy

→ ограниченный набор действий

Именно поэтому два разных Access Key могут успешно проходить аутентификацию на одном endpoint, но иметь совершенно разные возможности.

Например, один пользователь сможет выполнить GetObject, но получит AccessDenied на: DeleteObject

Это не ошибка авторизации.

Наоборот, авторизация уже прошла правильно — просто конкретное действие запрещено.

Чем отличаются credentials, ACL и bucket policy

Эти понятия легко смешать, потому что все они связаны с доступом.

Но работают на разных уровнях.

Credentials

Credentials — это учетные данные:

  • Access Key;
  • Secret Key.

Они отвечают на вопрос: Кто отправляет запрос?

То есть credentials идентифицируют пользователя или сервисный аккаунт.

ACL

ACL — Access Control List.

Это более старый механизм управления доступом к bucket или отдельным объектам.

Через ACL можно, например, выдавать права определенным пользователям или делать объект публично читаемым.

Но у разных S3-compatible провайдеров поддержка ACL может быть ограничена или вообще реализована не полностью.

Некоторые современные S3-сценарии вообще предпочитают policies и отключают ACL как основной механизм управления правами.

Bucket policy

Bucket policy — это политика, которая применяется к конкретному bucket.

Она позволяет описать:

  • Кто получает доступ;
  • К каким ресурсам;
  • Какие действия разрешены;
  • При каких условиях.

По смыслу policy гораздо гибче обычного «разрешить/запретить».

Например, можно разрешить сервисному пользователю:

  • Просматривать только my-backups;
  • Загружать объекты;
  • Читать объекты;
  • Но не удалять их.

Или разрешить публичное чтение только определенного префикса.

Условно различие можно свести к таблице:

Механизм На какой вопрос отвечает 
Credentials Кто выполняет запрос 
ACL Какие права назначены объекту или bucket 
Bucket policy Кто, что и при каких условиях может делать внутри bucket 

А теперь поехали к следующей главе.

Публичный bucket и публичный object — не одно и то же

Это тоже важный момент.

Когда говорят: «bucket публичный», под этим могут подразумевать совершенно разные вещи.

Например, bucket может разрешать анонимное чтение объектов, но запрещать просмотр их полного списка.

То есть пользователь сможет открыть https://.../images/logo.png, если знает точный адрес, но не сможет запросить: покажи мне вообще всё содержимое bucket.

И наоборот, можно настроить доступ так, что определенный пользователь имеет ListBucket, но не имеет GetObject.

Это потому, что в S3: список объектов и чтение конкретного объекта — разные API-действия.

Поэтому публичность лучше не воспринимать как один переключатель «всё открыто / всё закрыто».

Особенно если речь идет о S3-compatible провайдере: интерфейс панели может упрощать настройки, а под капотом использовать собственную реализацию policies или ACL.

Принцип минимальных прав

Один из базовых принципов безопасности здесь — least privilege, или принцип минимально необходимых прав.

Сервису нужно давать только те действия, которые реально необходимы для его задачи.

Например, backup-скрипту может быть достаточно:

  1. ListBucket
  2. PutObject
  3. GetObject

А вот DeleteObject можно не давать вообще.

Это особенно полезно как защита от двух вещей:

  • Ошибки в скрипте;
  • Компрометации credentials.

Представим, что скрипт по ошибке запускается с неправильным --delete.

Если учетная запись вообще не имеет DeleteObject, хранилище просто отклонит удаление.

То есть policy становится дополнительным предохранителем.

Именно поэтому давать всем сервисным ключам полный доступ «чтобы не мешало» — удобный, но плохой подход.

Какие возможности доступа могут отличаться у S3-compatible провайдеров

Вот здесь S3-compatible снова не означает полную идентичность AWS.

Разные провайдеры могут по-разному поддерживать:

  • bucket policies;
  • object ACL;
  • public access;
  • versioning;
  • Object Lock;
  • lifecycle rules;
  • IAM-подобных пользователей;
  • отдельные service accounts;
  • ограничения по IP;
  • временные credentials;
  • presigned URLs.

У одного провайдера можно создать сложную JSON-policy почти как в AWS.

У другого — только выбрать несколько готовых ролей в панели:

  1. Read Only
  2. Read/Write
  3. Full Access

А третий может разрешать управление доступом только на уровне проекта.

Поэтому перед переносом сложной политики из Amazon S3 в стороннее Object Storage лучше сначала проверить документацию конкретного сервиса.

Простые права вроде чтения и записи обычно совместимы хорошо.

А вот продвинутые механизмы IAM — уже не всегда.

Основные действия S3

Ниже — несколько прав, которые особенно часто встречаются в политиках доступа:

Право Что разрешает 
ListBucket Просматривать список объектов внутри bucket 
GetObject Читать и скачивать объект 
PutObject Загружать или перезаписывать объект 
DeleteObject Удалять объект 
GetBucketLocation Получать информацию о регионе bucket 
ListAllMyBuckets Просматривать список доступных bucket 

Важно, что ListBucket относится к самому bucket, а GetObject, PutObject и DeleteObject — уже к объектам внутри него.

Поэтому в policy часто приходится отдельно описывать ресурсы уровня bucket и уровня objects.

Например, логически это может выглядеть так:

Bucket:

arn:...:my-bucket

Objects:

arn:...:my-bucket/*

Точный формат зависит от конкретного провайдера и его реализации S3 policies.

На практике самый безопасный подход такой:

  1. Создать отдельного пользователя или service account.
  2. Выдать только нужный bucket.
  3. Разрешить только необходимые операции.
  4. Проверить каждое действие через AWS CLI.
  5. Только после этого использовать credentials в автоматизации.

Так гораздо проще понять, почему конкретная команда получает AccessDenied, и заметно безопаснее, чем выдавать полный доступ с самого начала.

Почему AWS CLI отвечает AccessDenied или SignatureDoesNotMatch

Когда AWS CLI уже установлен, профиль настроен, а endpoint известен, кажется, что дальше всё должно работать автоматически.

Но на практике именно на этом этапе чаще всего появляются ошибки вроде AccessDenied, InvalidAccessKeyId или SignatureDoesNotMatch.

Важно не воспринимать их как одну и ту же проблему. Они возникают на разных этапах обработки запроса и поэтому указывают на разные причины.

Если упростить, цепочка выглядит так: AWS CLI формирует запрос, подписывает его, отправляет на endpoint, а сервер уже проверяет credentials, подпись и права пользователя.

Неверные Access Key или Secret Key

Если указан неправильный Access Key, сервер может вообще не распознать учетную запись. В таком случае часто появляется ошибка InvalidAccessKeyId.

Причины обычно достаточно простые: опечатка, старый ключ, удаленный service account или профиль от другого S3-провайдера.

С Secret Key ситуация немного другая. Он участвует в формировании подписи, поэтому неверный Secret Key чаще приводит к SignatureDoesNotMatch.

При этом AWS CLI сам не может проверить Secret Key заранее. Он просто использует сохраненное значение для расчета подписи и отправляет результат серверу.

Поэтому если Access Key выглядит правильным, но подпись не сходится, имеет смысл повторно проверить именно Secret Key.

Отдельно стоит помнить про переменные окружения. Даже если файл ~/.aws/credentials содержит правильные значения, активные AWS_ACCESS_KEY_ID и AWS_SECRET_ACCESS_KEY могут подменить их.

Ошибка в endpoint

Неправильный endpoint может проявляться по-разному.

Если адрес вообще недоступен, AWS CLI обычно сообщает о проблеме соединения, например Could not connect to the endpoint URL.

Если же endpoint существует, но относится к другому региону или другому S3-сервису, ошибка может выглядеть уже как проблема авторизации или подписи.

Например, пользователь может случайно использовать credentials одного провайдера вместе с endpoint другого.

С точки зрения AWS CLI всё выглядит нормально: URL существует, ключи загружены, запрос подписан. Но сервер не может связать этот Access Key со своей системой и отклоняет запрос.

Поэтому endpoint всегда нужно проверять вместе с профилем, а не отдельно.

Неправильный регион

Регион участвует в SigV4, поэтому его значение влияет непосредственно на подпись.

Если сервис ожидает один регион, а CLI использует другой, сервер может получить корректно сформированный запрос, но вычислить другую подпись.

Итогом становится SignatureDoesNotMatch.

У сторонних S3-compatible провайдеров здесь бывают особенности. Некоторые используют знакомое значение вроде us-east-1 независимо от физического расположения хранилища, а другие требуют собственное имя региона.

Поэтому регион лучше брать из документации провайдера, а не определять по географическому расположению дата-центра.

Для проверки текущего значения можно использовать aws configure list --profile storage.

Рассинхронизация системного времени

В SigV4 используется время запроса.

Если часы на клиентской системе сильно спешат или отстают, сервер может посчитать запрос недействительным.

Это сделано не случайно: временная привязка помогает ограничивать повторное использование ранее подписанных запросов.

При большой разнице во времени можно встретить RequestTimeTooSkewed или другие ошибки, связанные с подписью и датой.

На VPS этот сценарий встречается редко, поскольку время обычно синхронизируется автоматически, но полностью исключать его не стоит.

Проверить состояние системных часов можно командой timedatectl. Если NTP активен, а System clock synchronized показывает yes, причина, скорее всего, находится в другом месте.

У пользователя нет нужного действия в policy

AccessDenied чаще всего означает уже не проблему credentials, а недостаток прав.

Например, пользователь может иметь GetObject, но не иметь PutObject. Тогда скачивание объекта будет работать, а загрузка завершится отказом.

То же самое относится к ListBucket, DeleteObject и другим действиям.

Есть и более интересный случай: пользователь может иметь доступ к конкретному bucket, но не иметь права просматривать список всех bucket аккаунта.

Тогда aws s3 ls вернет AccessDenied, хотя команда aws s3 ls s3://my-bucket с тем же профилем выполнится успешно.

Поэтому при диагностике важно смотреть не только на сам факт отказа, но и на конкретную операцию, которую пытался выполнить AWS CLI.

Если ошибка возникает только на одной команде, а остальные работают, проблема почти наверняка связана с policy.

Path-style и virtual-hosted-style запросы

S3 поддерживает два основных способа адресации bucket.

При path-style запросе имя bucket находится в пути:

https://s3.example-provider.com/my-bucket/object.txt

При virtual-hosted-style оно становится частью hostname:

https://my-bucket.s3.example-provider.com/object.txt

Для Amazon S3 virtual-hosted-style давно является основным вариантом.

Но у S3-compatible провайдеров поддержка может отличаться.

Например, сервис может корректно работать только с path-style или, наоборот, ожидать virtual-hosted-style.

Проблемы здесь часто выглядят странно: endpoint отвечает, credentials правильные, но отдельные запросы завершаются ошибками подписи, DNS или доступа к bucket.

Причина в том, что строка запроса и host входят в расчет подписи SigV4. Если клиент и сервер по-разному формируют адрес bucket, подпись может не совпасть.

Для AWS CLI можно принудительно использовать path-style через конфигурацию:

    aws configure set s3.addressing_style path --profile storage

Для возврата к автоматическому выбору используется значение auto.

Этот параметр особенно полезен со старыми или частично совместимыми S3-сервисами.

Таблица ошибок

Ошибка Вероятная причина Что проверить 
InvalidAccessKeyId Неверный или удаленный Access Key Профиль, Access Key, аккаунт и провайдера 
SignatureDoesNotMatch Неверный Secret Key, регион, endpoint или addressing style Secret Key, регион, endpoint, path/virtual-hosted-style 
AccessDenied Недостаточно прав Policy и разрешения на конкретное действие 
RequestTimeTooSkewed Системное время сильно отличается timedatectl, NTP и текущую дату
Could not connect to the endpoint URL Endpoint недоступен или указан неверно URL, DNS, сеть, firewall и TLS 
NoSuchBucket Bucket не существует или указано неправильное имя Имя bucket, endpoint и регион 
PermanentRedirect Используется неправильный endpoint или регион Региональный endpoint и настройки профиля 
AuthorizationHeaderMalformed Ошибка региона или параметров подписи Region в профиле и требования провайдера 

Удобнее всего диагностировать такие ошибки последовательно: сначала проверить endpoint и соединение, затем профиль и credentials, потом регион и системное время, а уже после этого разбираться с policy и способом адресации bucket.

Если выполнять проверки именно в таком порядке, большая часть типичных проблем с S3-compatible хранилищами находится довольно быстро.

Теперь, когда мы знаем не только как выполнить команды, но и как искать причины ошибок, можно провести финальную проверку всей цепочки: создать или выбрать bucket, загрузить тестовый файл, скачать его обратно, выполнить sync и удалить тестовый объект.

Проверяем работу хранилища целиком

Начнем со списка доступных bucket:

    aws s3 ls \
--endpoint-url https://s3.example-provider.com \
--profile storage

Если нужный bucket уже существует, можно использовать его. Если нет — создадим тестовый:

    aws s3 mb s3://my-bucket \
--endpoint-url https://s3.example-provider.com \
--profile storage

Теперь подготовим небольшой локальный файл:

echo "S3 test file" > test.txt

Загрузим его в Object Storage:

    aws s3 cp ./test.txt s3://my-bucket/test.txt \
--endpoint-url https://s3.example-provider.com \
--profile storage

После загрузки проверим, что объект действительно появился:

    aws s3 ls s3://my-bucket/ \
--endpoint-url https://s3.example-provider.com \
--profile storage

На этом этапе в выводе должен появиться test.txt с его размером и временем изменения.

Теперь проверим обратное направление и скачаем объект под другим локальным именем:

    aws s3 cp s3://my-bucket/test.txt ./downloaded-test.txt \
--endpoint-url https://s3.example-provider.com \
--profile storage

При желании содержимое двух файлов можно сравнить:

diff test.txt downloaded-test.txt

Если команда ничего не выводит, файлы совпадают.

Следующим шагом проверим sync. Создадим небольшой каталог:

mkdir -p sync-test

echo "First file" > sync-test/first.txt

echo "Second file" > sync-test/second.txt

Синхронизируем его с отдельным префиксом внутри bucket:

    aws s3 sync ./sync-test s3://my-bucket/sync-test/ \
--endpoint-url https://s3.example-provider.com \
--profile storage

После этого содержимое можно проверить рекурсивным просмотром:

    aws s3 ls s3://my-bucket/sync-test/ \
--recursive \
--endpoint-url https://s3.example-provider.com \
--profile storage

Если оба файла отображаются, значит sync также работает корректно.

Остается проверить право на удаление. Удалим созданный ранее тестовый объект:

    aws s3 rm s3://my-bucket/test.txt \
--endpoint-url https://s3.example-provider.com \
--profile storage

И повторно посмотрим содержимое:

    aws s3 ls s3://my-bucket/ \
--endpoint-url https://s3.example-provider.com \
--profile storage

Если test.txt исчез, полный цикл успешно пройден: AWS CLI может подключаться к собственному endpoint, читать содержимое bucket, загружать и скачивать объекты, синхронизировать каталоги и удалять данные.

Тестовые объекты из sync-test/ после проверки тоже можно удалить:

    aws s3 rm s3://my-bucket/sync-test/ \
--recursive \
--endpoint-url https://s3.example-provider.com \
--profile storage

Если сам bucket создавался только для этой проверки и больше не нужен, после очистки его можно удалить командой:

    aws s3 rb s3://my-bucket \
--endpoint-url https://s3.example-provider.com \
--profile storage

Удалять рабочий bucket ради проверки, разумеется, не требуется.

После такого теста можно считать базовую настройку AWS CLI завершенной. Осталась безопасность. 

Как безопасно использовать S3 credentials в production

Почему ключи не стоит хранить в скриптах

Самый очевидный, но до сих пор распространенный анти-паттерн — прописывать Access Key и Secret Key прямо в shell-скрипте.

Например, так делать не стоит:

export AWS_ACCESS_KEY_ID="ACCESS_KEY"

export AWS_SECRET_ACCESS_KEY="SECRET_KEY"

aws s3 sync ./backup s3://my-bucket/

Технически это будет работать, но секреты окажутся внутри обычного текстового файла.

Дальше этот файл может попасть:

  • в Git;
  • в архив с проектом;
  • в резервную копию;
  • в CI-логи;
  • в чужую учетную запись;
  • в тикет или чат при отладке.

Еще одна проблема — shell history. Если вставлять секреты прямо в команды терминала, они могут сохраниться в истории текущего пользователя.

Поэтому production-сценарий лучше строить так, чтобы приложение или скрипт получали credentials из отдельного защищенного источника, а не содержали их внутри кода.

В зависимости от инфраструктуры это могут быть:

  • ~/.aws/credentials с корректными правами доступа;
  • переменные окружения, передаваемые процессу;
  • secret storage CI/CD;
  • Vault или другой менеджер секретов;
  • встроенный механизм временных credentials, если его поддерживает конкретный провайдер.

При этом сам факт использования переменных окружения не делает систему автоматически безопасной. Важно, кто может читать окружение процесса, как секреты передаются и не попадают ли они в логи.

Ограничиваем права отдельного service account

Для production лучше не использовать один общий ключ с полным доступом ко всему Object Storage.

Намного безопаснее создать отдельный service account под конкретную задачу.

Например, backup-сервису может быть достаточно прав ListBucket, PutObject и GetObject только для одного bucket.

Если удаление резервных копий выполняется отдельной lifecycle policy, право DeleteObject такому аккаунту можно вообще не выдавать.

Это дает сразу несколько преимуществ.

Во-первых, случайная ошибка в скрипте не сможет выйти за пределы разрешенных действий.

Во-вторых, при компрометации Secret Key злоумышленник получит не полный доступ ко всему аккаунту, а только ограниченный набор возможностей.

В-третьих, становится проще понимать назначение ключей. Вместо одного универсального пользователя можно иметь отдельные учетные записи для:

  • backup;
  • загрузки медиа;
  • CI/CD;
  • архивирования;
  • чтения отчетов.

Для каждого service account лучше задавать отдельные credentials и минимально необходимые права.

Когда стоит менять ключи

Secret Key не обязательно менять каждый понедельник только ради самого факта ротации.

Гораздо важнее уметь быстро заменить его тогда, когда действительно появляется риск.

Ключ нужно немедленно отозвать и создать новый, если он:

  • Попал в Git;
  • Был отправлен в чат или тикет;
  • Оказался в логах;
  • Хранился на скомпрометированном сервере;
  • Стал доступен сотруднику или подрядчику, которому больше не нужен доступ.

Периодическая ротация тоже полезна, особенно для долгоживущих production credentials.

Хороший процесс ротации выглядит так: сначала создается новый ключ, приложения переводятся на него, подключение проверяется, и только после этого старый ключ отключается.

Так меньше риск случайно остановить backup или другой сервис из-за преждевременного удаления credentials.

Если провайдер поддерживает несколько активных ключей для одного service account, такая схема особенно удобна.

Почему Object Storage сам по себе не отменяет backup

Еще одна типичная ошибка — считать, что файл уже стал резервной копией просто потому, что он лежит в Object Storage.

Object Storage действительно повышает надежность хранения, но оно не защищает от всех сценариев потери данных.

Например, если скрипт ошибочно удаляет объект и у его credentials есть DeleteObject, удаление может успешно синхронизироваться с удаленным хранилищем.

То же самое относится к:

  • Ошибочной перезаписи;
  • Поврежденным исходным данным;
  • Компрометации credentials;
  • Ошибке администратора;
  • Неправильному sync --delete.

Поэтому надежная схема обычно использует дополнительные механизмы.

Если провайдер поддерживает versioning, предыдущие версии объектов можно сохранять после перезаписи.

Lifecycle rules позволяют автоматически переводить старые версии в другой класс хранения или удалять их через заданный срок.

Object Lock может защищать данные от изменения и удаления в течение определенного периода.

А для особенно важных данных разумно иметь независимую копию в другом аккаунте, регионе или даже у другого провайдера.

То есть Object Storage — отличная платформа для резервного копирования, но не самостоятельная гарантия того, что backup невозможно потерять.

Полезно разделять два понятия:

  • Удаленная копия данных;
  • Полноценная стратегия резервного копирования.

Вторая обычно включает историю версий, сроки хранения, контроль доступа и регулярную проверку восстановления.

Заключение

S3-совместимое Object Storage позволяет работать с хранилищами разных провайдеров через привычный S3 API и один и тот же AWS CLI.

Для подключения достаточно знать endpoint, регион и credentials, но за этой простой схемой скрывается несколько важных деталей: подпись SigV4, profiles, права доступа, addressing style и особенности реализации S3 у конкретного сервиса.

В статье мы прошли весь основной рабочий цикл: настроили AWS CLI, создали отдельный профиль, подключились к собственному endpoint, создали bucket, загрузили и скачали объекты, синхронизировали каталоги и разобрали типовые ошибки авторизации.

Для production остается соблюдать несколько простых правил: не хранить Secret Key в коде, использовать отдельные service accounts, выдавать минимальные права и заранее продумать замену credentials.

А если Object Storage используется для резервных копий, стоит отдельно настроить versioning, retention или другую защиту от случайной перезаписи и удаления.

После этого AWS CLI становится не просто удобной утилитой для ручной загрузки файлов, а полноценным инструментом для backup, автоматизации, CI/CD и работы с большими наборами объектов.

FAQ

Можно ли использовать AWS CLI с S3-хранилищем, которое не принадлежит Amazon?

Да. Если провайдер поддерживает совместимый S3 API, AWS CLI можно направить на его собственный endpoint через --endpoint-url. При этом конкретные возможности — policies, ACL, versioning, Object Lock и другие функции — могут отличаться от Amazon S3.

Почему aws s3 ls возвращает AccessDenied, а доступ к конкретному bucket работает?

Команда просмотра всех bucket требует отдельного разрешения. Пользователь может иметь доступ к конкретному bucket и его объектам, но не иметь права получать общий список хранилищ аккаунта.

Поэтому AccessDenied в таком случае не означает, что credentials настроены неправильно.

Что произойдет, если повторно загрузить файл с тем же object key?

Новый объект заменит существующий под тем же ключом. Если versioning не включен, прежняя версия обычно перестает быть доступной. Для резервных копий поэтому полезно использовать уникальные ключи или включать versioning, если провайдер его поддерживает.

Можно ли один профиль AWS CLI использовать для нескольких S3-провайдеров?

Технически можно постоянно менять endpoint и credentials, но это быстро приводит к путанице. Надежнее создать отдельный профиль для каждого провайдера или назначения: например, prod-backups, archive-storage и media-storage.

Почему sync --delete считается опасной командой?

Параметр --delete удаляет на стороне назначения объекты, которых нет в источнике. Если перепутать bucket, префикс или направление синхронизации, можно удалить нужные данные.

Перед такой операцией желательно сначала выполнить ту же команду с --dryrun и проверить запланированные изменения.

В чем разница между aws s3 и aws s3api?

aws s3 предоставляет высокоуровневые команды вроде cp, sync, ls и rm, удобные для повседневной работы с файлами.

aws s3api ближе к отдельным операциям S3 API и предоставляет более точный контроль. Он полезен, например, для работы с настройками bucket, policies и других функций, которые не представлены высокоуровневыми командами.

Нужно ли делать отдельные резервные копии данных, если они уже находятся в Object Storage?

Да, если данные действительно важны. Само по себе Object Storage не защищает от удаления с действительными credentials, ошибочной перезаписи или некорректного sync --delete.

Для критичных данных стоит использовать versioning, Object Lock или независимую резервную копию — в зависимости от возможностей конкретного провайдера.

Список источников

  1. AWS Documentation — Configuration and credential file settings in the AWS CLI
  2. Amazon S3 Documentation — Authenticating Requests (AWS Signature Version 4)
  3. AWS Documentation — AWS CLI s3 sync command reference
  4. Amazon S3 Documentation — Required permissions for Amazon S3 API operations

Подпишитесь на нашу рассылку и получайте статьи и новости

    Ознакомьтесь с другими нашими материалами