[アップデート]AWS CodeBuild のS3 キャッシュでキャッシュバージョン管理とプロジェクト間共有が可能になりました

[アップデート]AWS CodeBuild のS3 キャッシュでキャッシュバージョン管理とプロジェクト間共有が可能になりました

AWS CodeBuild のS3 キャッシュでキャッシュバージョン管理とプロジェクト間共有が可能になりました
Clock Icon2025.03.31

お疲れさまです。とーちです。

AWS CodeBuild が S3 キャッシュ用のカスタムキャッシュキーをサポートするようになったというアップデートがありました。こちらのアップデートを実際に試してみたので、今回はその内容をお届けします。

https://aws.amazon.com/jp/about-aws/whats-new/2025/03/aws-codebuild-custom-cache-keys-s3-caching/

CodeBuild のキャッシュ機能について

そもそも CodeBuild のキャッシュには「ローカルキャッシュ」と「S3 キャッシュ」の2種類があります。

ローカルキャッシュの特徴は、ビルドホストにキャッシュを持つことです。これによりネットワークを介さずにキャッシュにアクセスできますが、そのビルドホストのみが利用できるキャッシュという点に注意が必要です。

一方、S3 キャッシュの特徴としては、S3 バケットにキャッシュを保持することで複数のビルドホスト間でキャッシュを使い回せることが挙げられます。ローカルキャッシュと比べた場合のデメリットとしては、S3 からのダウンロード時間が追加でかかることです。このため依存ライブラリなどのキャッシュ対象の総容量が多い場合など、ビルド作業自体よりもキャッシュのダウンロードに時間がかかるときはローカルキャッシュのほうが良いでしょう。

今回のアップデートは S3 キャッシュに関するもので、S3 キャッシュ使用時にユーザーが任意のキャッシュキーを使用できるようになったというものです。これによってキャッシュのバージョン管理や、他の CodeBuild プロジェクト間でキャッシュを共有することが可能になりました。

それではさっそくやってみましょう。

やってみる

検証の前提条件

検証を始める前に、以下の条件を満たしていることを確認してください

  • CodeConnection で GitHub と AWS アカウントを接続済であること
  • キャッシュ用の S3 バケットが作成済みであること
    • 特別な設定などは必要なく普通に S3 バケットを作るだけなので作成方法は割愛します

キャッシュのバージョン管理を試す

今回は GitHub 上に buildspec.yml と package.json などのビルド時にインストールするパッケージ情報を書いたファイルを置いて、キャッシュの動作を確認してみます。

まずは CodeBuild プロジェクトを以下のように作成します。

alt text

キャッシュの設定は以下のような形です。

alt text

buildspec.yml は以下のように記載しました。

version: 0.2

phases:
  build:
    commands:
      - echo "=== Starting build at $(date) ==="
      - if [ -d "node_modules" ]; then echo "Cache HIT - node_modules exists"; else echo "Cache MISS - node_modules not found"; fi
      - time npm install
      - echo "=== Finished build at $(date) ==="
      - du -sh node_modules
      - find node_modules -type d -maxdepth 1 | wc -l

artifacts:
  files: 
    - package.json
    - package-lock.json
  
cache:
  key: npm-$(codebuild-hash-files 'package-lock.json')
  paths:
    - 'node_modules/**/*'

keyの部分が新しく追加された設定ですね。文字通り、キャッシュキー名を指定する項目で、key名の一部として環境変数やコマンド置換が使えます。

私は知らなかったのですが、codebuild-hash-files というCLIがCodeBuildの実行環境には備わっているようですね。 CodeBuild ソース ディレクトリ内のファイルの SHA-256 ハッシュを算出してくれるコマンドだそうです。

https://docs.aws.amazon.com/codebuild/latest/userguide/caching-s3.html#caching-s3-dynamic.codebuild-hash-files

また package.json は以下のような状態です。

{
  "dependencies": {
    "aws-sdk": "^2.1692.0",
    "next": "^15.2.4",
    "react": "^19.1.0",
    "react-dom": "^19.1.0",
    "typescript": "^5.8.2"
  }
}

この状態で1回目のビルドをしてみます。

alt text

1回目のビルドの結果がこちらです。重要な部分以外は省略しています。

<省略>

