AWS CodeBuild で AWS Lambda のカスタムイメージを使用して Terraform を実行してみた

記事タイトルとURLをコピーする

こんにちは、末廣です。

前回のブログでは CodeBuild のコンピューティングで Lambda を使用して実行したものを紹介しました。

blog.serverworks.co.jp

本ブログでは同様に Lambda コンピューティングを使用して、アップデートにて追加されたカスタムイメージを使用したビルドの実行を検証したのでまとめていきます。

前置き

上記ブログでは実行環境には AWS CodeBuild によって管理されたイメージを使用(ランタイムに Java、イメージに Coretto21) していました。 ランタイムの選択は以下図の中からのみ可能であり、Lambda コンピューティングには yumdocker build が使えないなど制約があったため、コンピューティングが EC2 や Docker のときよりも自由度が低い状態でした。

選択できるランタイム

Lambda コンピューティングの利点、制約やそれぞれ言語ごとの速度比較等は弊社山本のブログで紹介されております。

blog.serverworks.co.jp

このような制約があった中、2024年3月のアップデートにて Lambda コンピューティング用のカスタムイメージをサポートするようになりました。

aws.amazon.com

Amazon ECR リポジトリに保存されているコンテナイメージを使うことで、 Java、Python、Node.js 以外の言語や AWS CLI、AWS SAM CLI などのランタイムが実行可能となっています。

検証

コンテナイメージがあれば実行できるため、今回検証として Terraform をビルドしてみました。

構成

検証した構成は

  • ソース:CodeCommit(main.tf)
  • ビルド:CodeBuild(terraform apply)
  • アーティファクト:S3(tfstate)

となっています。

構成図

実際の Terraform の使い方としては CI/CD パイプラインの作成等を行うと思いますのでドキュメントをご参考ください。

docs.aws.amazon.com

CodeBuild プロジェクトの作成

では実際にカスタムイメージを選択したプロジェクトを作っていきます。

環境イメージにカスタムイメージ、コンピューティングに Lambda、環境タイプに Linux Lambda を選択しています。

イメージ、コンピューティングの選択

ECR イメージは、自身のアカウント内、または別のアカウントにあるものを使用できます。

ECR イメージの選択

ECR イメージの URI には ECR Public Gallery から選ぶこともできましたので、Terraform の公式イメージを入力しました。

ECR イメージ URI の入力

アタッチするロールには terraform applyで作成するリソースの権限を付与します。

CodeCommit ソース

Terraform ソースコード

HashiCorp 社公式のソースを利用して簡単な VPC とサブネットを作成します。

github.com

※6・14行目にてtags の記載方法に = が抜けているので追記しています。

main.tf
provider "aws" {
  region = "${var.region}"
}

resource "aws_vpc" "demo_vpc" {
  cidr_block = "${var.vpc_cidr_block}"

  tags = {
    Name = "fp_demo_vpc"
  }
}

resource "aws_subnet" "demo_subnet" {
  vpc_id            = "${aws_vpc.demo_vpc.id}"
  cidr_block        = "${var.subnet_cidr_block}"
  availability_zone = "${var.subnet_availability_zone}"

  tags = {
    Name = "fp_demo_subnet"
  }
}

CodeCommit リポジトリ

ビルド仕様ファイル

ビルドの流れとしては以下のようになります。

  1. ビルド前セクション:Terraform のバージョン確認、ワークディレクトリの初期化
  2. ビルドセクション:デプロイを実施
  3. ビルドアーティファクト:tfstate ファイルを S3 へ保存

terraform apply はオプションを付けないと yes を入力する必要があるため、-auto-approveを付与します。

buildspec.yml
version: 0.2
phases:
  pre_build:
    on-failure: ABORT
    commands:
      - terraform --version
      - cd ./getting-started/terraform-aws
      - terraform init
  build:
    commands:
      - terraform plan
      - terraform apply -auto-approve
artifacts:
  files:
    - getting-started/terraform-aws/terraform.tfstate

