こんにちは。
アプリケーションサービス部、DevOps担当の兼安です。
今回は、AWS CodeArtifact のお話です。
システムを開発していると、重複コードは共通化を図りたくなります。
この時、マイクロサービスアーキテクチャを採用していると、重複コードは避けたいけれどサービスが分散しているため、共通化が難しいということが起こります。
この問題を軽減するために、コードをパッケージ化して共有する方法があるので、今回はその方法を紹介します。

- 本記事の対象者
- 本記事の検証環境
- AWS CodeArtifact とは
- CI/CDパイプラインでCodeArtifactにパッケージをアップロードする
- CodeArtifactからパッケージをダウンロードしてインストールする
- まとめ
本記事の対象者
本記事は、マイクロサービスアーキテクチャなど、システムが複数のサブシステムに分かれている場合を想定して記述しています。
また、ソースコードのパッケージ化とアップロードの部分にCI/CDを使用しています。
したがって、以下のような前提知識をお持ちの方を対象としています。
- マイクロサービスアーキテクチャの概要を理解している
- Pythonのパッケージ管理ツールである
uvを使用したことがある - AWS CodePipelineの概要を理解している
本記事の検証環境
- macOS Sequoia 15.5
- Python 3.13.0
- uv 0.7.8
AWS CodeArtifact とは
AWS CodeArtifact(以降、CodeArtifactと記述)は、AWS が提供するプライベートなパッケージリポジトリサービスです。
CodeArtifact を使用すると、Python、Java、JavaScript、.Net などのプログラミング言語で作成されたパッケージを管理できます。
例えば、Project A で作成した Python のコードをパッケージ化してCodeArtifactにアップロードすると、Project Bでそのパッケージをダウンロードして使用することができます。
CodeArtifactへのアップロードはコマンドで行うことができるので、CI/CDパイプラインでソースコードがアップされたら、そのコードをパッケージ化してCodeArtifactにアップロードするということも可能です。
CodeArtifact のドメインとリポジトリ
CodeArtifactには、ドメインとリポジトリという概念があります。
CodeArtifactを使う場合は、まずドメインを作成し、そのドメインの中にリポジトリを作成します。
ドメインは複数作ることができ、さらにそのドメインの中に複数のリポジトリを作成することができます。
ドメインは、AWSアカウントの中で一意である必要があります。
graph TD
Root[CodeArtifact]
DomainA[DomainA]
DomainB[DomainB]
RepoA1[RepositoryA1]
RepoA2[RepositoryA2]
RepoB1[RepositoryB1]
RepoB2[RepositoryB2]
Root --> DomainA
Root --> DomainB
DomainA --> RepoA1
DomainA --> RepoA2
DomainB --> RepoB1
DomainB --> RepoB2
CodeArtifact のアップロードとダウンロード
本記事ではPythonとそのパッケージ公開ユーティリティtwineを使用して、CodeArtifactにパッケージをアップロードします。
ダウンロードとインストールにuvを使用します。
どちらも、CodeArtifactにログインしてから実行する必要があります。
CI/CDパイプラインでCodeArtifactにパッケージをアップロードする
今回は、CodeArtifactにパッケージをアップロードするためのCI/CDパイプラインを構築します。
ソースコードをAmazon S3にアップロードすると、CodePipelineがトリガーされてCodeBuildが実行されます。
CodeBuildでは、コマンドでソースコードをパッケージ化し、CodeArtifactにアップロードします。


CodeArtifactのドメインとリポジトリの作成
CodeArtifactのドメインとリポジトリは、事前に作成しておきます。