[Container] 2025/03/31 02:55:27.023429 Parsing and expanding cache keys
[Container] 2025/03/31 02:55:27.032872 Expanded cache key: npm-$(codebuild-hash-files 'package-lock.json') -> npm-70434d984db189e6aabde76c7010b35290736e190c35f41da6dacc9fea57ed98
[Container] 2025/03/31 02:55:27.037806 Downloading S3 cache...
[Container] 2025/03/31 02:55:27.038546 Searching for cache with primary key: npm-70434d984db189e6aabde76c7010b35290736e190c35f41da6dacc9fea57ed98
[Container] 2025/03/31 02:55:27.107905 No cache found
[Container] 2025/03/31 02:55:27.108592 Unable to download cache: no caches were found with the provided cache keys

<省略>

[Container] 2025/03/31 02:55:27.851045 Running command echo "=== Starting build at $(date) ==="
=== Starting build at Mon Mar 31 02:55:27 AM UTC 2025 ===

[Container] 2025/03/31 02:55:27.862380 Running command if [ -d "node_modules" ]; then echo "Cache HIT - node_modules exists"; else echo "Cache MISS - node_modules not found"; fi
Cache MISS - node_modules not found

[Container] 2025/03/31 02:55:27.870519 Running command time npm install
npm warn deprecated querystring@0.2.0: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.

added 73 packages, and audited 74 packages in 20s

23 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

real    0m26.252s
user    0m10.841s
sys 0m2.363s

<省略>

[Container] 2025/03/31 02:55:54.139778 Running command du -sh node_modules
545M    node_modules

[Container] 2025/03/31 02:55:54.178187 Running command find node_modules -type d -maxdepth 1 | wc -l
73

<省略>

[Container] 2025/03/31 02:55:54.232871 Uploading S3 cache...
[Container] 2025/03/31 02:55:54.272851 Saving cache at S3 path: ae802ee0-4271-4c3e-a8f0-7d3cc323bb7d/cfd480081b05b236f4092cac6130db6c/npm-70434d984db189e6aabde76c7010b35290736e190c35f41da6dacc9fea57ed98
[Container] 2025/03/31 02:55:58.691818 Cache saved with key: npm-70434d984db189e6aabde76c7010b35290736e190c35f41da6dacc9fea57ed98

<省略>

Expanded cache key: npm-$(codebuild-hash-files 'package-lock.json') -> npm-*** で 'package-lock.json' ファイルのハッシュ値が自動で展開されているのがわかります。

2025/03/31 02:55:27.107905 No cache found となっており、初回のビルドなのでキャッシュがダウンロードできなかったことがわかりますね。

キャッシュ未使用時の npm インストールのコマンドの実行時間は、real 0m26.252s なので、26.2 秒くらいです。

2025/03/31 02:55:54.272851 Saving cache at S3 path となっているので S3 を見てみるとキャッシュが保存されていました。

alt text

ではこのまま、設定など何も変えずに2回目のビルドを行います。

2回目のビルドログがこちらです。

<省略>

[Container] 2025/03/31 03:01:46.944773 Expanded cache key: npm-$(codebuild-hash-files 'package-lock.json') -> npm-70434d984db189e6aabde76c7010b35290736e190c35f41da6dacc9fea57ed98
[Container] 2025/03/31 03:01:46.949326 Downloading S3 cache...
[Container] 2025/03/31 03:01:46.949924 Searching for cache with primary key: npm-70434d984db189e6aabde76c7010b35290736e190c35f41da6dacc9fea57ed98
[Container] 2025/03/31 03:01:47.106526 Cache hit for key: npm-70434d984db189e6aabde76c7010b35290736e190c35f41da6dacc9fea57ed98
[Container] 2025/03/31 03:01:47.106554 Downloaded cache archive from S3 path: ae802ee0-4271-4c3e-a8f0-7d3cc323bb7d/cfd480081b05b236f4092cac6130db6c/npm-70434d984db189e6aabde76c7010b35290736e190c35f41da6dacc9fea57ed98
[Container] 2025/03/31 03:01:47.142825 Download duration: 156ms
[Container] 2025/03/31 03:01:47.142856 Size: 114.83 MiB
[Container] 2025/03/31 03:01:47.142859 Unarchiving cache...
[Container] 2025/03/31 03:01:50.868145 Extraction duration: 3725ms
[Container] 2025/03/31 03:01:50.868164 Cache restored from key: npm-70434d984db189e6aabde76c7010b35290736e190c35f41da6dacc9fea57ed98

