Построение CI/CD для проекта на базе Docker с использованием CodeBuild, CodeDeploy и Lambda

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

CI/CD-пайплайны автоматизируют процессы создания, тестирования и развертывания программного обеспечения, позволяя командам быстро и надежно выпускать обновления. В этой статье рассмотрим, как создать пайплайн с помощью AWS, как использовать CodeBuild для запуска при размещении кода в ветке. Также разберем, как запускать тесты, затем собирать и размещать образ Docker в ECR, и сохранять артефакты кода в S3, после чего можно использовать функцию Lambda для запуска CodeDeploy, которая развернет код на группе EC2-инстансов.

Почему бы просто не использовать CodePipeline?! Ответ - не везде это возможно.

А что, если я собираюсь отправлять образы в ECR, то зачем использовать CodeDeploy для отправки кода в EC2-инстансы? В некоторых случаях вы не сможете получить код из частного хранилища в ECR.

Вот схематический обзор того, что мы будем делать: 

Наш код

Для примера я собираюсь использовать простое приложение на Python для создания API с помощью flask

# app.py
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return "Hello, Docker!"

if __name__ == '__main__':
    app.run(host='0.0.0.0',port=80)

Тесты важны для кода: в случае неудачи мы не развернем в продакшене код с ошибками.

# tests/test_app.py
from app import app

def test_index_route_success_status():
    response = app.test_client().get('/')
    assert response.status_code == 200
    
def test_index_route_success_text():
    response = app.test_client().get('/')
    assert response.data.decode('utf-8') == 'Hello, Docker!'

И, наконец, мы пишем Dockerfile

# Dockerfile
FROM python:3.8-slim

# Set the working directory in the container
WORKDIR /app

# Install the dependencies
RUN pip install flask pytest

# Copy the application code to the container
COPY . .

# Set the command to run the application
CMD ["python", "app.py"]

Теперь наш код готов к переносу в основную ветку и развертыванию.

CodeBuild

Теперь откройте AWS CodeBuild и создайте проект для построения, добавьте имя проекта и источник кода — bitBucket в нашем примере — и ветку, которую необходимо считывать. Включите webhooks.

И в разделе «Окружение» необходимо включить привилегированный режим, поскольку мы хотим собирать Docker-образы.

И если мы хотим передать информацию в процесс сборки, мы можем использовать переменные среды. Здесь мы должны передать несколько значений: 


AWS_DEFAULT_REGION: регион, который вы используете

IMAGE_TAG: тег для образа Docker

IMAGE_REPO_NAME: имя репозитория ECR

AWS_ACCOUNT_ID: идентификатор учетной записи пользователя

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

В артефактах мы выберем S3, затем выберем хранилище, куда мы хотим их отправить. Артефакты должны быть в формате Zip.

buildspec.yml

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

#buildspec.yml
version: 0.2

phases:
  pre_build:
    commands:
       - echo Logging in to Amazon ECR...
       - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
  build:
    commands:
      - echo run tests first
      - pip install flask pytest
      - python3 -m pytest --junitxml=/usr/tests/test-report.xml
      - echo Build started on `date`
      - echo Building the Docker image...          
      - docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG .
      - docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG 
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker image...
      - docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
      
Reports:
  pytest-reports:
    files:
      - test-report.xml
    base-directory: /usr/tests/
    file-format: JUNITXML

Artifacts:
  type: zip
  files:
    - '**/*'

На этапе pre_build мы вошли в нашу учетную запись ECR

На этапе сборки мы запустили тест, сохранили результат в файл и собрали образ

На этапе post_build мы поместили docker в хранилище.

*Данные, переданные из переменных окружения, которые мы задали в консоли, могут быть доступны со знаком $

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

Артефакты:

CodeDeploy

Создайте приложение и затем создайте группу для развертывания. Развернем для одного инстанса EC2 с тегом «env» и значением «dev».

И отключите функцию балансировки нагрузки, в этом случае она нам не нужна. Лучше установить Codedeploy вручную.

