木曜日, 5月 8, 2025
No menu items!
ホームニューステックニュースTerraform で DockerイメージをLambdaへデプロイ

Terraform で DockerイメージをLambdaへデプロイ


今回は、Terraformを使用してDockerイメージをLambdaへデプロイする手順を紹介していこうと思います。
本記事では、TerraformからECRへDockerイメージをプッシュし、それをLambdaで実行するシンプルな構成をまとめています。

まず簡単にTerraformについてまとめていきます。
一言で言えば、IaCの一種でクラウドリソースをコード化することができるツールです。
Terraform は、AWS、Azure、GCP など、1000 以上のプロバイダーに対応しており、異なるプロバイダーのリソースをHCL(HashiCorp Configuration Language) という言語で管理できます。
Terraformを使用する上で覚えていきたいコマンドは以下の5つです。

  • terraform init

    • Terraformプロジェクトの初期化を行うコマンド
    • プロバイダーのダウンロードとインストールバックエンドの初期化モジュールのダウンロードをしてくれます
  • terraform plan

    • 現在の状態から目的の状態への変更内容を確認するコマンド
  • terraform apply

    • インフラストラクチャに変更を適用するコマンド
    • 実行後は、planの結果が表示され、続行の確認が求められます
  • terraform destroy

    • Terraform で作成したすべてのリソースを削除するコマンド
  • terraform fmt

    • Terraformの設定ファイルを標準的なフォーマットに整形するコマンド
    • インデントの調整・改行の統一・スペースの調整をしてくれます


本記事では、リージョンを「ap-northeast-1(東京)」に設定して、Terraformを使った Lambdaデプロイを構築していきます。

なお、実際に使用したコードや構成ファイルは以下のGitHubリポジトリで公開しています。

https://github.com/anton-fuji/terraform_lambda_docker

Dockerfileの作成

まずは、Lambda関数のベースとなるDockerイメージを用意します。
今回は Python 3.13 の Lambda ランタイムを使用します。
apiディレクトリを作成し、以下の内容で Dockerfileを作成してください。

FROM --platform=linux/amd64 public.ecr.aws/lambda/python:3.13

COPY app.py ${LAMBDA_TASK_ROOT}

CMD [ "app.handler" ]
  • --platform=linux/amd64は、Apple M1/M2 チップなどのARM環境でビルドエラーを避けるための指定
  • LAMBDA_TASK_ROOTは、AWS Lambdaが実行時にコードを読み込むディレクトリ

app.pyの作成

次に、Lambda 関数の処理本体となる app.py を作成します。
先ほどのDockerfileではこのファイルをコンテナ内にコピーし、handler関数をエントリーポイントとしています。
以下の内容でapi/app.pyを作成してください。

import json

def handler(event, context):
    print(event)
    
    return {
        "statusCode": 200,
        "body": json.dumps({ "message": "Hello, Lambda!" })
    }

Lambdaが正常に動作すると "Hello, Lambda!"というメッセージが返されるシンプルな構成にしています。
今回は Pythonの標準ライブラリのみを使用しているため、requirements.txtの作成やパッケージのインストールは行っていません。

ローカルで関数をテストする

では、実際に機能するかをdockerをビルドして確かめてみましょう。
以下の手順に従って確認していきましょう。


cd api


docker build -t api .


docker run -p 9000:8080 api


curl -XPOST "" -d '{"payload":"Hello, Lambda!"}'

以下のJSONが得られたら、テスト成功です。

{
  "statusCode": 200,
  "body": "{\"message\": \"Hello, Lambda!\"}"
}

今回は以下の2つのファイルを用意します。

  • main.tf

    • Terraform の基本設定用のファイル
    • どのクラウド(AWS)・ツール(Docker)を使うかを記述しています
  • api.tf

    • ECRとLambdaを構築・デプロイするためのファイル

main.tfについて

main.tfファイルでは、Terraformがどのプロバイダ(AWSやDockerなど)を使用するか、また AWS の接続先リージョンを指定しています。

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
    docker = {
      source  = "kreuzwerker/docker"
      version = "~> 3.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1" 
}
  • required_providers

    • awsdocker はTerraformで操作したいサービス群を意味します
    • source はそのプロバイダがどこから提供されているか(hashicorp/aws)
    • version は互換性のあるバージョンを指定しており、たとえば “~> 5.0” は 5.x 系の最新版を自動で使うという意味です
  • provider

    • どのリージョンのAWSに対してリソースを作成するかを指定します

api.tfについて

api.tfファイルでは、以下の3つの処理をまとめて行っています

  • DockerイメージのビルドECRへのプッシュ
  • Lambda関数の作成
  • Dockerレジストリへの認証設定(Terraform が ECR に push するため)
data "aws_ecr_authorization_token" "token" {}

data "aws_caller_identity" "current" {}

provider "docker" {
  registry_auth {
    address  = "${data.aws_caller_identity.current.account_id}.dkr.ecr.ap-northeast-1.amazonaws.com"
    username = data.aws_ecr_authorization_token.token.user_name
    password = data.aws_ecr_authorization_token.token.password
  }
}

module "lambda_function" {
  source = "terraform-aws-modules/lambda/aws"

  function_name  = "python-api"
  create_package = false

  image_uri    = module.docker_image.image_uri
  package_type = "Image"

  depends_on = [module.docker_image]
}

module "docker_image" {
  source = "terraform-aws-modules/lambda/aws//modules/docker-build"

