Непрерывная доставка с помощью GitHub Actions

CloudFormation - это сервис в Amazon Web Services. Он позволяет описывать инфраструктуру как код. Вы можете определить необходимые сервисы и зависимости между ними в файлах шаблонов в формате .yml или .json.

Если мы решим хранить файлы шаблонов на GitHub, мы хотели бы иметь автоматическое развертывание в AWS с каждой новой фиксацией в нашем репозитории. Этого можно добиться с помощью GitHub Actions.

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

Создать пользователя IAM

GitHub взаимодействует с AWS через API. Для этого нам нужны идентификатор ключа доступа и секретный ключ доступа. Итак, нам нужно сначала создать пользователя IAM и сгенерировать для него учетные данные. Рекомендуется хранить учетные данные в секрете GitHub Actions.

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

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "cloudformation:*"
            ],
            "Resource": "*"
        }
    ]
}

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

Настройка рабочего процесса

Это обычный шаг для создания любого действия GitHub. Вам необходимо создать файл .yml в каталоге .github/workflows проекта. Этот файл определяет все необходимые шаги для выполнения. Документация GitHub Actions описывает структуру конфигурации.

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

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:        
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}        
        aws-region: eu-west-2
    - name: Deploy CloudFormation Stack
      uses: aws-actions/[email protected]         
      with:
        name: RootStack
        template: root_stack.yml

Это минимальная настройка рабочего процесса.

Подготовить стек CloudFormation

Лично это была самая сложная задача. Мой стек CloudFormation использует вложенные стеки в шаблонах. Каждый вложенный стек определяется в отдельном файле шаблона.

Например, файл шаблона user_template.yml создает нового пользователя IAM. Корневой стек будет ссылаться на файл шаблона по его пути.

AWSTemplateFormatVersion: '2010-09-09'
Resources:
  IamStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: user_template.yml

Развертывание этого стека постоянно терпело неудачу. Не удалось найти файл шаблона, даже если он был там. Оказалось, что GitHub Action не запускает команду package.

Согласно документации CloudFormation, все артефакты, определенные в шаблоне, необходимо упаковать перед развертыванием. Когда команда package завершится, все артефакты будут загружены в корзину S3, и все ссылки на файлы шаблонов будут соответственно обновлены.

aws cloudformation package\
  --template-file root_stack.yml \ 
  --s3-bucket uploading-bucket \
  --output-template-file root_stack.packaged.yml

В приведенном выше примере команда package из интерфейса командной строки AWS выгружает все ссылочные шаблоны из корневого стека в корзину S3 uploading-bucket. Затем он сгенерирует новый файл с именем root_stack.packaged.yml, который будет иметь точно такую ​​же структуру, что и исходный файл стека, но все ссылки на вложенные файлы шаблонов будут заменены ссылками на файлы в корзине S3.

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

Заключение

CloudFormation - мощный сервис от AWS. В то же время GitHub остается отличным местом для размещения исходных файлов. С помощью GitHub Actions можно построить эффективный конвейер развертывания, чтобы следовать лучшим практикам непрерывной доставки.