こんにちは🐱
技術課の山本です。
11/6 のニュースで CodeBuild で AWS Lambda のランタイムを使用したビルドが可能になりました。
ニュース:
AWS CodeBuild で AWS Lambda によるコンピューティングのサポートを開始
ドキュメント:
AWS Lambda compute in AWS CodeBuild - AWS CodeBuild
何が嬉しいか
いままでは、EC2 または コンテナイメージ の 2 択でした。
Lambda が加わることにより、選択肢が 3 つになっています。
増えた部分:
ビルドは CodeBuild の指示書(buildspec.yml)に従って行うため、Lambda 関数にビルド処理を書けるわけではありません。
公式さんのニュースとドキュメントには以下の記載があります。
AWS Lambda はほぼ瞬時に起動するため、より高速なビルドが可能となります。また、Lambda でコンピューティングを実行すると、1 秒あたりの使用量に対して課金されるため、コストを最適化することができます。CodeBuildでは、x86_64 と Arm64 のどちらの命令セットアーキテクチャでも AWS Lambda によるコンピューティングを実行できます。
AWS CodeBuild で AWS Lambda によるコンピューティングのサポートを開始 より
AWS Lambda コンピューティングは、ビルドの最適化された起動速度を提供します。AWS Lambda は、起動レイテンシーが短いため、より高速なビルドをサポートします。AWS Lambda は自動的にスケーリングするため、ビルドがキューで実行を待機することもありません。ただし、AWS Lambda がサポートしていないユースケースがいくつかあるため、影響がある場合は EC2 コンピューティングを使用してください
AWS Lambda compute in AWS CodeBuild - AWS CodeBuild より
上記を踏まえると、嬉しい点は以下 3 つのようです。
- Lambda は瞬時に起動するため、高速にビルドができるようになる
- Lambda の利用料は秒単位の課金になるためコストを最適化できる
- Lambda は自動的にスケールするため、ビルドの同時実行が素早くなる
「ビルドの起動が早い!安い!スケールしやすい!」 ということですね。
他、制約もいくつかあるので、のちほど詳しく見ていきましょう。
ビルドの起動が早い!
Lambda のイメージを利用した場合にはビルドが瞬時に起動するか検証してみました。
比較用に、EC2 、 Lambda 、Docker のイメージを利用したビルドプロジェクトを用意し、ビルド処理の実行にどの程度処理時間がかかるのか見てみました。
Lambda はランタイムによる差異も確認するため、go , java , python のプロジェクトをそれぞれ作りました。
また、各 CPU アーキテクチャ(ARM , x86 ) 分、プロジェクトを作りました。
サイズは各イメージの最小サイズを使用しました。
参考ドキュメント:Docker images provided by CodeBuild - AWS CodeBuild
用意したプロジェクト:
なお、test-terraform
は dockerhub にある docker イメージを使用するビルドプロジェクトです。test-ec2
はtest-ec2-arm
の誤りです。
起動までの時間を測るため、実際にビルドはせず、日付時刻とランタイムバージョンを標準出力するだけの簡単な ビルドファイル (buildspec.yml)を作成しました。 利用するイメージに応じて、コメントアウトを変えて、Python のイメージを使用する際には "python --version" を実行するようにしました。なお、EC2 の Standard ランタイムのイメージには各言語が入っています。(terraform以外)
- buildspec.yml
version: 1 env: variables: version: "v1" phases: pre_build: commands: - echo pre build #- python --version #- java -version #- go version - terraform -v build: commands: - echo Build started on `date` post_build: commands: - echo Build completed on `date` artifacts: files: artifacts.json
結論として、EC2 やカスタムイメージ ( Docker ) に比べて、Lambda は早いです。
実行時間 | 環境イメージ | オペレーティングシステム | CPU | ランタイム | サイズ | イメージ |
---|---|---|---|---|---|---|
90 秒 | EC2 | Amazon Linux | ARM | Standard | 4 GB メモリ、2 vCPUs | aws/codebuild/amazonlinux2-x86_64-standard:5.0 |
26 秒 | EC2 | Amazon Linux | x86 | Standard | 3 GB メモリ、2 vCPUs | aws/codebuild/amazonlinux2-aarch64-standard:3.0 |
8 秒 | Lambda | Amazon Linux | ARM | GO 1.21 | 1 GB メモリ | aws/codebuild/amazonlinux-aarch64-lambda-standard:go1.21 |
8 秒 | Lambda | Amazon Linux | x86 | GO 1.21 | 1 GB メモリ | aws/codebuild/amazonlinux-x86_64-lambda-standard:go1.21 |
9 秒 | Lambda | Amazon Linux | ARM | Amazon Corretto 17 | 1 GB メモリ | aws/codebuild/amazonlinux-aarch64-lambda-standard:corretto17 |
8 秒 | Lambda | Amazon Linux | x86 | Amazon Corretto 17 | 1 GB メモリ | aws/codebuild/amazonlinux-x86_64-lambda-standard:corretto17 |
8 秒 | Lambda | Amazon Linux | ARM | Python 3.11 | 1 GB メモリ | aws/codebuild/amazonlinux-aarch64-lambda-standard:python3.11 |
7 秒 | Lambda | Amazon Linux | x86 | Python 3.11 | 1 GB メモリ | aws/codebuild/amazonlinux-x86_64-lambda-standard:python3.11 |
25 秒 | カスタムイメージ (Docker イメージ) | Linux EC2 | x86 | - | 3 GB メモリ、2 vCPUs | public.ecr.aws/hashicorp/terraform:1.5.0 |
特に、環境を作成するプロビジョニング(PROVISIONING)の部分が早いです。
EC2:
Lambda:
Lambda に使用するランタイム(java , go , python)や CPU アーキテクチャ(x86 , ARM)は特に何も影響しませんでした。
「特に java はコールドスタートになるんじゃないか?」とか懸念していたのは、杞憂に終わりました。
何回やっても早かったです。
ビルドが安い!
上で試したビルドの料金を、料金ページ 料金 - AWS CodeBuild | AWS から試算してみましょう。
EC2 と Lambda で比較してみます。
EC2 の場合:
ビルド時間はビルドを送信してからビルドが終了するまでの時間で、分単位で切り上げられます。
Lambda の場合:
ビルド時間はビルドを送信してからビルドが終了するまでの時間で、秒単位で計算され、秒単位に切り上げられます。
上の実行結果のうち、上から 4 つ分の費用を出してみました。
EC2 の場合、90 秒の場合は 2 分間の課金として計算しています。
Lambda の場合、8 秒の場合は 9 秒間の課金として計算しています。
料金 | 実行時間 | 環境イメージ | オペレーティングシステム | CPU | ランタイム | サイズ | イメージ |
---|---|---|---|---|---|---|---|
0.0085 USドル | 90 秒 | EC2 | Amazon Linux | ARM | Standard | 4 GB メモリ、2 vCPUs | aws/codebuild/amazonlinux2-x86_64-standard:5.0 |
0.005 USドル | 26 秒 | EC2 | Amazon Linux | x86 | Standard | 3 GB メモリ、2 vCPUs | aws/codebuild/amazonlinux2-aarch64-standard:3.0 |
0.00009 USドル | 8 秒 | Lambda | Amazon Linux | ARM | GO 1.21 | 1 GB メモリ | aws/codebuild/amazonlinux-aarch64-lambda-standard:go1.21 |
0.00018 USドル | 8 秒 | Lambda | Amazon Linux | x86 | GO 1.21 | 1 GB メモリ | aws/codebuild/amazonlinux-x86_64-lambda-standard:go1.21 |
Lambda の方が安いですね。
実際の使用時には、実行するビルド処理の時間が大きなウェイトを占めるため、ビルド時間が少ない場合は Lambda を使って受けられるコスト効果が大きいと言えます。
プロビジョニング(PROVISIONING)にかかる時間の占める割合が大きいときですね。
ビルドがスケールしやすい!
ビルドの同時実行数には引き続き上限がある
CodeBuild には 1 つの AWS アカウントの 1 つのリージョンごとに同時実行可能なビルド数に上限があります。
ビルドプロジェクトをすでにいくつか同時に実行しているときに、新しいビルドプロジェクトを実行できない!ということです。
デフォルト値が低いので、ビルドを同時に複数行う環境では、上限緩和することが多いです。上限は利用するイメージの種類とコンピューティングサイズの組み合わせ毎に設定があります。
ランタイムに Lambda を使用する場合には上限がないのかな?と思って調べたものの、Lambda のランタイムを利用する場合にもビルドの同時実行数に上限があります。
私の検証用 AWS アカウントの東京リージョンでは、概ね 60 になっていました。デフォルト値は 1 のようです。少ないと感じます。
Service Quotas から上限を緩和できますので、必要に応じて実施ください。
Service Quotas の画面より。Lambda ランタイム用の制限値があります。
上限数の情報は以下のドキュメントもご参照ください。
Quotas for AWS CodeBuild - AWS CodeBuild
キューを使用していないためビルド処理のスケールを素早くできる
CodeBuild にはキューという仕組みがあります。
現在のビルド数が、1 つのAWS アカウントの 1 つのリージョン内で同時実行可能なビルド数の上限に達している場合には、ビルド処理のリクエストをキューに入れて待つ仕組みです。
「キュータイムアウト」を設定しておくと、一定期間キューに入れて待たせることができます。5 分~8 時間の間で設定できます。
「上限を超えても待ってくれたらビルドできるよ〜」ということですね。
設定箇所:
Lambda をランタイムにする場合、この設定はありません。
画面:
Lambda のランタイムを使用する場合は、そもそも「キューを使わない」ことにより、ビルド処理の起動を早くしているようです。
以下のイメージです。
ランタイムが EC2 や Docker コンテナの場合:
- ビルド処理のリクエストをキューに入れる
- 同時実行制限数に達していない場合、ビルド処理のリクエストを処理する
- 同時実行制限数に達している場合、「キュータイムアウト」の設定がある場合は、一定期間キューに入れて待たせる。設定がない場合はエラーで終了する。
ランタイムが Lambda の場合:
- 同時実行制限数に達していない場合、ビルド処理のリクエストを処理する
- 同時実行制限数に達している場合はエラーで終了する。
「キューに入れる」という処理を省いたことにより、高速にスケールできるようです。
その分、同時実行リクエスト数の超過時は、超過分が異常終了するということですね。
制約
ドキュメント AWS Lambda compute in AWS CodeBuild - AWS CodeBuild をご覧ください。
yum が使えない、docker build できない、/tmpストレージは使えない、15 分でタイム・アウトする、といった制約があります。
まとめ
CodeBuild で AWS Lambda のランタイムを使用したビルドが可能になりました。
以下のシーンで活躍しそうですね。
- ビルドを素早く起動したい
- ビルドを安く実行したい
- 同時に多くのビルドを行いたい
ビルド環境のプロビジョニング(PROVISIONING)にかかる時間が短くなり、スケールが早いので、「短い時間で終わるビルド処理を同時に多数実行したい」という場面で大活躍となるでしょう。
ただし、その分キューイングができないので、「時間がかかっても確実にビルドする」という場面では不利かもしれません。
余談
隙間時間に近所の山を走っています。
悪天候の山も美しいものです。
山本 哲也 (記事一覧)
カスタマーサクセス部のエンジニア。2024 Japan AWS Top Engineers に選んでもらいました。
今年の目標は Advanced Networking – Specialty と Machine Learning - Specialty を取得することです。
山を走るのが趣味です。今年の目標は 100 km と 100 mile を完走することです。 100 km は Gran Trail みなかみで完走しました。OSJ koumi 100 で 100 mile 砕け散りました。どこかで 100 mile やりたいです。
基本的にのんびりした性格です。座右の銘は「いつか着く」