ビルド実行

マネジメントコンソールからビルドを実行し、ログを見てみます。 少々長いので以下クリックで展開ください。

コンソールからも無事リソースが確認でき、アーティファクトも出力されています。

作成リソースの確認

ビルドアーティファクト

当然ですが、生成された tfstate ファイルを含めずにもう一度ビルドを実行すると全く同じリソースが作成されるため、ビルドソースに tfstate を含めた状態でビルドする必要があります。 以下ビルドソースに tfstate を含め、再度ビルドを実行したログとなります。

[Container] 2024/04/08 05:51:43.577940 Running command terraform plan
aws_vpc.demo_vpc: Refreshing state... [id=vpc-008e918ad3b7b99d0]
aws_subnet.demo_subnet: Refreshing state... [id=subnet-0a80ca6cd7a54de2d]
No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration
and found no differences, so no changes are needed.

おまけ:タイムアウトさせてみよう

ここまで問題なく Terraform によるビルド、リソースの作成が行えましたが、CodeBuild の Lambda コンピューティングは制約として 15分を超えた処理を行うことができません。

docs.aws.amazon.com

AWS Lambda は、キャッシュ、バッチビルド、カスタムビルドのタイムアウト、キューのタイムアウト、ビルドバッジ、特権モード、カスタムランタイム環境、または 15 分を超えるランタイムをサポートしていません。

つまり Terraform で作成に時間のかかるリソースを作成しようとした場合途中で停止してしまうわけです。 今回はあえてタイムアウトするようなリソースを作成し、問題を発生させてみます。

作成するリソース

作成に時間のかかるリソースということで、FSx を作成してみます。 同時に Managed Microsoft AD も構築されるため、15分以上はかかると想定しています。

Terraform のモジュールとして FSx が用意されていますのでこちらを使っていきます。

github.com

ビルド仕様ファイル

buildspec.yml は以下の様にディレクトリの指定を行います。

version: 0.2
phases:
  pre_build:
    on-failure: ABORT
    commands:
      - terraform --version
      - cd ./terraform-aws-fsx/examples/windows
      - terraform init
  build:
    commands:
      # - terraform plan
      - terraform apply -auto-approve
artifacts:
  files:
    - terraform-aws-fsx/examples/windows/terraform.tfstate

ビルド実行

ログを確認すると、Still creating… で終了してしましました。

フェーズ詳細を確認すると、ビルドフェーズでタイムアウトになっていることが確認できます。

フェーズ詳細

作成中だった AD についてコンソールから確認すると作成中状態です。 ちなみに、API の呼び出しが開始された(今回で言う AD)リソースの作成は CodeBuild が動作しなくなってからも動いているようで、暫く経つと完了していました。作成が開始すらされなかった FSx については構築はされていませんでした。

AD の作成状況

ビルドが完了していないため、アーティファクトに tfstate も出力されず、terraform destroy を CodeBuild で実行しようにも不可能です。

main.tf に backend として S3 に tfstate ファイルを保存するよう設定を行うことで外部に出力することは可能なので、このようにタイムアウトのせいでロールバックも行われず、アーティファクトも出力されなかった場合に有用になるかもしれません。

terraform {
  backend "s3" {
    bucket         = "xxx"
    key            = "backend/fsx/terraform.tfstate"
    region         = "ap-northeast-1"
    encrypt        = true
  }
}

まとめ

本ブログでは CodeBuild に Lambda コンピューティングを使用して、アップデートにて追加されたカスタムイメージを Terraform で実行してみました。 Lambda コンピューティングはビルドの起動が早く、料金も安く実行可能ですが、タイムアウトした場合の処理も考えておかないと問題が発生する可能性があります。 そのため、時間がかかる処理を確実に完了させたい場合は向かない点、使用する場合は注意が必要になるでしょう。

末廣 満希(執筆記事の一覧)

2022年新卒入社です。ここに何かかっこいい一言を書くことができるエンジニアになれるように頑張ります。