ドメインにはドメイン所有者、リポジトリにはリポジトリ管理者が設定できます。
自分のAWSアカウントの中で、CodeArtifactのドメインを作成した場合は、そのAWSアカウントがドメイン所有者・リポジトリ管理者になります。
ソースコードをパッケージにするための設定
パッケージにするためのソースコードは、フォルダ内にpyproject.tomlを作ってパッケージ名を指定しておきます。
[build-system] requires = ["setuptools>=61.0", "wheel"] build-backend = "setuptools.build_meta" [project] name = "<パッケージ名>" version = "1.0.0" description = "A sample Python package for CodeArtifact demonstration" readme = "README.md" 以下省略
パッケージ化とCodeArtifactへのアップロードコマンドの設定
パッケージ化してCodeArtifactにアップロードする部分は、コマンド一式をbuildspec.ymlに記述します。
version: 0.2 phases: install: runtime-versions: python: 3.13 commands: - echo "=== Installing build dependencies ===" - pip install --upgrade pip - pip install build twine - echo "Build dependencies installed successfully" pre_build: commands: - echo "=== Configuring CodeArtifact authentication ===" - echo "Domain:" $CODEARTIFACT_DOMAIN - echo "Repository:" $CODEARTIFACT_REPOSITORY - echo "Region:" $AWS_REGION - echo "Getting AWS account ID..." - export AWS_ACCOUNT_ID=$(aws sts get-caller-identity \ --query Account \ --output text) - echo "AWS Account ID:" $AWS_ACCOUNT_ID - echo "Getting CodeArtifact authorization token..." - | export CODEARTIFACT_AUTH_TOKEN=$(aws codeartifact get-authorization-token \ --domain $CODEARTIFACT_DOMAIN \ --domain-owner $AWS_ACCOUNT_ID \ --query authorizationToken \ --output text) - echo "Getting CodeArtifact repository endpoint..." - | export CODEARTIFACT_REPOSITORY_URL=$(aws codeartifact get-repository-endpoint \ --domain $CODEARTIFACT_DOMAIN \ --domain-owner $AWS_ACCOUNT_ID \ --repository $CODEARTIFACT_REPOSITORY \ --format pypi \ --query repositoryEndpoint \ --output text) - echo "CodeArtifact repository URL:" $CODEARTIFACT_REPOSITORY_URL - echo "CodeArtifact authentication configured successfully" build: commands: - echo "=== Building Python package ===" - echo "Current directory:" $(pwd) - echo "Directory contents:" - ls -la - echo "Running python -m build..." - python -m build - echo "Build completed. Checking generated artifacts:" - ls -la dist/ - echo "Package built successfully" post_build: commands: - echo "=== Uploading package to CodeArtifact ===" - echo "Uploading package using twine..." - | twine upload \ --repository-url $CODEARTIFACT_REPOSITORY_URL \ --username aws \ --password $CODEARTIFACT_AUTH_TOKEN \ dist/* - echo "Package uploaded to CodeArtifact successfully" - echo "=== Build and upload process completed ===" artifacts: files: - dist/* name: python-package-artifacts
コマンドを実行するCodeBuildの設定
CodeBuildのビルドプロジェクトでbuildspec.ymlを使用するように設定します。
上述のbuildspec.ymlは、CodeArtifactのドメインとリポジトリを環境変数から取得するようにしています。
したがって、CodeBuildのビルドプロジェクトで環境変数として設定します。

buildspec.ymlの各フェーズで行っていること
| フェーズ | 処理内容 |
|---|---|
pre_build |
CodeArtifact のログイントークンとリポジトリエンドポイントの取得 |
build |
Python パッケージのビルド処理 |
post_build |
twine を使用して CodeArtifact にパッケージをアップロード |
twineは、Pythonのパッケージをアップロードするためのツールで、CodeArtifactへのアップロードもサポートしています。
この設定のCodePipelineとCodeBuildを作ってから、S3にソースコードをアップロードすると、CodePipelineがトリガーされてCodeBuildが実行されます。
CodeBuildでは、buildspec.ymlに記述したコマンドが実行されてCodeArtifactにパッケージがアップロードされます。
アップロードしたパッケージは、CodeArtifactのリポジトリで確認できます。

CodeArtifactからパッケージをダウンロードしてインストールする
CodeArtifactにアップロードしたパッケージをインストールしてみましょう。
Pythonのuvの場合、以下の手順でインストールします。
- CodeArtifactにログイン
uvでインデックスURLを指定uv pip installコマンドで直接インストール、もしくは、pyproject.tomlに当該パッケージを依存関係として追加して、uv syncを実行
uvのインデックスURLとは、Pythonパッケージをインストールする際に参照するサーバーのURLのことです。
インデックスURLの形式に従い、CodeArtifactのリポジトリのURLを設定します。
CodeArtifactへのログインとインデックスURLの設定
CodeArtifactへのログインとインデックスURLの設定までのコマンドは以下の通りです。
# 環境変数を設定 export CODEARTIFACT_DOMAIN=<ドメイン名> export CODEARTIFACT_REPOSITORY=<リポジトリ名> export AWS_ACCOUNT_ID=$(aws sts get-caller-identity \ --query Account \ --output text) # CodeArtifact にログイン aws codeartifact login \ --tool pip \ --domain $CODEARTIFACT_DOMAIN \ --repository $CODEARTIFACT_REPOSITORY # uv用の環境変数を設定 export UV_INDEX_URL="https://aws:$(aws codeartifact get-authorization-token \ --domain $CODEARTIFACT_DOMAIN \ --domain-owner $AWS_ACCOUNT_ID \ --query authorizationToken \ --output text)@$CODEARTIFACT_DOMAIN-$AWS_ACCOUNT_ID.d.codeartifact.ap-northeast-1.amazonaws.com/pypi/$CODEARTIFACT_REPOSITORY/simple/" export UV_EXTRA_INDEX_URL="https://pypi.org/simple/"
環境変数UV_INDEX_URLとUV_EXTRA_INDEX_URLでインデックスURLを設定しています。
このように設定することで、uvはCodeArtifactのリポジトリからパッケージをダウンロードできるようになります。
UV_INDEX_URLとUV_EXTRA_INDEX_URLの2つの環境変数を設定しているのは、CodeArtifactのリポジトリにパッケージがない場合に、PyPIからパッケージをダウンロードさせるためです。
インデックスURLにpypi・simpleというキーワードが含まれていますが、これらはPyPIのSimple APIの仕様に従ったものです。
詳しくは下記のページを参照してください。
uv pip installコマンドで直接インストール
上述のコマンドでCodeArtifactへのログインとインデックスURLの設定を行ったら、コマンドでパッケージをインストールすることができます。
uv pip install <パッケージ名>
uvを使っているのに、pyproject.tomlを使わずに直接インストールする方を先に書いているのは、次項で説明します。
pyproject.tomlに当該パッケージを依存関係として追加して、uv syncを実行
CodeArtifactへのログインとインデックスURLの設定を行っていれば、pyproject.tomlに当該パッケージを依存関係として追加して、uv syncを実行することもできます。
pyproject.tomlの例は以下の通りです。
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "consumer-example"
version = "0.1.0"
description = "Example consumer application for CodeArtifact sample package"
readme = "README.md"
requires-python = ">=3.13"
省略
dependencies = [
"<パッケージ名>",
"click>=8.0.0",
]
省略
pyproject.tomlに依存関係を追加したら、以下のコマンドでパッケージをインストールします。
uv sync
この方法のデメリットは、以下のようにuv.lockファイルにインデックスURLが書き込まれることです。
インデックスURLはCodeArtifactのリポジトリのURLを指定する必要があります。
CodeArtifactのリポジトリのURLは、AWSアカウントごとに異なるため、uv.lockファイルを共有すると、他の人が同じURLでインストールできなくなる可能性があります。
ここは、チーム内でどのような形でパッケージを運用するか相談が必要でしょう。
[[package]]
name = "<パッケージ名>"
version = "<バージョン>"
source = { registry = "https://<ドメイン名>-<AWSアカウントNo>.d.codeartifact.ap-northeast-1.amazonaws.com/pypi/<リポジトリ名>/simple/" }
dependencies = [
{ name = "requests" },
]
sdist = { url = "https://<リポジトリ名>-<AWS>.d.codeartifact.ap-northeast-1.amazonaws.com/pypi/<リポジトリ名>/simple/<パッケージ名>/<バージョン>/<パッケージ名>-<バージョン>.tar.gz", hash = "sha256:0c6bef09401583866bf7f604d0da25af7b9f1a32af7a5536a6b0a8e4930a7fb2" }
wheels = [
{ url = "https://<ドメイン名>-<AWSアカウント>.d.codeartifact.ap-northeast-1.amazonaws.com/pypi/<リポジトリ名>/simple/<パッケージ名>/<バージョン>/<パッケージ名>-<バージョン>-py3-none-any.whl", hash = "sha256:d0f87557a8e7f8163f961016f6fa5d4ca71099c966dc582754690acf2bd2ed9d" },
]
まとめ
CodeArtifactを使用することで、複数のプロジェクト間でコードをパッケージ化して共有することができます。
マイクロサービスアーキテクチャや、複数のサブシステムを持つシステムにおけるコードの共通化の問題を軽減することができます。
CodeArtifactにパッケージをアップロードするとき、またはインストールするときは、ログインを行う必要があります。
ログイン後にリポジトリのURLを設定することで、パッケージ管理ツールを通じてパッケージのインストールが可能になります。
ただし、インストール方法によっては、ファイルにAWSアカウント番号を含んだURLが記録されることがあるため、インストール方法には注意が必要です。
兼安 聡(執筆記事の一覧)
アプリケーションサービス部 DS3課所属
2025 Japan AWS Top Engineers (AI/ML Data Engineer)
2025 Japan AWS All Certifications Engineers
2025 AWS Community Builders
Certified ScrumMaster
PMP
広島在住です。今日も明日も修行中です。