  create_ecr_repo = true
  ecr_repo        = "python-api"

  use_image_tag = true
  image_tag     = "1.0"

  triggers = {
    redeployment = timestamp()
  }

  source_path = "../api"
}

こちらのファイルでは以下のポイントに気をつけてください。

Docker イメージを使う Lambda 関数の定義

module "lambda_function" {
  source = "terraform-aws-modules/lambda/aws"

  function_name  = "python-api"
  create_package = false

  image_uri    = module.docker_image.image_uri
  package_type = "Image"

  depends_on = [module.docker_image]
}
  • create_package = false

    • 今回はzipではなくDockerイメージを使うため、こちらは必須
  • image_uri

    • ECRに登録されたDockerイメージを指定
  • depends_on

    • ビルドされたイメージが先に必要なので依存関係を明示

Dockerレジストリの認証

provider "docker" {
  registry_auth {
    address  = "${data.aws_caller_identity.current.account_id}.dkr.ecr.ap-northeast-1.amazonaws.com"
    username = data.aws_ecr_authorization_token.token.user_name
    password = data.aws_ecr_authorization_token.token.password
  }
}
  • Docker CLIではなくTerraformが docker push するための認証設定です
  • usernamepasswordには、AWSから取得したECR認証トークンの値を使用しています
  • address(ECR のURL)に関しては${data.aws_caller_identity.current.account_id} を使って動的にアカウントIDを取得しています
    • もちろん、ここは “123456789012.dkr.ecr.ap-northeast-1.amazonaws.com” のように手動で書いても問題ありませんが、複数人で使う場合・GitHubでソースコードを管理する場合は自動化しておく方が安全です

では、ここから実際にTerraformを使ってLambdaのデプロイ作業を行っていきます。
今回は、AWS CloudShellを利用して作業を進めました。
CloudShellは AWS マネジメントコンソールからすぐに開けて、IAMロールに紐づく認証情報が自動で使えるため、Terraform の初期実行にも非常に便利です。

Step.1 CloudShellでTerraformのセットアップ


wget https://releases.hashicorp.com/terraform/1.11.4/terraform_1.11.4_linux_amd64.zip


sudo unzip terraform_1.11.4_linux_amd64.zip -d /usr/local/bin/


terraform -version  

Step.2 GitHub から Terraform ファイルを取得

先ほど作成したものを、GitHub上におき、そちらをCloudShell上でgit clone を使って取得します。

git clone https://github.com/your-username/your-repo-name.git


cd your-repo-name

Step.3 Terraformでリソースをデプロイ

① Terraformの初期化

main.tf, api.tfファイルがあることを確認し、以下のコマンドを実行してください。

コマンド入力後は、以下の出力があればinitの完了です。

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

これにより、必要なプロバイダやモジュールが .terraform/ディレクトリにダウンロードされ、Terraformの実行準備が整います。

もし、init実行時に"no space left on device"エラーが発生した場合は、以下の記事を参考に対応してください。

https://qiita.com/free-honda/items/14fad93c1d0b8f6cda35#はじめに

② デプロイの実行!

terraform apply --auto-approve

--auto-approveを付けることで、yesの確認を省略して自動で処理が進みます。
実行すると以下のような感じでモジュールが作成されていきます。

以下のメッセージが出力されれば、Terraformでの実行は完了です。

Apply complete! Resources: 7 added, 0 changed, 0 destroyed.

デプロイできたか確認

ECRへ移動して、実際にpython-apiがあるか確認してください。

次は、Lambdaへ移動しpython-api関数がECRのイメージを参照していれば、デプロイ完了です!

新しいイベントを実行してみる

デプロイが完了したら、Lambda 関数が正しく動作するかどうかをテストしてみましょう。
まずは、AWSマネジメントコンソール上でLambdaに移動し、関数ページの右上にある「テスト」ボタンをクリックします。
以下の画像の通りに進め、イベント名は任意で大丈夫です。JSONはデフォルトのままで問題ありません。
Lambdaテストイベント作成

テスト」を実行すると、以下のように Lambda のレスポンス結果が表示されます。
成功すれば、"Hello, Lambda!" というメッセージが返ってくることを確認できます。
成功

これで、Lambda関数がDockerイメージをもとに正しく動作していることが確認できました!
なお、このイベント実行の内容は CloudWatch Logs にも記録されます
必要に応じて CloudWatch側のログを確認しながら作業を進めるのもおすすめです。

最後に検証終了後は、リソースを以下のコマンドで全て削除しておきましょう。

terraform destroy --auto-approve

今回は、Terraform を使って Docker イメージを AWS Lambda にデプロイする手順を紹介しました。
手動でリソースを構築するのではなく、コード化して管理することでインフラの再現性・可搬性・チームでの共有性が大きく向上することを体感できました。
引き続きTerraformの学習を頑張っていこうと思います。
最後まで読んでいただきありがとうございました!

https://gallery.ecr.aws/lambda/python

https://registry.terraform.io/modules/terraform-aws-modules/lambda/aws/latest/submodules/docker-build

https://releases.hashicorp.com/terraform/

https://qiita.com/free-honda/items/14fad93c1d0b8f6cda35#はじめに

フラッグシティパートナーズ海外不動産投資セミナー 【DMM FX】入金

Source link

Views: 2

RELATED ARTICLES

返事を書く

あなたのコメントを入力してください。
ここにあなたの名前を入力してください

- Advertisment -

Most Popular