Теперь, после проверки, связки Cloudflare и Yandex.CLoud S3, можно перенести этот сайт на Yandex. Придется переделать Gitlab CI скрипты, но по большому счету, переделка будет связана с условиями запуска этапов. Здесь же речь пойдет об загрузке файлов в S3 хранилище.

Варианты решений

В документации Yandex.Cloud S3 есть несколько вариантов загрузки:

  • консольные клиенты;
  • файловые браузеры;
  • SDK;
  • FUSE;
  • FTP.

Из всего этого нас интересуют именно консольные клиенты, так как именно их можно без проблем использовать в .gitlab-ci.yml. По остальным вариантам сказать особо нечего, файловые браузеры не подходят для использования в скриптах, SDK предполагают интеграцию в приложения, FUSE (лично мое мнение) это overkill для просто загрузки файлов, а FTP это Docker образ с FTP сервером и какой-то магической загрузкой внутри.

Так как для универсальности нужно выбрать консольный клиент и для выбора в документации есть два:

Лично мой выбор оказался AWS CLI, так как для этого инструмента в Gitlab CI уже есть готовый и настроенный Docker образ registry.gitlab.com/gitlab-org/cloud-deploy/aws-base. В нем нужно будет указать переменные окружения и endpoint-url.

Через образ от Gitlab

Вот так в файле .gitlab-ci.yml записывается задача:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
upload-prod:
  stage: upload
  image: registry.gitlab.com/gitlab-org/cloud-deploy/aws-base:latest
  needs:
    - job: build-prod
      artifacts: true
  script:
    - aws s3 sync ./public/ "$AWS_S3_BUCKET_NAME" --delete --endpoint-url "https://storage.yandexcloud.net"
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
  environment:
    name: production
    action: prepare

Как видно тут –endpoint-url приходится указывать полностью “руками”. В современной версии AWS CLI для каждого сервиса можно указать свой endpoint-url через переменные окружения. Проблема в том, что образ от Gitlab давненько не обновляется. Минимальная версия для работы с переменной окружения AWS_ENDPOINT_URL_S3 2.13.0:

2.13.0

feature:configuration: Configure the endpoint URL in the shared configuration file or via an environment variable for a specific AWS service or all AWS services.

В образе от Gitlab версия 2.9.8 (на момент написания):

1
2
$ aws --version
aws-cli/2.9.8 Python/3.9.11 Linux/5.15.154+ exe/x86_64.ubuntu.20 prompt/off

Через образ от AWS

Для работы через образ AWS нужно будет немного изменить .gitlab-ci.yml:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
upload-prod:
  stage: upload
  image:
    name: amazon/aws-cli:latest
    entrypoint: [ "" ]
  needs:
    - job: build-prod
      artifacts: true
  script:
    - aws s3 sync ./public/ "$AWS_S3_BUCKET_NAME" --delete
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
  environment:
    name: production
    action: prepare

Здесь entrypoint-url задается через переменную CI AWS_ENDPOINT_URL_S3. Стоит обратить внимание на запись блока image. Она имеет такой вид из-за особенностей образа от AWS.

Дополнительные действия

Для работы нужно будет создать переменные CI:

  • AWS_ACCESS_KEY_ID;
  • AWS_SECRET_ACCESS_KEY;
  • AWS_DEFAULT_REGION;
  • AWS_ENDPOINT_URL_S3.

Так же нужно настроить сервисный аккаунт, дать ему права доступа к бакету и настроить ключи по мануалу. Это описано в документации Yandex.Cloud для S3.