AWS CodeArtifact и процесс управления пакетами – лучшие практики для интеграции

Оригинал статьи: ссылка (John Standish, AWS Solutions Architect and Yogesh Chaturvedi, AWS Solutions Architect)

Чаще всего, мы используем репозитории артефактов для хранения и совместного использования программного обеспечения или пакетов развёртывания. Артефакты, расположенные в централизованном хранилище, позволяют командам работать независимо и обмениваться разными версиями программных пакетов в рамках организации. При этом, совместное использование артефактов нужной версии в организации увеличивает повторное использование кода и сокращает время разработки. Наличие центрального хранилища артефактов обеспечивает более гранулярное управление артефактами и обеспечивает прозрачность с точки зрения безопасности. В этом посте используются некоторые из этих паттернов, чтобы показать, как интегрировать AWS CodeArtifact эффективным и оптимальным с точки зрения цены способом.

Использование сервиса AWS CodeArtifact

AWS CodeArtifact – основные принципы

AWS CodeArtifact использует следующие компоненты:

Asset – отдельный файл, хранящийся в AWS CodeArtifact, и ассоциированный с версией пакета, например, npm .tgz файл или Maven POM и JAR файлы.

Package – это пакет программного обеспечения и метаданных, необходимых для управления зависимостями и установки программного обеспечения. AWS CodeArtifact поддерживает форматы пакетов npm, PyPI, и Maven.

Repository – репозиторий CodeArtifact содержит набор версий пакетов, каждая из которых сопоставляется с набором файлов (assets). Репозитории являются полиглотами — один репозиторий может содержать пакеты любого поддерживаемого типа. Каждый репозиторий предоставляет конечные точки (endpoints) для скачивания и публикации пакетов с использованием утилит командной строки npm, mvn (Maven) и pip.

Domain – репозитории объединяются в объект более высокого уровня, известный как Домен. Домен позволяет применять политику организации к нескольким репозиториям. Внутри домена происходит дедупликация хранимых в репозиториях пакетов.

Создание Домена на основе организационной структуры

Когда вы создаёте Домен в CodeArtifact, важно организовать Домен на основе структуры вашей организации. Примером может быть компания, являющаяся Доменом, а её продукты – репозиториями. Домены позволяют применять организационные политики к нескольким репозиториям. Как правило, мы рекомендуем создавать один Домен для каждой компании или организации. В некоторых случаях также может быть полезно иметь Домен-песочницу, в котором находятся репозитории-прототипы. В «песочнице» команды могут создавать свои собственные репозитории и экспериментировать, не влияя на файлы (assets) поставляемые для производственной среды. При использовании Домена-песочницы пакеты будут дублироваться, репозитории будут изолированы друг от друга без возможности копирования пакетов между Доменами, а также увеличатся затраты, поскольку дедупликация пакетов обрабатывается на уровне Домена. Организация пакетов по Доменам увеличивает количество попаданий в кэш для пакета в Домене и снижает стоимость каждого последующего запроса на загрузку пакета.

Всякий раз, когда пакет запрашивается из репозитория, ресурс кэшируется в вашем домене CodeArtifact для минимизации стоимости последующих запросов. Конкретный asset сохраняется в домене в единственном экземпляре, неважно, доступен ли он в двух или даже двух тысячах репозиториев. Это означает, что вы платите за хранение только один раз. Копирование версии пакета с помощью API CopyPackageVersions возможно только между репозиториями в одном домене CodeArtifact.

Вы можете создать домен для вашей организации, используя команду create-domain интерфейса командной строки AWS (AWS CLI), AWS SDK, или в интерфейсе CodeArtifact. Пример кода:

aws codeartifact create-domain --domain "my-org"

После создания домена вы увидите домены в разделе Domains в интерфейсе CodeArtifact.

Организация пакетов по доменам

Использование общего репозитория

Использование общего репозитория имеет смысл, когда команда считает, что компонент полезен для остальной части организации, не находится на стадии тестирования или в личном проекте, и не предназначен для широкого распространения внутри организации. Примерами общих компонентов являются общедоступные репозитории с открытым исходным кодом (npm, PyPI и Maven), библиотеки аутентификации, логирования и другие вспомогательные библиотеки. Общие библиотеки не связаны с библиотеками продуктов; например, библиотека с API контрактами продукта не должна находиться в общем репозитории. Общий репозиторий должен быть настроен в режиме «только для чтения» всем пользователям, за исключением IAM роли для публикации. В Amazon мы обнаружили, что многие команды хотят использовать общие пакеты в рамках своих приложений, и им не нужно публиковать какие-либо пакеты самостоятельно. Этим командам не нужен собственный репозиторий, так как они получают пакеты из общего доступа. В целом, примерно 80% пакетов загружаются из общего репозитория, а 20% — из репозиториев, относящихся к команде или проекту.

