Построение конвейера непрерывной доставки с использованием современного API CDK Pipelines
22 декабря 2022 г.В этом пошаговом руководстве мы узнаем, как создать непрерывную доставку с использованием конвейеров CDK и современного API. Прежде чем обсуждать конвейеры CDK, давайте сначала обсудим несколько моментов, чтобы мы все были на одной волне.
Что такое конвейер CI/CD?
Конвейер CI/CD автоматизирует процесс доставки программного обеспечения. Это ряд шагов, которые происходят, когда вы отправляете свои изменения до развертывания, например создание кода, запуск тестов и развертывание приложения и служб.
Почему CDK Pipelines?
AWS CDK
– это среда разработки программного обеспечения с открытым исходным кодом, позволяющая определять облачную инфраструктуру. AWS CDK поддерживает множество языков, включая Typescript, Python, C# и Java. Подробнее об AWS CDK можно узнать из документации здесь, а я написал руководство для начинающих. в моем блоге здесь.
Если вы уже используете AWS CDK для определения своей инфраструктуры, проще использовать конвейеры CDK. Это бессерверное приложение, и вы платите только за то, что используете.
Конвейеры CDK являются самоизменяющимися. Это означает, что если вы добавите какой-либо этап или стек в свой конвейер, конвейер CDK перенастроится для развертывания этих новых этапов или стеков. р>
Проект
В этом руководстве мы собираемся создать конвейер с помощью CDK Pipeline
для простого бессерверного проекта. Поскольку основная цель этого руководства — объяснить концепции и реализацию конвейеров CDK с использованием современного API, фактическое приложение (бессерверный проект) намеренно сделано простым. Однако та же концепция применима даже к крупномасштабным приложениям. Единственная разница заключается в развертывании вашего приложения.
В этом проекте лямбда-функция будет вызываться всякий раз, когда объект загружается в корзину S3.
Архитектура конвейера CDK
Ниже представлена общая схема архитектуры Code Pipeline.
Наш код находится в репозитории GitHub. Сначала мы создадим подключение к репозиторию GitHub с помощью AWS CodeStar
в консоли AWS (подробные инструкции приведены далее в этой статье).
Каждый раз, когда пользователь отправляет какие-либо изменения на GitHub, AWS CodeStar обнаруживает изменения, и ваш конвейер кода AWS начинает выполняться. AWS CodeBuild создаст ваш проект, а AWS CodeDeploy развернет ресурсы AWS, необходимые для проекта (корзина S3 и функция Lambda)
Создание проекта AWS CDK
Перед созданием нового проекта CDK вы должны установить пакет aws-cdk
глобально. Если нет, вы можете установить с помощью приведенной ниже команды
npm i -g aws-cdk
Затем вы можете выполнить приведенные ниже команды, чтобы создать новый проект CDK.
mkdir aws-cdk-pipelines
cd aws-cdk-pipelines
cdk init app --language=typescript
Как только приложение CDK будет создано, оно предоставит шаблон по умолчанию для создания очереди SQS (код с комментариями), как показано ниже.
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
// import * as sqs from 'aws-cdk-lib/aws-sqs';
export class AwsCdkPipelinesStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// The code that defines your stack goes here
// example resource
// const queue = new sqs.Queue(this, 'AwsCdkPipelinesQueue', {
// visibilityTimeout: cdk.Duration.seconds(300)
// });
}
}
Поскольку SQS нам не понадобится, вы можете удалить закомментированные строки.
Создать репозиторий GitHub
Мы создадим новый репозиторий GitHub и отправим изменения (проект CDK, который мы создали ранее).
git remote add origin git@github.com:<your-github-username>/<your-repo-name>.git
git branch -M main
git push -u origin main
Этот репозиторий GitHub понадобится нам на следующем этапе для создания подключения к AWS CodeStar. Соединение с AWS CodeStar — это соединение между AWS CodePipeline и вашим репозиторием GitHub.
Создание подключения к AWS CodeStar
Вы можете перейти к сервису AWS CodePipeline в консоли AWS и выбрать settings
в меню слева, как показано на снимке экрана ниже
Нажмите кнопку "Создать подключение", и вы увидите показанный ниже экран. Вы можете выбрать Github
в качестве провайдера, ввести имя подключения и нажать кнопку «Подключиться к GitHub»
После того, как вы нажмете кнопку "Подключиться к GitHub", вы увидите показанный ниже экран и сможете нажать кнопку "Установить новое приложение"
Как только вы нажмете кнопку «Установить новое приложение», вы будете перенаправлены на GitHub с просьбой одобрить доступ к репозиторию. Экран будет выглядеть так, как показано ниже.
Либо вы можете предоставить доступ ко всем репозиториям, либо к определенному репозиторию. Рекомендуется предоставлять доступ к определенному репозиторию. Мы выбрали созданный ранее репозиторий GitHub.
Как только вы нажмете «Сохранить», соединение будет создано.
Обратите внимание, что мы будем использовать ARN (имя ресурса Amazon) этого подключения в нашем конвейере.
Создание конвейера AWS CDK
AWS CDK предоставляет конструкцию L2 для создания конвейеров CDK
Мы хотим сделать следующие шаги как часть нашего конвейера
* Подключитесь к источнику (в нашем случае репозиторий GitHub)
* Установить пакеты
* Построить проект
* Создайте шаблоны cloudformation
из кода CDK, которые затем можно развернуть
Все эти 4 шага можно выполнить с помощью ShellStep
. ShellStep
— это конструкция, предоставляемая CDK, где вы можете выполнять команды сценария оболочки в конвейере. Вы можете указать ShellStep
для свойства synth
, как показано ниже.
const pipeline = new pipelines.CodePipeline(this, 'Pipeline', {
synth: new pipelines.ShellStep('Synth', {
// Use a connection created using the AWS console to authenticate to GitHub
// Other sources are available.
input: pipelines.CodePipelineSource.connection(
'mugiltsr/aws-cdk-pipelines',
'main',
{
connectionArn:
'arn:aws:codestar-connections:us-east-1:853185881679:connection/448e0e0b-0066-486b-ae1c-b4c8be92f79b', // Created using the AWS console
}
),
commands: ['npm ci', 'npm run build', 'npx cdk synth'],
}),
dockerEnabledForSynth: true,
});
Свойство input
в synth
представляет исходное соединение GitHub — оно принимает 3 параметра
- Репозиторий GitHub следует шаблону — <владелец>/<имя репозитория>. Мой идентификатор GitHub —
mugiltsr
, а имя моего репозитория —aws-cdk-pipelines
- Имя ветки, для которой должен быть запущен конвейер. Поскольку я хочу, чтобы конвейер выполнялся, когда код помещается в ветку
main
, я указалmain
в качестве имени ветки connectionArn
— это ARN (имя ресурса Amazon) подключения, которое мы создали ранее в консоли AWS.
Свойство commands
представляет собой массив строк, содержащий команды, которые необходимо выполнить.
npm ci
— эта команда предназначена для установки пакетов в режиме CInpm run build
— команда для сборки проектаnpm run test
– при желании вы можете выполнить тестовые случаиnpx cdk synth
. Командаsynth
предназначена для создания шаблонов формирования облака из нашего кода CDK .
dockerEnabledForSynth
: установите для этого свойства значение true, если мы хотим включить докер для шага synth
. Поскольку мы собираемся использовать объединение для создания лямбда-функций, мы должны установить для этого свойства значение true.
Развертывание нашего стека
Зафиксируйте и отправьте эти изменения в репозиторий GitHub.
Только в первый раз нам нужно развернуть стек с помощью команды cdk deploy
. После выполнения команды будет создан и запущен AWS Code Pipeline.
Со следующего раза нам не нужно развертывать наш код вручную. Как видно на снимке экрана ниже, конвейер успешно создан и запущен.
Создание нашего бессерверного приложения
Наше бессерверное приложение довольно простое и состоит из следующих компонентов
- Корзина S3
- Лямбда-функция
- Добавить источник событий S3 для лямбда-функции
У нас будут все эти компоненты в новом стеке AwsS3LambdaStack
, который будет находиться в каталоге lib
рядом с нашим стеком конвейера
export class AwsS3LambdaStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// create s3 bucket
// create lambda function
// add s3 event source for lambda function
}
}
Создание корзины S3
Ниже приведен код CDK для создания корзины S3
const bucket = new s3.Bucket(this, 'S3Bucket', {
bucketName: `aws-lambda-s3-132823`,
autoDeleteObjects: true,
removalPolicy: RemovalPolicy.DESTROY,
});
Он имеет 3 свойства: bucketName
представляет имя корзины, autoDeleteObjects
сообщает, должны ли объекты в корзине удаляться при сносе стека, removalPolicy
указывает, следует ли удалять ведро при остановке стека. Только свойство bucketName
является обязательным.
Создание лямбда-функции
Мы создаем простую лямбда-функцию с Node16 в качестве среды выполнения. Настраиваем свойства таймаута и размера памяти и указываем путь к лямбда-функции.
const nodeJsFunctionProps: NodejsFunctionProps = {
bundling: {
externalModules: [
'aws-sdk', // Use the 'aws-sdk' available in the Lambda runtime
],
},
runtime: Runtime.NODEJS_16_X,
timeout: Duration.minutes(3), // Default is 3 seconds
memorySize: 256,
};
const readS3ObjFn = new NodejsFunction(this, 'readS3ObjFn', {
entry: path.join(__dirname, '../src/lambdas', 'read-s3.ts'),
...nodeJsFunctionProps,
functionName: 'readS3ObjFn',
});
bucket.grantRead(readS3ObjFn);
Поскольку мы используем NodeJsFunction
, он будет использовать докер для связывания лямбда-функции. Именно поэтому мы установили для свойства dockerEnabledForSynth
значение true в конвейере.
Добавление S3 в качестве источника событий для Lambda
Мы хотим, чтобы лямбда-выражение срабатывало при создании объекта в корзине S3, и код ниже CDK делает это
readS3ObjFn.addEventSource(
new S3EventSource(bucket, {
events: [s3.EventType.OBJECT_CREATED],
})
);
Код лямбда-функции
Мы просто печатаем содержимое загруженного объекта S3. Однако вы можете обработать файл в соответствии с потребностями вашего приложения. Ниже приведен код лямбда-функции, которая печатает содержимое файла.
import { S3Event } from 'aws-lambda';
import * as AWS from 'aws-sdk';
export const handler = async (
event: S3Event,
context: any = {}
): Promise<any> => {
for (const record of event.Records) {
const bucketName = record?.s3?.bucket?.name || '';
const objectKey = record?.s3?.object?.key || '';
const s3 = new AWS.S3();
const params = { Bucket: bucketName, Key: objectKey };
const response = await s3.getObject(params).promise();
const data = response.Body?.toString('utf-8') || '';
console.log('file contents:', data);
}
};
Создание бессерверного приложения
Мы собираемся использовать наш лямбда-стек в нашем приложении. Назовем это приложение MyApplication
. Вы можете назвать все, что хотите.
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { AwsS3LambdaStack } from './lambda-stack';
export class MyApplication extends cdk.Stage {
constructor(scope: Construct, id: string, props?: cdk.StageProps) {
super(scope, id, props);
const lambdaStack = new AwsS3LambdaStack(this, 'lambdaStack');
}
}
Обратите внимание, что мы расширяем конструкцию cdk.Stage
, чтобы использовать ее в качестве этапа в нашем конвейере.
Добавление этапа в нашу воронку
Вы можете использовать приведенный ниже код CDK, чтобы добавить наше приложение в качестве этапа конвейера
pipeline.addStage(new MyApplication(this, 'lambdaApp'));
Зафиксируйте и отправьте эти изменения в ветку main
. Обратите внимание, что нам не нужно развертывать стек вручную.
«Конвейер кода» будет самоизменяться и создавать дополнительные шаги, развертывать корзину S3 и создавать лямбда-функцию.
Зафиксируйте и отправьте эти изменения в ветку main
. Обратите внимание, что нам не нужно развертывать стек вручную.
«Конвейер кода» самоизменится, создаст дополнительные шаги, развернет корзину S3 и создаст лямбда-функцию
Тестирование
Чтобы протестировать наше фактическое бессерверное приложение, я загружаю в корзину простой текстовый файл (скриншот показан ниже)
Наша лямбда-функция будет вызвана, и вы можете увидеть то же самое в журналах выполнения
Вывод:
Надеемся, вы узнали о создании конвейеров CI/CD с помощью конвейеров CDK. Из-за этой самоизменяющейся функции проще построить CICD Pipeline. п
Оригинал