<省略>

[Container] 2025/03/31 03:01:51.594104 Running command echo "=== Starting build at $(date) ==="
=== Starting build at Mon Mar 31 03:01:51 AM UTC 2025 ===

[Container] 2025/03/31 03:01:51.605305 Running command if [ -d "node_modules" ]; then echo "Cache HIT - node_modules exists"; else echo "Cache MISS - node_modules not found"; fi
Cache HIT - node_modules exists

[Container] 2025/03/31 03:01:51.613064 Running command time npm install

up to date, audited 74 packages in 8s

23 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

real    0m13.649s
user    0m0.666s
sys 0m0.127s

<省略>

[Container] 2025/03/31 03:02:05.277224 Running command du -sh node_modules
545M    node_modules

[Container] 2025/03/31 03:02:05.312842 Running command find node_modules -type d -maxdepth 1 | wc -l
73

<省略>

[Container] 2025/03/31 03:02:05.366449 Uploading S3 cache...
[Container] 2025/03/31 03:02:05.400002 Skipping cache generation, cache already exists for key: npm-70434d984db189e6aabde76c7010b35290736e190c35f41da6dacc9fea57ed98
[Container] 2025/03/31 03:02:05.400033 Found cache at S3 path ae802ee0-4271-4c3e-a8f0-7d3cc323bb7d/cfd480081b05b236f4092cac6130db6c/npm-70434d984db189e6aabde76c7010b35290736e190c35f41da6dacc9fea57ed98 created at 2025-03-31 02:55:56 +0000 UTC

<省略>

Cache hit for key: npm-*** となっており、今回はキャッシュヒットできていますね。

Download duration: 156ms などダウンロードやその展開にかかった時間もちゃんと表示してくれるんですね。あまりキャッシュ機能を使ったことがなかったので知りませんでした。これを見れば S3 キャッシュがいいかローカルキャッシュがいいかの判断の参考になりそうです。

npm インストールのコマンドの実行時間は、real 0m13.649s 13.6 秒くらいなので、当たり前ですが、キャッシュ未使用時の 26.2 秒と比べてビルド時間は短くなっています。

キャッシュのバージョン管理を試す(続き)

前置きが長くなりましたが、ここまでは従来も出来ていた普通の S3 キャッシュ機能になります。ここからは、キャッシュキーの値を変えることで新しくキャッシュし直す様子を確認してみましょう。

package.json の中身を変えてみましょう。変更した後は npm install を行い、package-lock.json にも更新をかけます。その後、GitHub に push をします。

分かりづらいですが、 "aws-sdk": "^2.1690.0" の部分が変わっています。

{
  "dependencies": {
    "aws-sdk": "^2.1690.0",
    "next": "^15.2.4",
    "react": "^19.1.0",
    "react-dom": "^19.1.0",
    "typescript": "^5.8.2"
  }
}

package-lock.json の中身が変わったことで、$(codebuild-hash-files 'package-lock.json') で算出されるハッシュ値も変更されるはずです。

3回目のビルドログがこちらになります。

<省略>

[Container] 2025/03/31 03:22:55.968210 Expanded cache key: npm-$(codebuild-hash-files 'package-lock.json') -> npm-62f9774a5dd0c05d42ef53a82a4b317b84f72e2d7961d84ef79fc22260590d39
[Container] 2025/03/31 03:22:55.972806 Downloading S3 cache...
[Container] 2025/03/31 03:22:55.973328 Searching for cache with primary key: npm-62f9774a5dd0c05d42ef53a82a4b317b84f72e2d7961d84ef79fc22260590d39
[Container] 2025/03/31 03:22:56.048846 No cache found
[Container] 2025/03/31 03:22:56.049462 Unable to download cache: no caches were found with the provided cache keys

<省略>

[Container] 2025/03/31 03:22:56.731132 Running command echo "=== Starting build at $(date) ==="
=== Starting build at Mon Mar 31 03:22:56 AM UTC 2025 ===