Вы можете создать общий репозиторий, вызвав команду create-repository и настроив политику ресурсов, которая делает репозиторий доступным только для чтения.

Для создания репозитория используйте команду интерфейса командной строки AWS create-repository. Пример кода:

aws codeartifact create-repository --domain "my-org" \
--domain-owner "account-id" --repository "my-shared-repo-name" \
--description "My new repository"

Затем сделайте репозиторий доступным только для чтения, установив политику ресурсов. Пример кода:

{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"codeartifact:DescribePackageVersion",
"codeartifact:DescribeRepository",
"codeartifact:GetPackageVersionReadme",
"codeartifact:GetRepositoryEndpoint",
"codeartifact:ListPackages",
"codeartifact:ListPackageVersions",
"codeartifact:ListPackageVersionAssets",
"codeartifact:ListPackageVersionDependencies",
"codeartifact:ReadFromRepository"
],
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::444455556666:root"
},
"Resource": "*"
}
]
}

Чтобы применить политику ресурсов к репозиторию, запустите команду put-repository-permissions. Пример кода:

aws codeartifact put-repository-permissions-policy --domain "my-org" \
--domain-owner "account-id" --repository "my-shared-repo-name" \
--policy-document file:///PATH/TO/policy.json

Создав репозиторий, вы увидите его в списке «Repositories» в интерфейсе CodeArtifact.

Общие репозитории в AWS CodeArtifact

Подключение внешних репозиториев

CodeArtifact позволяет подключать внешние репозитории и реплицировать их в CodeArtifact. Внешнее подключение снижает зависимость ваших приложений от внешнего репозитория. Когда вы запрашиваете из репозитория CodeArtifact пакет, которого в нём ещё нет, этот пакет может загрузиться через внешнее подключение. Это позволяет использовать библиотеки с открытым исходным кодом в вашем приложении. Использование внешнего подключения уменьшает количество внешних зависимостей в процессе разработки, например, если пакет был удален из общедоступного репозитория, у вас всё равно останется копия пакета, хранящаяся в CodeArtifact. У вас должно быть сопоставление «один к одному» с внешними репозиториями: необходимо избегать нескольких репозиториев CodeArtifact, указывающих на один и тот же общедоступный репозиторий. Каждый файл (asset), который CodeArtifact импортирует в ваш репозиторий из общедоступного репозитория, оплачивается как один запрос, при этом каждое подключение должно полностью проверить и загрузить пакет, прежде чем вернуть ответ. Имея сопоставление «один к одному», вы можете увеличить процент попадания в кэш, сократить время загрузки пакетов из CodeArtifact и уменьшить количество запросов для определения внешних зависимостей. Подключение внешнего репозитория к вашему репозиторию выполняется с помощью команды associate-external-connection. Пример кода:

aws codeartifact associate-external-connection \
--domain "my-org" --domain-owner "account-id" \
--repository "my-external-repo" --external-connection public:npmjs

После того, как вы установили внешнее подключение к вашему репозиторию, вы его увидите в разделе «Repositories». В этом примере мы подключили репозиторий к внешнему репозиторию npmjs.

Внешнее подключение к npmjs для AWS CodeArtifact репозитория

Репозитории для команд и продуктов

При работе в распределённых командах вы часто создаёте отдельные репозитории на каждый продукт. Команды, работающие с собственным репозиторием, могут обновлять его по мере необходимости. Примером может служить создание внутреннего пакета, который команда использует только для своего продукта.

Пример кода:

aws codeartifact create-repository --domain my-org \
--domain-owner account-id --repository my-team-repo \
--description "My new team repository"

По мере разработки пакета команде нужно будет сохранять изменения в репозиторий. Для этого внутри вашего CI/CD-конвейера вам нужно будет опубликовать пакет в репозиторий. Пример кода:

# Log in to CodeArtifact
aws codeartifact login --tool npm \
--domain "my-org" --domain-owner "account-id" \
--repository "my-team-repo"

# Run build commands here
...

