コンテナイメージを使用して Go Lambda 関数をデプロイする
Go Lambda 関数のコンテナイメージを構築するには 2 つの方法があります。
-
Go は、他のマネージドランタイムとは異なる方法で実装されています。Go は実行可能バイナリにネイティブにコンパイルするため、専用の言語ランタイムは必要ありません。OS 専用のベースイメージを使用して、Lambda 用の Go イメージを構築します。イメージに Lambda との互換性を持たせるには、イメージに
aws-lambda-go/lambda
パッケージを含める必要があります。 -
Alpine Linux や Debian など、別のコンテナレジストリの代替ベースイメージを使用することもできます。組織が作成したカスタムイメージを使用することもできます。イメージに Lambda との互換性を持たせるには、イメージに
aws-lambda-go/lambda
パッケージを含める必要があります。
ヒント
Lambda コンテナ関数がアクティブになるまでの時間を短縮するには、「Docker ドキュメント」の「マルチステージビルドを使用する
このページでは、Lambda のコンテナイメージを構築、テスト、デプロイする方法について説明します。
Go 関数をデプロイするための AWS ベースイメージ
Go は、他のマネージドランタイムとは異なる方法で実装されています。Go は実行可能バイナリにネイティブにコンパイルするため、専用の言語ランタイムは必要ありません。OS 専用のベースイメージを使用して、Go 関数を Lambda にデプロイします。
名前 | 識別子 | オペレーティングシステム | 廃止日 | 関数の作成をブロックする | 関数の更新をブロックする |
---|---|---|---|---|---|
OS 専用ランタイム |
|
Amazon Linux 2023 |
スケジュールされていません |
スケジュールされていません |
スケジュールされていません |
OS 専用ランタイム |
|
Amazon Linux 2 |
スケジュールされていません |
スケジュールされていません |
スケジュールされていません |
Amazon Elastic コンテナレジストリ公開ギャラリー: gallery.ecr.aws/lambda/provided
Go 用ランタイムインターフェイスクライアント
aws-lambda-go/lambda
パッケージには、ランタイムインターフェイスの実装が含まれています。イメージで aws-lambda-go/lambda
を使用する方法の例については、AWS の OS 専用ベースイメージを使用する または 非 AWS ベースイメージを使用する を参照してください。
AWS の OS 専用ベースイメージを使用する
Go は、他のマネージドランタイムとは異なる方法で実装されています。Go は実行可能バイナリにネイティブにコンパイルするため、専用の言語ランタイムは必要ありません。OS 専用のベースイメージを使用して、Go 関数のコンテナイメージを構築します。
タグ | ランタイム | オペレーティングシステム | Dockerfile | 廃止 |
---|---|---|---|---|
al2023 |
OS 専用ランタイム | Amazon Linux 2023 | GitHub の OS 専用ランタイムの Dockerfile |
スケジュールされていません |
al2 |
OS 専用ランタイム | Amazon Linux 2 | GitHub の OS 専用ランタイムの Dockerfile |
スケジュールされていません |
これらのベースイメージの詳細については、Amazon ECR Public Gallery の「provided
aws-lambda-go/lambda
このセクションの手順を完了するには、以下が必要です。
provided.al2023
ベースイメージを使用して Go 関数をビルドしデプロイするには
-
プロジェクト用のディレクトリを作成し、そのディレクトリに切り替えます。
mkdir hello cd hello
-
新しい Go モジュールを初期化します。
go mod init
example.com/hello-world
-
Lambda ライブラリを新しいモジュールの依存関係として追加します。
go get github.com/aws/aws-lambda-go/lambda
-
「
main.go
」という名前のファイルを作成し、テキストエディタで開きます。これは Lambda 関数のコードです。次のサンプルコードをテストに使用することも、独自のサンプルコードで置き換えることもできます。package main import ( "context" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" ) func handler(ctx context.Context, event events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { response := events.APIGatewayProxyResponse{ StatusCode: 200, Body: "\"Hello from Lambda!\"", } return response, nil } func main() { lambda.Start(handler) }
-
テキストエディタを使用して、プロジェクトディレクトリに Dockerfile を作成します。
-
次の Dockerfile の例では、「マルチステージビルド
」が使用されます。これにより、各ステップで異なるベースイメージを使用できます。「Go ベースイメージ 」など、1 つのイメージを使用し、コードをコンパイルして実行可能なバイナリを構築できます。その後、最後の FROM
ステートメントでprovided.al2023
など別のイメージを使用し、Lambda にデプロイするイメージを定義できます。ビルドプロセスは最終デプロイイメージとは分離されているため、最終イメージにはアプリケーションの実行に必要なファイルのみが含まれます。 -
オプションの
lambda.norpc
タグを使用して、Lambdaライブラリの Remote Procedure Call (RPC) コンポーネントを除外することができます。RPC コンポーネントは、Go 1.x ランタイムを使用している場合にのみ必要です。RPC を除外すると、デプロイパッケージのサイズが小さくなります。 -
この例の Dockerfile には USER 命令
が含まれていないことに注意してください。コンテナイメージを Lambda にデプロイすると、最小特権のアクセス許可を付与したデフォルトの Linux ユーザーを Lambda が自動的に定義します。これは標準の Docker 動作とは異なります。標準の動作とは、 USER
命令を指定しなかったときにroot
ユーザーのデフォルトとなる動作のことです。
例 — マルチステージビルド Dockerfile
注記
Dockerfile で指定する Go のバージョン (たとえば、
golang:1.20
) が、アプリケーションの作成に使用した Go のバージョンと同じであることを確認してください。FROM
golang:1.20
as build WORKDIR /helloworld # Copy dependencies list COPY go.mod go.sum ./ # Build with optional lambda.norpc tag COPY main.go . RUN go build-tags lambda.norpc
-o main main.go # Copy artifacts to a clean image FROMpublic.ecr.aws/lambda/provided:al2023
COPY --from=build /helloworld/main ./main ENTRYPOINT [ "./main" ] -
-
Docker イメージを「Docker の構築
」コマンドで構築します。次の例では、イメージを docker-image
と名付けてtest
タグを付けます。 docker build --platform linux/amd64 -t
docker-image
:test
.注記
このコマンドは、ビルドマシンのアーキテクチャに関係なく、コンテナが Lambda の実行環境と互換性があることを確認する
--platform linux/amd64
オプションを特定します。ARM64 命令セットアーキテクチャを使用して Lambda 関数を作成する場合は、代わりに--platform linux/arm64
オプションを使用するようにコマンドを変更してください。
ランタイムインターフェイスエミュレーターprovided.al2023
ベースイメージには、ランタイムインターフェイスエミュレーターが含まれています。
ローカルマシンでランタイムインターフェイスエミュレーターを実行するには
-
docker run コマンドを使用して、Docker イメージを起動します。次の点に注意してください。
-
docker-image
はイメージ名、test
はタグです。 -
./main
は Dockerfile からのENTRYPOINT
です。
docker run -d -p 9000:8080 \ --entrypoint /usr/local/bin/aws-lambda-rie \
docker-image:test ./main
このコマンドはイメージをコンテナとして実行し、
localhost:9000/2015-03-31/functions/function/invocations
でローカルエンドポイントを作成します。 -
-
新しいターミナルウィンドウから、curl コマンドを使用して次のエンドポイントにイベントをポストします。
curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
このコマンドは、空のイベントで関数を呼び出し、応答を返します。関数によっては JSON ペイロードが必要な場合があります。例:
curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '
{"payload":"hello world!"}
' -
コンテナ ID を取得します。
docker ps
-
「docker kill
」コマンドを使用してコンテナを停止します。このコマンドでは、 3766c4ab331c
を前のステップのコンテナ ID で置き換えます。docker kill
3766c4ab331c
Amazon ECR にイメージをアップロードして Lambda 関数を作成するには
-
「get-login-password
」コマンドを実行して Amazon ECR レジストリに Docker CLI を認証します。 -
--region
値を Amazon ECR リポジトリを作成する AWS リージョン に設定します。 -
111122223333
を AWS アカウント ID に置き換えます。
aws ecr get-login-password --region
us-east-1
| docker login --username AWS --password-stdin111122223333
.dkr.ecr.us-east-1
.amazonaws.com -
-
「create-repository
」コマンドを使用して Amazon ECR にリポジトリを作成します。 aws ecr create-repository --repository-name
hello-world
--regionus-east-1
--image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE注記
Amazon ECR リポジトリは Lambda 関数と同じ AWS リージョン に配置されている必要があります。
成功すると、次のようなレスポンスが表示されます。
{ "repository": { "repositoryArn": "arn:aws:ecr:us-east-1:111122223333:repository/hello-world", "registryId": "111122223333", "repositoryName": "hello-world", "repositoryUri": "111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world", "createdAt": "2023-03-09T10:39:01+00:00", "imageTagMutability": "MUTABLE", "imageScanningConfiguration": { "scanOnPush": true }, "encryptionConfiguration": { "encryptionType": "AES256" } } }
-
前のステップの出力から
repositoryUri
をコピーします。 -
「docker tag
」コマンドを実行して、最新バージョンとしてローカルイメージを Amazon ECR リポジトリにタグ付けします。このコマンドで: -
docker-image:test
は、Docker イメージの名前とタグです。これは、 docker build
コマンドに指定したイメージの名前とタグです。 -
<ECRrepositoryUri>
を、コピーしたrepositoryUri
に置き換えます。URI の末尾には必ず:latest
を含めてください。
docker tag docker-image:test
<ECRrepositoryUri>
:latest例:
docker tag
docker-image
:test
111122223333
.dkr.ecr.us-east-1
.amazonaws.com/hello-world
:latest -
-
「docker push
」コマンドを実行して Amazon ECR リポジトリにローカルイメージをデプロイします リポジトリ URI の末尾には必ず :latest
を含めてください。docker push
111122223333
.dkr.ecr.us-east-1
.amazonaws.com/hello-world
:latest -
まだ作成済みでない場合、関数に「実行ロールの作成」を実行してください。次のステップではロールの Amazon リソースネーム (ARN) が必要です。
-
Lambda 関数を作成します。
ImageUri
には、先ほど使用したリポジトリ URI を指定します。URI の末尾には必ず:latest
を含めてください。aws lambda create-function \ --function-name
hello-world
\ --package-type Image \ --code ImageUri=111122223333
.dkr.ecr.us-east-1
.amazonaws.com/hello-world
:latest \ --rolearn:aws:iam::111122223333:role/lambda-ex
注記
イメージが Lambda 関数と同じリージョンに配置されていれば、別の AWS アカウントのイメージを使用して関数を作成することができます。詳細については、「 Amazon ECR クロスアカウント許可」を参照してください。
-
関数を呼び出します。
aws lambda invoke --function-name
hello-world
response.json次のような結果が表示されます。
{ "ExecutedVersion": "$LATEST", "StatusCode": 200 }
-
関数の出力を確認するには、
response.json
ファイルをチェックします。
関数コードを更新するには、イメージを再構築し、新しいイメージを Amazon ECR リポジトリにアップロードしてから、update-function-code
Lambda は、イメージタグを特定のイメージダイジェストに解決します。これは、関数のデプロイに使用されたイメージタグを Amazon ECR 内の新しいイメージを指すように変更しても、Lambda は新しいイメージを使用するように自動的に関数を更新しないことを意味します。
新しいイメージを同じ Lambda 関数にデプロイするには、Amazon ECR のイメージタグが同じままであっても、update-function-code--publish
オプションが最新のコンテナイメージを使用して関数の新しいバージョンを作成しています。
aws lambda update-function-code \ --function-name
hello-world
\ --image-uri111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
\ --publish
非 AWS ベースイメージを使用する
非 AWS ベースイメージからも、Go 用のコンテナイメージを構築できます。次のステップでは、Dockerfile の例で Alpine ベースイメージ
aws-lambda-go/lambda
このセクションの手順を完了するには、以下が必要です。
Alpine ベースイメージを使用して Go 関数をビルドおよびデプロイするには
-
プロジェクト用のディレクトリを作成し、そのディレクトリに切り替えます。
mkdir hello cd hello
-
新しい Go モジュールを初期化します。
go mod init
example.com/hello-world
-
Lambda ライブラリを新しいモジュールの依存関係として追加します。
go get github.com/aws/aws-lambda-go/lambda
-
「
main.go
」という名前のファイルを作成し、テキストエディタで開きます。これは Lambda 関数のコードです。次のサンプルコードをテストに使用することも、独自のサンプルコードで置き換えることもできます。package main import ( "context" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" ) func handler(ctx context.Context, event events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { response := events.APIGatewayProxyResponse{ StatusCode: 200, Body: "\"Hello from Lambda!\"", } return response, nil } func main() { lambda.Start(handler) }
-
テキストエディタを使用して、プロジェクトディレクトリに Dockerfile を作成します。次の Dockerfile の例では、Alpine ベースイメージ
を使用しています。この例の Dockerfile には USER 命令 が含まれていないことに注意してください。コンテナイメージを Lambda にデプロイすると、最小特権のアクセス許可を付与したデフォルトの Linux ユーザーを Lambda が自動的に定義します。これは標準の Docker 動作とは異なります。標準の動作とは、 USER
命令を指定しなかったときにroot
ユーザーのデフォルトとなる動作のことです。例 Dockerfile
注記
Dockerfile で指定する Go のバージョン (たとえば、
golang:1.20
) が、アプリケーションの作成に使用した Go のバージョンと同じであることを確認してください。FROM golang:1.20.2-alpine3.16 as build WORKDIR /helloworld # Copy dependencies list COPY go.mod go.sum ./ # Build COPY main.go . RUN go build -o main main.go # Copy artifacts to a clean image FROM alpine:3.16 COPY --from=build /helloworld/main /main ENTRYPOINT [ "/main" ]
-
Docker イメージを「Docker の構築
」コマンドで構築します。次の例では、イメージを docker-image
と名付けてtest
タグを付けます。 docker build --platform linux/amd64 -t
docker-image
:test
.注記
このコマンドは、ビルドマシンのアーキテクチャに関係なく、コンテナが Lambda の実行環境と互換性があることを確認する
--platform linux/amd64
オプションを特定します。ARM64 命令セットアーキテクチャを使用して Lambda 関数を作成する場合は、代わりに--platform linux/arm64
オプションを使用するようにコマンドを変更してください。
ランタイムインターフェイスエミュレーター
ローカルマシンにランタイムインターフェイスエミュレーターをインストールして実行するには
-
プロジェクトディレクトリから次のコマンドを実行して、GitHub からランタイムインターフェイスエミュレーター (x86-64 アーキテクチャ) をダウンロードし、ローカルマシンにインストールします。
-
docker run コマンドを使用して、Docker イメージを起動します。次の点に注意してください。
-
docker-image
はイメージ名、test
はタグです。 -
/main
は Dockerfile からのENTRYPOINT
です。
このコマンドはイメージをコンテナとして実行し、
localhost:9000/2015-03-31/functions/function/invocations
でローカルエンドポイントを作成します。注記
ARM64 命令セットアーキテクチャ用に Docker イメージをビルドした場合は、
--platform linux/
の代わりにamd64
--platform linux/
オプションを使用してください。arm64
-
-
イベントをローカルエンドポイントにポストします。
-
コンテナ ID を取得します。
docker ps
-
「docker kill
」コマンドを使用してコンテナを停止します。このコマンドでは、 3766c4ab331c
を前のステップのコンテナ ID で置き換えます。docker kill
3766c4ab331c
Amazon ECR にイメージをアップロードして Lambda 関数を作成するには
-
「get-login-password
」コマンドを実行して Amazon ECR レジストリに Docker CLI を認証します。 -
--region
値を Amazon ECR リポジトリを作成する AWS リージョン に設定します。 -
111122223333
を AWS アカウント ID に置き換えます。
aws ecr get-login-password --region
us-east-1
| docker login --username AWS --password-stdin111122223333
.dkr.ecr.us-east-1
.amazonaws.com -
-
「create-repository
」コマンドを使用して Amazon ECR にリポジトリを作成します。 aws ecr create-repository --repository-name
hello-world
--regionus-east-1
--image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE注記
Amazon ECR リポジトリは Lambda 関数と同じ AWS リージョン に配置されている必要があります。
成功すると、次のようなレスポンスが表示されます。
{ "repository": { "repositoryArn": "arn:aws:ecr:us-east-1:111122223333:repository/hello-world", "registryId": "111122223333", "repositoryName": "hello-world", "repositoryUri": "111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world", "createdAt": "2023-03-09T10:39:01+00:00", "imageTagMutability": "MUTABLE", "imageScanningConfiguration": { "scanOnPush": true }, "encryptionConfiguration": { "encryptionType": "AES256" } } }
-
前のステップの出力から
repositoryUri
をコピーします。 -
「docker tag
」コマンドを実行して、最新バージョンとしてローカルイメージを Amazon ECR リポジトリにタグ付けします。このコマンドで: -
docker-image:test
は、Docker イメージの名前とタグです。これは、 docker build
コマンドに指定したイメージの名前とタグです。 -
<ECRrepositoryUri>
を、コピーしたrepositoryUri
に置き換えます。URI の末尾には必ず:latest
を含めてください。
docker tag docker-image:test
<ECRrepositoryUri>
:latest例:
docker tag
docker-image
:test
111122223333
.dkr.ecr.us-east-1
.amazonaws.com/hello-world
:latest -
-
「docker push
」コマンドを実行して Amazon ECR リポジトリにローカルイメージをデプロイします リポジトリ URI の末尾には必ず :latest
を含めてください。docker push
111122223333
.dkr.ecr.us-east-1
.amazonaws.com/hello-world
:latest -
まだ作成済みでない場合、関数に「実行ロールの作成」を実行してください。次のステップではロールの Amazon リソースネーム (ARN) が必要です。
-
Lambda 関数を作成します。
ImageUri
には、先ほど使用したリポジトリ URI を指定します。URI の末尾には必ず:latest
を含めてください。aws lambda create-function \ --function-name
hello-world
\ --package-type Image \ --code ImageUri=111122223333
.dkr.ecr.us-east-1
.amazonaws.com/hello-world
:latest \ --rolearn:aws:iam::111122223333:role/lambda-ex
注記
イメージが Lambda 関数と同じリージョンに配置されていれば、別の AWS アカウントのイメージを使用して関数を作成することができます。詳細については、「 Amazon ECR クロスアカウント許可」を参照してください。
-
関数を呼び出します。
aws lambda invoke --function-name
hello-world
response.json次のような結果が表示されます。
{ "ExecutedVersion": "$LATEST", "StatusCode": 200 }
-
関数の出力を確認するには、
response.json
ファイルをチェックします。
関数コードを更新するには、イメージを再構築し、新しいイメージを Amazon ECR リポジトリにアップロードしてから、update-function-code
Lambda は、イメージタグを特定のイメージダイジェストに解決します。これは、関数のデプロイに使用されたイメージタグを Amazon ECR 内の新しいイメージを指すように変更しても、Lambda は新しいイメージを使用するように自動的に関数を更新しないことを意味します。
新しいイメージを同じ Lambda 関数にデプロイするには、Amazon ECR のイメージタグが同じままであっても、update-function-code--publish
オプションが最新のコンテナイメージを使用して関数の新しいバージョンを作成しています。
aws lambda update-function-code \ --function-name
hello-world
\ --image-uri111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
\ --publish