[Container] 2025/03/31 03:22:56.741925 Running command if [ -d "node_modules" ]; then echo "Cache HIT - node_modules exists"; else echo "Cache MISS - node_modules not found"; fi
Cache MISS - node_modules not found

[Container] 2025/03/31 03:22:56.749235 Running command time npm install
npm warn deprecated querystring@0.2.0: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.

added 73 packages, and audited 74 packages in 19s

23 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

real    0m24.998s
user    0m10.722s
sys 0m2.210s

<省略>

[Container] 2025/03/31 03:23:21.770943 Running command du -sh node_modules
545M    node_modules

[Container] 2025/03/31 03:23:21.808200 Running command find node_modules -type d -maxdepth 1 | wc -l
73

<省略>

[Container] 2025/03/31 03:23:21.864474 Uploading S3 cache...
[Container] 2025/03/31 03:23:21.901173 Saving cache at S3 path: ae802ee0-4271-4c3e-a8f0-7d3cc323bb7d/cfd480081b05b236f4092cac6130db6c/npm-62f9774a5dd0c05d42ef53a82a4b317b84f72e2d7961d84ef79fc22260590d39
[Container] 2025/03/31 03:23:26.117302 Cache saved with key: npm-62f9774a5dd0c05d42ef53a82a4b317b84f72e2d7961d84ef79fc22260590d39

<省略>