# Set $VERSION from your build system
npm version $VERSION

# Publish to CodeArtifact
npm publish

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

# Promoting to a shared repo
aws codeartifact copy-package-versions --domain "my-org" \
--domain-owner "account-id" --source-repository "my-team-repo" \
--destination-repository "my-shared-repo" \
--package my-package --format npm \
--versions '["6.0.2"]'

Когда вы создали общий репозиторий, вы увидите, что репозитории обновились, как показано ниже:

Репозитории для команд и по продуктам

Совместное использование репозиториев между аккаунтами

Часто команды или рабочие нагрузки имеют отдельные AWS аккаунты в организации. Это рекомендуемая практика, поскольку она чётко определяет область владения ресурсами и устанавливает границы безопасности. Если ваша организация использует стратегию с несколькими аккаунтами, вы можете совместно использовать репозитории между аккаунтами с помощью политики ресурсов CodeArtifact. Команды могут разрабатывать продукты в своём аккаунте и публиковать их в репозитории CodeArtifact, находящемся в управлении в аккаунте для совместного использования.

Здесь вы видите список репозиториев, который включает в себя как разделяемый, так и командный репозитории:

Предоставление доступа к AWS CodeArtifact репозиториев для разных AWS аккаунтов

Использование Amazon CloudWatch Events при загрузке пакета

Когда пакет загружается в репозиторий, его новая версия может повлиять на программные зависимости, команды или операционные процессы. При загрузке артефакта в CodeArtifact, создаётся событие Amazon CloudWatch Events, которое можно использовать для запуска дополнительных обработчиков. Вы можете реагировать на эти события, подписавшись на событие CodeArtifact в Amazon EventBridge. Некоторые примеры реакций на изменения: тестирование зависимостей, развёртывание зависимых приложений, уведомление команд об изменениях или запуск процесса сборки новых зависимостей.

Вы можете использовать Amazon EventBridge для запуска конвейера (pipeline) в AWS CodePipeline, отправить сообщение в Amazon Simple Notification Service (Amazon SNS) или вызвать AWS Chatbot. Для получения дополнительной информации см. формат событий CodeArtifact и их примеры. Если вы хотите интегрировать AWS Chatbot в конвейер развёртывания приложений, см. Receive AWS Developer Tools Notifications over Slack using AWS Chatbot.

Развёртывание кода в гибридной среде

Вы можете обеспечить бесшовное развёртывание программного обеспечения в AWS и локальных средах, интегрировав CodeArtifact со службами сборки и развёртывания программного обеспечения. Вы можете использовать CodeArtifact с существующими инструментами конвейера сборки, такими как NPM, Python, и Maven. Благодаря встроенной поддержке этих менеджеров пакетов вы можете получить доступ к CodeArtifact в любых утилитах, с которыми вы привыкли работать.

Сначала войдите в CodeArtifact, запустите процесс сборки кода и опубликуйте, используя npm publish следующим образом:

# Log in to CodeArtifact
aws codeartifact login --tool npm \
--domain "my-org" --domain-owner "account-id" \
--repository "my-team-repo"

# Run build commands here
...

# Set $VERSION from your build system
npm version $VERSION

# Publish to CodeArtifact
npm publish

Процесс удаления

Когда вы захотите удалить созданные вами репозитории и домены, это нужно будет сделать в определенном порядке. Помните, что удаление репозитория является невозвратным действием, которое удалит все находящиеся в нём пакеты. Чтобы удалить домен и удалить репозиторий, созданные в предыдущих разделах, нужно использовать команды delete-domain и delete-repository.

Вам нужно будет удалить домен и репозиторий в следующем порядке:

Удалите все репозитории в домене.

Удалите домен.

Чтобы удалить репозиторий и домен, см. следующий код:

# Delete the repository
aws codeartifact delete-repository --domain "my-org" --domain-owner "account-id" --repository "my-team-repo"

# Delete the domain
aws codeartifact delete-domain --domain "my-org" --domain-owner "account-id"

Заключение

В этом посте мы осветили аспекты интеграции CodeArtifact в ваш конвейер программной разработки и эффективного использования CodeArtifact. Подход с общим репозиторием помогает создавать повторно используемые компоненты в вашей организации. Использование командных репозиториев и распространение пакетов в рамках общего репозитория, позволяет командам разрабатывать продукты независимо друг от друга. Для получения дополнительной информации см. Getting started with CodeArtifact.