Приветствую! Сегодня я расскажу вам, как настроить CI/CD для AWS Lambda с использованием AWS CodePipeline и AWS SAM CLI. Если вы хотите автоматизировать процесс деплоя серверлесс-приложений и избавиться от рутины, то эта статья для вас.
Что нам понадобится
Перед началом работы убедитесь, что у вас есть:
-
AWS Account: доступ к облачным сервисам AWS.
-
AWS CLI: инструмент командной строки для взаимодействия с AWS.
-
AWS SAM CLI: утилита для разработки и деплоя серверлесс-приложений.
-
AWS CodePipeline: сервис для создания CI/CD пайплайнов.
-
AWS CodeBuild: для сборки и тестирования вашего кода.
-
GitHub или AWS CodeCommit: репозиторий для хранения исходного кода.
-
S3 Bucket: хранилище для артефактов сборки.
Настройка окружения
После всех установок необходимо настроить AWS CLI, чтобы он мог взаимодействовать с вашим аккаунтом AWS:
aws configure
Вам будет предложено ввести:
-
AWS Access Key ID и AWS Secret Access Key: их можно получить в AWS Console в разделе IAM → Users → [Ваш пользователь] → Security credentials.
-
Default region name: указываем регион, в котором будут развёрнуты ресурсы (например,
us-east-1
). -
Default output format: обычно ставят
json
.
Создание серверлесс-приложения
Теперь создадим простое серверлесс-приложение, которое будем деплоить.
Запустим команду инициализации:
sam init --runtime python3.8 --name my-lambda-app --app-template hello-world
-
--runtime python3.8
: выбираем язык и версию. -
--name my-lambda-app
: имя нашего проекта. -
--app-template hello-world
: используем шаблон «Hello World».
В результате появится структура проекта с базовой Lambda-функцией.
Дерево проекта будет выглядеть так:
my-lambda-app/ ├── README.md ├── events/ │ └── event.json ├── hello_world/ │ ├── app.py │ └── requirements.txt ├── template.yaml └── tests/ └── unit/ └── test_handler.py
-
app.py
: содержит код Lambda-функции. -
template.yaml
: описывает инфраструктуру и конфигурацию для AWS. -
tests/
: содержит тесты для нашей функции.
Файл template.yaml
является шаблоном CloudFormation и определяет ресурсы, которые будут созданы в AWS. Папка tests/
содержит тесты.
В файле hello_world/app.py
находится простой обработчик:
import json def lambda_handler(event, context): message = "Hello, World!" return { 'statusCode': 200, 'body': json.dumps({'message': message}) }
Эта функция возвращает простой JSON с сообщением.
Локальное тестирование функции
Прежде чем деплоить функцию, убедимся, что она работает локально.
Переходим в корневой каталог проекта и установим необходимые зависимости:
pip install -r hello_world/requirements.txt
Если requirements.txt
пуст, значит дополнительных пакетов не требуется.
SAM CLI позволяет запускать функцию локально, имитируя API Gateway:
sam local start-api
Вы увидите сообщение, что сервер запущен на http://127.0.0.1:3000/hello
.
Открываем новый терминал и выполняем запрос:
curl http://127.0.0.1:3000/hello
Вы должны получить ответ:
{"message": "Hello, World!"}
Это означает, что функция работает корректно и готова к деплою.
Подготовка к деплою
Перед тем как настроить CI/CD, нужно подготовить инфраструктуру для деплоя.
AWS SAM использует S3 для хранения артефактов сборки. Создадим бакет:
aws s3 mb s3://my-lambda-artifacts-bucket
Важно заменить my-lambda-artifacts-bucket
на уникальное имя бакета.
S3 бакет необходим для хранения упакованного кода функции, который затем используется при деплое с помощью CloudFormation.
Соберём приложение и подготовим его к деплою:
sam package \ --output-template-file packaged.yaml \ --s3-bucket my-lambda-artifacts-bucket
-
sam package
: упаковывает ваш код и загружает его в S3, обновляя ссылки в шаблоне. -
--output-template-file
: файл, в который будет записан обновлённый шаблон CloudFormation. -
--s3-bucket
: бакет, куда будут загружены артефакты.
Эта команда подготавливает всё необходимое для деплоя и генерирует обновлённый шаблон, который указывает на артефакты в S3.
Можно проверить деплой вручную, чтобы убедиться, что всё работает:
sam deploy \ --template-file packaged.yaml \ --stack-name my-lambda-stack \ --capabilities CAPABILITY_IAM
-
sam deploy
: выполняет деплой вашего приложения в AWS. -
--stack-name
: имя стека CloudFormation, который будет создан или обновлён. -
--capabilities
: подтверждаем создание IAM ролей, необходимых для работы функции.
После успешного деплоя вы получите URL для вызова функции. Попробуйте вызвать её и убедитесь, что она работает как ожидается.
Настройка репозитория
Для автоматизации нужен репозиторий, где будет храниться код.
В корне проекта инициализируем репозиторий:
git init git add . git commit -m "Initial commit"
Это позволяет отслеживать изменения в коде и интегрировать систему контроля версий с CI/CD пайплайном.
Создадим новый репозиторий на GitHub и свяжем его с локальным:
git remote add origin https://github.com/yourusername/my-lambda-app.git git push -u origin master
Теперь код доступен в удалённом репозитории, и можно настроить автоматизацию на основе изменений в нём.
Настройка CodeBuild
CodeBuild будет отвечать за сборку и тестирование приложения.
Создадим файл buildspec.yml
в корне проекта со следующим содержанием:
version: 0.2 phases: install: runtime-versions: python: 3.8 commands: - pip install aws-sam-cli pre_build: commands: - pip install -r hello_world/requirements.txt - pip install -r tests/requirements.txt - python -m pytest tests/unit -v - sam validate --template template.yaml build: commands: - sam build post_build: commands: - sam package --s3-bucket my-lambda-artifacts-bucket --output-template-file packaged.yaml artifacts: files: - packaged.yaml
В файле tests/unit/test_handler.py
добавляем:
import json from hello_world import app def test_lambda_handler(): event = {} context = {} response = app.lambda_handler(event, context) data = json.loads(response['body']) assert response['statusCode'] == 200 assert data['message'] == 'Hello, World!'
Это простой тест, который проверяет корректность ответа функции.
Создадим файл tests/requirements.txt
и добавим:
pytest
Это необходимо для установки pytest
на этапе сборки.
Настройка CodePipeline
Теперь настроим сам пайплайн, который будет автоматизировать процесс от коммита до деплоя.
Переходим в консоль AWS CodePipeline и создаём новый пайплайн.
Шаги настройки:
-
Pipeline settings:
-
Name:
MyLambdaPipeline
. -
Service role: создаём новую роль или используем существующую с необходимыми правами.
-
-
Add source stage:
-
Source provider: GitHub.
-
Connect to GitHub: предоставляем доступ AWS к вашему репозиторию.
-
Repository: выбираем репозиторий
my-lambda-app
. -
Branch:
master
.
-
-
Add build stage:
-
Build provider: AWS CodeBuild.
-
Project configuration: создаём новый проект.
-
Environment:
-
Managed image: используем стандартный образ
aws/codebuild/standard:5.0
. -
Runtime(s): Python 3.8.
-
-
Buildspec: используем
buildspec.yml
из репозитория.
-
-
-
Add deploy stage:
-
Deploy provider: AWS CloudFormation.
-
Action mode: Create or update a stack.
-
Stack name:
my-lambda-stack
. -
Template:
packaged.yaml
. -
Capabilities: отметьте
CAPABILITY_IAM
.
-
После настройки пайплайна сохраняем его.
Сделаем изменение в коде, например, обновим сообщение в функции:
def lambda_handler(event, context): message = "Hello, AWS Lambda!" return { 'statusCode': 200, 'body': json.dumps({'message': message}) }
Закоммитим и запушим изменения:
git add . git commit -m "Updated message" git push origin master
Переходим в CodePipeline и убеждаемся, что пайплайн автоматически запустился и прошёл все этапы.
Управление конфигурацией и секретами
Для управления настройками и секретами рекомендуется использовать переменные окружения и сервисы AWS.
Обновим template.yaml
, чтобы передавать переменные окружения в функции:
Globals: Function: Environment: Variables: STAGE: !Ref Stage Parameters: Stage: Type: String Default: dev
В коде функции можно получить переменную STAGE
:
import os def lambda_handler(event, context): stage = os.environ.get('STAGE', 'dev') message = f"Hello from {stage} stage!" return { 'statusCode': 200, 'body': json.dumps({'message': message}) }
Теперь используем AWS Systems Manager Parameter Store для хранения секретов и конфиденциальных данных.
aws ssm put-parameter --name "/myapp/secret" --value "mysecretvalue" --type SecureString
Доступ к параметру в коде:
import boto3 def get_secret(): ssm = boto3.client('ssm') parameter = ssm.get_parameter(Name='/myapp/secret', WithDecryption=True) return parameter['Parameter']['Value']
Роль Lambda должна иметь права на ssm:GetParameter
. Это можно сделать, добавив соответствующую политику к роли функции.
Мониторинг и логирование
Важно иметь возможность отслеживать работу функции и быстро находить ошибки.
В начале файла app.py
добавим:
import logging logger = logging.getLogger() logger.setLevel(logging.INFO)
Внутри функции используем:
def lambda_handler(event, context): logger.info('Received event: %s', event) # Основная логика
Это позволит записывать логи, которые можно просматривать в AWS CloudWatch.
Обновим template.yaml
, чтобы включить X-Ray:
Globals: Function: Tracing: Active
AWS X-Ray позволяет собирать данные о производительности функции, создавать трассировки и визуализировать поток данных через приложение.
Обработка ошибок
Оборачивайте важные части кода в блоки try-except
для отлова исключений:
Globals: Function: Environment: Variables: STAGE: !Ref Stage Parameters: Stage: Type: String Default: dev
Это позволит записать ошибку в логи и, при необходимости, повторно вызвать функцию.
В template.yaml
добавьте параметры повторного вызова:
import os def lambda_handler(event, context): stage = os.environ.get('STAGE', 'dev') message = f"Hello from {stage} stage!" return { 'statusCode': 200, 'body': json.dumps({'message': message}) }
Это позволит автоматом повторять выполнение функции в случае ошибок.
Заключение
Если у вас возникли вопросы или вы хотите поделиться своим опытом, пишите в комментариях.
Сегодня в 20:00 пройдет открытый урок «Mock интервью на позицию Cloud Solution Architect» — поговорим, как уверенно пройти все этапы интервью. Если актуально — записывайтесь на урок на странице курса «Cloud Solution Architecture».
ссылка на оригинал статьи https://habr.com/ru/articles/852328/
Добавить комментарий