Searching for cache with primary key: npm-62f9774a5dd0c05d42ef53a82a4b317b84f72e2d7961d84ef79fc22260590d39 ということでちゃんとハッシュキーが変わっていますね。(以前のキーは:npm-70434d984db189e6aabde76c7010b35290736e190c35f41da6dacc9fea57ed98

それに伴い、No cache found となりました。

Saving cache at S3 path: ということで、ビルド完了後は再度キャッシュを S3 にアップロードしているのがわかります。

なお、キャッシュキーには npm-key-$CODEBUILD_RESOLVED_SOURCE_VERSION のような形で環境変数をキーの一部とすることも可能になっていますので、ビルドの方法に合わせて、キャッシュキーをどのような名前にするか考えると良いのではないかと思います。

プロジェクト間のキャッシュ共有

プロジェクト間のキャッシュ共有も試してみます。

プロジェクト間でキャッシュを共有するには cacheNamespace というパラメータを使います。

上記で作成した CodeBuild プロジェクトを編集して cacheNamespace を追加します。

alt text

続いて、新しく CodeBuild プロジェクトを作成します。

alt text

新しい CodeBuild プロジェクトにも同じように cacheNamespace を設定するのがポイントです。

この状態で初回のビルドを実施してみます。

<省略>

[Container] 2025/03/31 03:34:47.896807 Expanded cache key: npm-$(codebuild-hash-files 'package-lock.json') -> npm-62f9774a5dd0c05d42ef53a82a4b317b84f72e2d7961d84ef79fc22260590d39
[Container] 2025/03/31 03:34:47.901909 Downloading S3 cache...
[Container] 2025/03/31 03:34:48.154589 Searching for cache with primary key: npm-62f9774a5dd0c05d42ef53a82a4b317b84f72e2d7961d84ef79fc22260590d39
[Container] 2025/03/31 03:34:48.171282 No cache found
[Container] 2025/03/31 03:34:48.172063 Unable to download cache: no caches were found with the provided cache keys

<省略>

[Container] 2025/03/31 03:35:12.563185 Uploading S3 cache...
[Container] 2025/03/31 03:35:12.951529 Saving cache at S3 path: cachekey-update-shared/cfd480081b05b236f4092cac6130db6c/npm-62f9774a5dd0c05d42ef53a82a4b317b84f72e2d7961d84ef79fc22260590d39
[Container] 2025/03/31 03:35:17.392346 Cache saved with key: npm-62f9774a5dd0c05d42ef53a82a4b317b84f72e2d7961d84ef79fc22260590d39

<省略>

予想に反して、No cache found となりましたね。これはなぜかというと、最初に作成した CodeBuild プロジェクトで、cacheNamespace の変更をしたあとにビルドを行っていなかったからです。キャッシュ用の S3 バケットを見ると分かるのですが、

alt text

上記のように cacheNamespace として設定した値でディレクトリが作成されています。cacheNamespace を指定したビルドにより作成されたキャッシュは上記の通り、専用のディレクトリに配置されるようです。

上記のログを見ると分かるのですが、キャッシュのアップロード処理の部分が以下のようなログになっていることからも cachekey-update-shared ディレクトリにキャッシュが配置されたことがわかります。

  • Saving cache at S3 path: cachekey-update-shared/cfd480081b05b236f4092cac6130db6c/npm-62f9774a5dd0c05d42ef53a82a4b317b84f72e2d7961d84ef79fc22260590d39

気を取り直して3個目の CodeBuild プロジェクトを新規作成(設定は上記とほぼ同じなので割愛)し、キャッシュが使われるかを確認します。まっさらな状態でビルドを実行してみると以下のような結果になりました。

<省略>

[Container] 2025/03/31 03:41:43.717784 Expanded cache key: npm-$(codebuild-hash-files 'package-lock.json') -> npm-62f9774a5dd0c05d42ef53a82a4b317b84f72e2d7961d84ef79fc22260590d39
[Container] 2025/03/31 03:41:43.722630 Downloading S3 cache...
[Container] 2025/03/31 03:41:43.982403 Searching for cache with primary key: npm-62f9774a5dd0c05d42ef53a82a4b317b84f72e2d7961d84ef79fc22260590d39
[Container] 2025/03/31 03:41:44.109101 Cache hit for key: npm-62f9774a5dd0c05d42ef53a82a4b317b84f72e2d7961d84ef79fc22260590d39
[Container] 2025/03/31 03:41:44.109132 Downloaded cache archive from S3 path: cachekey-update-shared/cfd480081b05b236f4092cac6130db6c/npm-62f9774a5dd0c05d42ef53a82a4b317b84f72e2d7961d84ef79fc22260590d39
[Container] 2025/03/31 03:41:44.154727 Download duration: 126ms
[Container] 2025/03/31 03:41:44.154756 Size: 115.34 MiB
[Container] 2025/03/31 03:41:44.154760 Unarchiving cache...
[Container] 2025/03/31 03:41:46.955290 Extraction duration: 2800ms
[Container] 2025/03/31 03:41:46.955309 Cache restored from key: npm-62f9774a5dd0c05d42ef53a82a4b317b84f72e2d7961d84ef79fc22260590d39

<省略>

[Container] 2025/03/31 03:41:47.643789 Running command if [ -d "node_modules" ]; then echo "Cache HIT - node_modules exists"; else echo "Cache MISS - node_modules not found"; fi
Cache HIT - node_modules exists

[Container] 2025/03/31 03:41:47.651898 Running command time npm install

up to date, audited 74 packages in 9s

23 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

real    0m14.902s
user    0m0.706s
sys 0m0.110s

<省略>

[Container] 2025/03/31 03:42:02.570885 Running command du -sh node_modules
545M    node_modules

[Container] 2025/03/31 03:42:02.644449 Running command find node_modules -type d -maxdepth 1 | wc -l
73

<省略>

[Container] 2025/03/31 03:42:02.768482 Uploading S3 cache...
[Container] 2025/03/31 03:42:03.003623 Skipping cache generation, cache already exists for key: npm-62f9774a5dd0c05d42ef53a82a4b317b84f72e2d7961d84ef79fc22260590d39
[Container] 2025/03/31 03:42:03.003650 Found cache at S3 path cachekey-update-shared/cfd480081b05b236f4092cac6130db6c/npm-62f9774a5dd0c05d42ef53a82a4b317b84f72e2d7961d84ef79fc22260590d39 created at 2025-03-31 03:35:14 +0000 UTC

<省略>

はい、今度はちゃんとキャッシュが使われ、CodeBuild プロジェクト間でもキャッシュを共有できることが確認できました。

まとめ

AWS CodeBuild が S3 キャッシュ用のカスタムキャッシュキーをサポートするようになったというアップデートの紹介でした。

ユーザーが任意のキャッシュキーをつけられるようになったことで、よりキャッシュを管理しやすくなりましたね。またプロジェクト間でもキャッシュを使い回せるということで、同じようなライブラリを使用しているプロジェクトが複数あれば、恩恵を受けられそうなアップデートです。気になった方はぜひ試してみてください。

以上、とーちでした。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.