Для работы CodeDeploy необходимо написать шаги, что делать, когда инстанс в установочной группе получает код. Эти шаги записываются в appspec.yml, файл также должен располагаться в корневой директорий проекта.

appspec.yml
version: 0.0
os: linux
# this to copy all files in the project to spacfic location
files:
  - source: /
    destination: /usr/src/app/
# overrite file if they are already there
file_exists_behavior: OVERWRITE

hooks:
  BeforeInstall:
    - location: scripts/before_install.sh
      runas: root
  ApplicationStart:
    - location: scripts/application_start.sh
      runas: root

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

#scripts/before_install.sh

#stop all running containers
docker kill $(docker ps -q)

#delete all images
docker rmi -f $(docker images -aq)

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

#scripts/application_start.sh

# build the docker image
docker build -f /usr/src/app/Dockerfile /usr/src/app/ -t myapp

# run the container
docker run -d -p 80:80 myapp

В запуске приложения мы собираем наш образ и затем запускаем его на порту 80

*CodeDpoly должен быть установлен на целевом инстансе EC2. Иногда он не подключается, так что вам придется перезапустить процесс или весь инстанс.

Вот окончательная структура нашего проекта:

Lambda Functions

Необходимо используем эту функцию для  развертывания всякий раз, когда CodeBuild размещает новые артефакты в S3. Можно использовать Python и библиотеку boto3, которая позволяет писать программное обеспечение, использующее такие сервисы, как Amazon S3 и Amazon EC2.

import boto3

def lambda_handler(event, context):
    # Get the S3 bucket and object information from the event
    s3_bucket = event['Records'][0]['s3']['bucket']['name']
    s3_key = event['Records'][0]['s3']['object']['key']

    # Create a CodeDeploy client
    codedeploy_client = boto3.client('codedeploy')

    # Create a deployment with the S3 revision
    response = codedeploy_client.create_deployment(
        applicationName='codedeply-ec2',            #change this to codedepoly application name
        deploymentGroupName='codedeploy-ec2',       #change this to deployment group name
        revision={
            'revisionType': 'S3',
            's3Location': {
                'bucket': s3_bucket,
                'key': s3_key,
                'bundleType': 'zip'
            }
        }
    )

    # Print the deployment ID
    deployment_id = response['deploymentId']
    print(f"Deployment ID: {deployment_id}")
От редакции

Возможности CI/CD позволяют специалистам автоматизировать процессы интеграции и регулярно выпускать ПО высокого качества. На курсе «CI/CD на примере Gitlab CI» мы учим принципам CI/CD: конвейерному методу разработки, работе с пайплайнами, билдами и артефактами. Узнать больше о программе и записаться на курс вы можете на нашем сайте: https://slurm.io/gitlab-ci-cd

Источник: https://habr.com/ru/companies/southbridge/articles/747704/


Интересные статьи

Интересные статьи

Каждый собственник вне зависимости от размеров своего предприятия хочет, чтобы его прибыли росли. Рост прибыли подразумевает рост самого бизнеса, увеличение штата сотрудников, средств труда, повыше...
Миллионы людей используют веб-приложения, построенные на основе ASP.NET Core. Поэтому мы решили улучшить работу PVS-Studio при анализе таких проектов. Для демонстрации результата нашей работы мы прове...
Продолжение истории с электросаксофоном, написанной в прошлом году.Год прошел, решил рассказать, что за это время произошло. А произошло многое:• Электросакс изменился до неузнаваемости• Из Pet-проект...
Финансовый университет при Правительстве РФ и Федеральный научный агроинженерный центр ВИМ при технологической поддержке Microsoft разработали умного робота для сбора урожая яблок. Ученым...
Вчера, полностью серьезно и без каких-либо шуток-прибауток, компания Cloudflare анонсировала свой новый продукт — VPN-сервис на базе DNS-приложения 1.1.1.1 для мобильных устройств с использование...