

# Go による Lambda 関数の構築
<a name="lambda-golang"></a>

Go は、他のマネージドランタイムとは異なる方法で実装されています。Go は実行可能バイナリにネイティブにコンパイルするため、専用の言語ランタイムは必要ありません。Go 関数を Lambda にデプロイするには、[OS 専用ランタイム](runtimes-provided.md) (`provided` ランタイム ファミリ) を使用します。

**Topics**
+ [Go ランタイムのサポート](#golang-al1)
+ [ツールとライブラリ](#golang-libraries)
+ [Go の Lambda 関数ハンドラーの定義](golang-handler.md)
+ [Lambda コンテキストオブジェクトを使用して Go 関数の情報を取得する](golang-context.md)
+ [.zip ファイルアーカイブを使用して Go Lambda 関数をデプロイする](golang-package.md)
+ [コンテナイメージを使用して Go Lambda 関数をデプロイする](go-image.md)
+ [Go Lambda 関数のレイヤーを操作する](golang-layers.md)
+ [Go Lambda 関数のログ記録とモニタリング](golang-logging.md)
+ [AWS Lambda での Go コードの作成](golang-tracing.md)

## Go ランタイムのサポート
<a name="golang-al1"></a>

Lambda の Go 1.x マネージドランタイムは[非奨励になりました](lambda-runtimes.md#runtime-support-policy)。Go 1.x ランタイムを使用する関数がある場合は、関数を `provided.al2023` または `provided.al2` に移行する必要があります。`provided.al2023` および `provided.al2` ランタイムには、arm64 アーキテクチャのサポート (AWS Graviton2 プロセッサー)、バイナリの小型化、若干の呼び出し時間短縮化など、`go1.x` と比べていくつか利点があります。

この移行ではコードの変更は必要ありません。必要な変更は、デプロイパッケージの構築方法と、関数の作成に使用するランタイムに関するもののみです。詳細については、「*AWS コンピュートブログ*」の「[AWS Lambda 関数を Go1.x ランタイムから Amazon Linux 2 のカスタムラインタイムに移行](https://aws.amazon.com/blogs/compute/migrating-aws-lambda-functions-from-the-go1-x-runtime-to-the-custom-runtime-on-amazon-linux-2/)」を参照してください。


| 名前 | 識別子 | オペレーティングシステム | 廃止日 | 関数の作成をブロックする | 関数の更新をブロックする | 
| --- | --- | --- | --- | --- | --- | 
|  OS 専用ランタイム  |  `provided.al2023`  |  Amazon Linux 2023  |   2029 年 6 月 30 日   |   2029 年 7 月 31 日   |   2029 年 8 月 31 日   | 
|  OS 専用ランタイム  |  `provided.al2`  |  Amazon Linux 2  |   2026 年 7 月 31 日   |   2026 年 8 月 31 日   |   Sep 30, 2026   | 

## ツールとライブラリ
<a name="golang-libraries"></a>

Lambda は、Go ランタイム用の次のツールとライブラリを提供します。
+ [AWS SDK for Go v2](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2): Go プログラミング言語用の公式の AWS SDK。
+ [github.com/aws/aws-lambda-go/lambda](https://github.com/aws/aws-lambda-go/tree/master/lambda): Go 用の Lambda プログラミングモデルの実装。このパッケージは、[ハンドラー](golang-handler.md)を呼び出すために AWS Lambda で使用されます。
+ [github.com/aws/aws-lambda-go/lambdacontext](https://github.com/aws/aws-lambda-go/tree/master/lambdacontext): [コンテキストオブジェクト](golang-context.md)からコンテキスト情報にアクセスするためのヘルパー。
+ [github.com/aws/aws-lambda-go/events](https://github.com/aws/aws-lambda-go/tree/master/events): このライブラリは一般的なイベントソース統合のタイプの定義を提供します。
+ [github.com/aws/aws-lambda-go/cmd/build-lambda-zip](https://github.com/aws/aws-lambda-go/tree/master/cmd/build-lambda-zip): このツールは、Windows で .zip ファイルアーカイブを作成するために使用することができます。

詳細については、GitHub の「[aws-lambda-go](https://github.com/aws/aws-lambda-go)」をご参照ください。

Lambda は、Go ランタイム用の次のサンプルアプリケーションを提供します。

**Go のサンプル Lambda アプリケーション**
+ [go-al2](https://github.com/aws-samples/sessions-with-aws-sam/tree/master/go-al2) — パブリック IP アドレスを返す Hello World 関数。このアプリは `provided.al2` カスタムランタイムを使用しています。
+ [blank-go](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-go) – Lambda の Go ライブラリ、ログ記録、環境変数、AWS SDK の使用を示す Go 関数。このアプリは `go1.x` ランタイムを使用しています。

# Go の Lambda 関数ハンドラーの定義
<a name="golang-handler"></a>

Lambda 関数*ハンドラー*は、イベントを処理する関数コード内のメソッドです。関数が呼び出されると、Lambda はハンドラーメソッドを実行します。関数は、ハンドラーが応答を返すか、終了するか、タイムアウトするまで実行されます。

このページでは、プロジェクトのセットアップ、命名規則、ベストプラクティスなど、Go で Lambda 関数ハンドラーを操作する方法について説明します。このページには、注文に関する情報を取得し、テキストファイル受信を生成し、このファイルを Amazon Simple Storage Service (Amazon S3) バケットに配置する Go Lambda 関数の例も含まれています。関数を書き込んだ後にデプロイする方法については、「[.zip ファイルアーカイブを使用して Go Lambda 関数をデプロイする](golang-package.md)」または「[コンテナイメージを使用して Go Lambda 関数をデプロイする](go-image.md)」を参照してください。

**Topics**
+ [Go ハンドラープロジェクトのセットアップ](#golang-handler-setup)
+ [Go Lambda 関数のコードの例](#golang-example-code)
+ [ハンドラーの命名規則](#golang-handler-naming)
+ [入力イベントオブジェクトの定義とアクセス](#golang-example-input)
+ [Lambda コンテキストオブジェクトへのアクセスと使用](#golang-example-context)
+ [Go ハンドラーの有効なハンドラー署名](#golang-handler-signatures)
+ [ハンドラーでの AWS SDK for Go v2 の使用](#golang-example-sdk-usage)
+ [環境変数にアクセスする](#golang-example-envvars)
+ [グローバルな状態を使用する](#golang-handler-state)
+ [Lambda 関数のコードのベストプラクティス](#go-best-practices)

## Go ハンドラープロジェクトのセットアップ
<a name="golang-handler-setup"></a>

[Go](https://golang.org/) で書き込まれた Lambda 関数は、Go 実行可能ファイルとして作成されます。Go Lambda 関数プロジェクトは、以下の `go mod init` コマンドを使用して他の Go プロジェクトを初期化するのと同じ方法で初期化できます:

```
go mod init example-go
```

ここでは、`example-go` がモジュール名です。これは何にでも置き換えることができます。このコマンドはプロジェクトを初期化し、プロジェクトの依存関係を一覧表示する `go.mod` ファイルを生成します。

`go get` コマンドを使用して、外部依存関係をプロジェクトに追加します。例えば、Go のすべての Lambda 関数には、Go 用の Lambda プログラミングモデルを実装する [github.com/aws/aws-lambda-go/lambda](https://github.com/aws/aws-lambda-go/tree/master/lambda) パッケージを含める必要があります。以下の `go get` コマンドでこのパッケージを含めます:

```
go get github.com/aws/aws-lambda-go
```

関数コードは Go ファイルに存在する必要があります。以下の例では、この `main.go` ファイルに名前を付けます。このファイルではハンドラーメソッドに、このハンドラーを呼び出す `main()` 関数と同様にコア関数ロジックを実装します。

## Go Lambda 関数のコードの例
<a name="golang-example-code"></a>

以下の Go Lambda 関数コードの例では、注文に関する情報を取得し、テキストファイル受信を生成し、このファイルを Amazon S3 バケットに配置します。

**Example `main.go` Lambda 関数**  

```
package main

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"os"
	"strings"

	"github.com/aws/aws-lambda-go/lambda"
	"github.com/aws/aws-sdk-go-v2/config"
	"github.com/aws/aws-sdk-go-v2/service/s3"
)

type Order struct {
	OrderID string  `json:"order_id"`
	Amount  float64 `json:"amount"`
	Item    string  `json:"item"`
}

var (
	s3Client *s3.Client
)

func init() {
	// Initialize the S3 client outside of the handler, during the init phase
	cfg, err := config.LoadDefaultConfig(context.TODO())
	if err != nil {
		log.Fatalf("unable to load SDK config, %v", err)
	}

	s3Client = s3.NewFromConfig(cfg)
}

func uploadReceiptToS3(ctx context.Context, bucketName, key, receiptContent string) error {
	_, err := s3Client.PutObject(ctx, &s3.PutObjectInput{
		Bucket: &bucketName,
		Key:    &key,
		Body:   strings.NewReader(receiptContent),
	})
	if err != nil {
		log.Printf("Failed to upload receipt to S3: %v", err)
		return err
	}
	return nil
}

func handleRequest(ctx context.Context, event json.RawMessage) error {
	// Parse the input event
	var order Order
	if err := json.Unmarshal(event, &order); err != nil {
		log.Printf("Failed to unmarshal event: %v", err)
		return err
	}

	// Access environment variables
	bucketName := os.Getenv("RECEIPT_BUCKET")
	if bucketName == "" {
		log.Printf("RECEIPT_BUCKET environment variable is not set")
		return fmt.Errorf("missing required environment variable RECEIPT_BUCKET")
	}

	// Create the receipt content and key destination
	receiptContent := fmt.Sprintf("OrderID: %s\nAmount: $%.2f\nItem: %s",
		order.OrderID, order.Amount, order.Item)
	key := "receipts/" + order.OrderID + ".txt"

	// Upload the receipt to S3 using the helper method
	if err := uploadReceiptToS3(ctx, bucketName, key, receiptContent); err != nil {
		return err
	}

	log.Printf("Successfully processed order %s and stored receipt in S3 bucket %s", order.OrderID, bucketName)
	return nil
}

func main() {
	lambda.Start(handleRequest)
}
```

この `main.go` ファイルには以下のコードのセクションが含まれます:
+ `package main`: Go では、`func main()` 関数を含むパッケージは常に `main` と名付けられる必要があります。
+ `import` ブロック: このブロックを使用して、Lambda 関数に必要なライブラリを含めます。
+ `type Order struct {}` ブロック: この Go 構造体で予想される入力イベントの形状を定義します。
+ `var ()` ブロック: このブロックを使用して、Lambda 関数で使用するグローバル変数を定義します。
+ `func init() {}`: この `init()` メソッドには、[初期化フェーズ](lambda-runtime-environment.md#runtimes-lifecycle-ib) 中に Lambda を実行するコードを含めます。
+ `func uploadReceiptToS3(...) {}`: これは、メイン `handleRequest` ハンドラーメソッドによって参照されるヘルパーメソッドです。
+ `func handleRequest(ctx context.Context, event json.RawMessage) error {}`: これは**メインハンドラーメソッド**で、メインアプリケーションロジックが含まれています。
+ `func main() {}`: これは Lambda ハンドラーに必要なエントリポイントです。`lambda.Start()` メソッドの引数は、メインハンドラーメソッドです。

この関数が正しく機能するには、[実行ロール](lambda-intro-execution-role.md)で `s3:PutObject` アクションを許可する必要があります。また、必ず `RECEIPT_BUCKET` 環境変数を定義してください。呼び出しに成功したら、Amazon S3 バケットに受信ファイルが含まれているはずです。

## ハンドラーの命名規則
<a name="golang-handler-naming"></a>

Go の Lambda 関数では、ハンドラーに任意の名前を使用できます。この例では、ハンドラーメソッド名は `handleRequest` です。コード内でハンドラー値を参照するには、`_HANDLER` 環境変数を使用できます。

[.zip デプロイパッケージ](golang-package.md)を使用してデプロイされた Go 関数の場合、関数コードを含む実行ファイルには `bootstrap` という名前を付ける必要があります。さらに、`bootstrap` ファイルは、.zip ファイルのルートに置く必要があります。[コンテナイメージ](go-image.md#go-image-provided)を使用してデプロイされた Go 関数の場合、実行ファイルには任意の名前を使用できます。

## 入力イベントオブジェクトの定義とアクセス
<a name="golang-example-input"></a>

JSON は Lambda 関数の最も一般的な標準入力形式です。この例では、関数は以下のような入力を想定しています:

```
{
    "order_id": "12345",
    "amount": 199.99,
    "item": "Wireless Headphones"
}
```

Go で Lambda 関数を使用する場合、予想される入力イベントの形状を Go 構造体として定義できます。この例では、`Order` を表す構造体を定義します。

```
type Order struct {
    OrderID string  `json:"order_id"`
    Amount  float64 `json:"amount"`
    Item    string  `json:"item"`
}
```

この構造体は、予想される入力形状と一致します。構造体を定義したら、[encoding/json 標準ライブラリ](https://pkg.go.dev/encoding/json)と互換性のある汎用 JSON 型を取り込むハンドラー署名を記述できます。その後、[func Unmarshal](https://golang.org/pkg/encoding/json/#Unmarshal) 関数を使用して、構造体に逆シリアル化できます。これはハンドラーの最初の数行に示されています:

```
func handleRequest(ctx context.Context, event json.RawMessage) error {
    // Parse the input event
    var order Order
    if err := json.Unmarshal(event, &order); err != nil {
        log.Printf("Failed to unmarshal event: %v", err)
        return err
    ...
}
```

この逆シリアル化の後、`order` 変数のフィールドにアクセスできます。例えば、`order.OrderID` は元の入力から `"order_id"` の値を取得します。

**注記**  
`encoding/json` パッケージはエクスポートされたフィールドにのみアクセスできます。エクスポートするには、イベント構造体のフィールド名が大文字である必要があります。

## Lambda コンテキストオブジェクトへのアクセスと使用
<a name="golang-example-context"></a>

Lambda [コンテキストオブジェクト](golang-context.md)には、呼び出し、関数、および実行環境に関する情報が含まれます。この例では、ハンドラー署名でこの変数を `ctx` として宣言しました:

```
func handleRequest(ctx context.Context, event json.RawMessage) error {
    ...
}
```

`ctx context.Context` 入力は、関数ハンドラーのオプション引数です。受理されたハンドラー署名の詳細については、「[Go ハンドラーの有効なハンドラー署名](#golang-handler-signatures)」を参照してください。

AWS SDK を使用して他のサービスを呼び出す場合、コンテキストオブジェクトはいくつかの重要な領域で必要です。例えば、SDK クライアントを適切に初期化するには、以下のようにコンテキストオブジェクトを使用して正しい AWS SDK 設定をロードできます:

```
// Load AWS SDK configuration using the default credential provider chain
    cfg, err := config.LoadDefaultConfig(ctx)
```

SDK 呼び出し自体では、コンテキストオブジェクトを入力として必要とする場合があります。例えば、`s3Client.PutObject` 呼び出しはコンテキストオブジェクトを最初の引数として受け入れます:

```
// Upload the receipt to S3
    _, err = s3Client.PutObject(ctx, &s3.PutObjectInput{
        ...
    })
```

AWS SDK リクエスト以外では、関数のモニタリングにコンテキストオブジェクトを使用することもできます。コンテキストオブジェクトの詳細については、「[Lambda コンテキストオブジェクトを使用して Go 関数の情報を取得する](golang-context.md)」を参照してください。

## Go ハンドラーの有効なハンドラー署名
<a name="golang-handler-signatures"></a>

Go で Lambda 関数ハンドラーを構築するには複数の方法がありますが、次のルールに従う必要があります。
+ ハンドラーは関数である必要があります。
+ ハンドラーは 0 から 2 までの引数を取る場合があります。2 つの引数がある場合は、最初の引数が `context.Context` を実装する必要があります。
+ ハンドラーは 0 から 2 までの引数を返す場合があります。単一の戻り値がある場合は、この値が `error` を実装する必要があります。2 つの戻り値がある場合には、2 番目の値が `error` を実装している必要があります。

次のリストは、有効なハンドラー署名の一覧です。 `TIn` と `TOut` は、 *encoding/json* 標準ライブラリと互換性のあるタイプを表しています。詳細については、「[func アンマーシャリング](https://golang.org/pkg/encoding/json/#Unmarshal)」でこれらのタイプが逆シリアル化する方法を参照してください。
+ 

  ```
  func ()
  ```
+ 

  ```
  func () error
  ```
+ 

  ```
  func () (TOut, error)
  ```
+ 

  ```
  func (TIn) error
  ```
+ 

  ```
  func (TIn) (TOut, error)
  ```
+ 

  ```
  func (context.Context) error
  ```
+ 

  ```
  func (context.Context) (TOut, error)
  ```
+ 

  ```
  func (context.Context, TIn) error
  ```
+ 

  ```
  func (context.Context, TIn) (TOut, error)
  ```

## ハンドラーでの AWS SDK for Go v2 の使用
<a name="golang-example-sdk-usage"></a>

多くの場合、Lambda 関数を使用して、他の AWS リソースとやり取りしたり、更新したりします。これらのリソースとインターフェイスする最も簡単な方法は、 [AWS SDK for Go v2](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2) を使用することです。

**注記**  
AWS SDK for Go (v1) はメンテナンスモードであり、2025 年 7 月 31 日にサポートが終了する予定です。今後は AWS SDK for Go v2 のみを使用することをお勧めします。

SDK 依存関係を関数に追加するには、必要な特定の SDK クライアントに `go get` コマンドを使用します。前のサンプルコードでは、`config` ライブラリと `s3` ライブラリを使用しました。これらの依存関係を追加するには、`go.mod` と `main.go ` ファイルが格納されているディレクトリで以下のコマンドを実行します。

```
go get github.com/aws/aws-sdk-go-v2/config
go get github.com/aws/aws-sdk-go-v2/service/s3
```

次に、依存関係を関数の import ブロックにインポートします:

```
import (
    ...
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)
```

ハンドラーで SDK を使用する場合は、適切な設定でクライアントを設定します。これを行う最も簡単な方法は、[デフォルトの認証情報プロバイダーチェーン](https://docs.aws.amazon.com/sdkref/latest/guide/standardized-credentials.html#credentialProviderChain)を使用することです。この例では、この設定をロードする 1 つの方法を示しています:

```
// Load AWS SDK configuration using the default credential provider chain
    cfg, err := config.LoadDefaultConfig(ctx)
    if err != nil {
        log.Printf("Failed to load AWS SDK config: %v", err)
        return err
    }
```

この設定を `cfg` 変数にロードした後、この変数をクライアントインスタンスに渡すことができます。サンプルコードは、以下のように Amazon S3 クライアントをインスタンス化します:

```
// Create an S3 client
    s3Client := s3.NewFromConfig(cfg)
```

この例では、関数を呼び出すたびに初期化する必要がないように、`init()` 関数で Amazon S3 クライアントを初期化しました。問題は、`init()` 関数で Lambda がコンテキストオブジェクトにアクセスできないことです。回避策として、初期化フェーズ中に `context.TODO()` のようなプレースホルダーを渡すことができます。後で、クライアントを使用して呼び出しを行うときは、コンテキストオブジェクト全体を渡します。この回避策については、[AWS SDK クライアントの初期化と呼び出しでのコンテキストの使用](golang-context.md#golang-context-sdk) でも説明されています。

SDK クライアントを設定して初期化したら、SDK クライアントを使用して他の AWS サービスとやり取りできます。サンプルコードは、以下のように Amazon S3 `PutObject` API を呼び出します。

```
_, err = s3Client.PutObject(ctx, &s3.PutObjectInput{
    Bucket: &bucketName,
    Key:    &key,
    Body:   strings.NewReader(receiptContent),
})
```

## 環境変数にアクセスする
<a name="golang-example-envvars"></a>

ハンドラーコードでは、`os.Getenv()` メソッドを使用して任意の[環境変数](configuration-envvars.md)を参照できます。この例では、以下のコード行を使用して、定義された `RECEIPT_BUCKET` 環境変数を参照します:

```
// Access environment variables
    bucketName := os.Getenv("RECEIPT_BUCKET")
    if bucketName == "" {
        log.Printf("RECEIPT_BUCKET environment variable is not set")
        return fmt.Errorf("missing required environment variable RECEIPT_BUCKET")
    }
```

## グローバルな状態を使用する
<a name="golang-handler-state"></a>

関数を呼び出すたびに新しいリソースが作成されないようにするには、Lambda 関数のハンドラーコードの外部でグローバル変数を宣言および変更できます。これらのグローバル変数は、`var` ブロックまたはステートメントで定義します。さらに、ハンドラーは[初期化フェーズ](lambda-runtime-environment.md#runtimes-lifecycle-ib)中に実行される `init()` 関数を宣言することがあります。この `init` メソッドは、AWS Lambda でも標準の Go プログラムと同じように作動します。

## Lambda 関数のコードのベストプラクティス
<a name="go-best-practices"></a>

Lambda 関数をビルドするときは、次のリストのガイドラインに従って、コーディングのベストプラクティスを実行してください。
+ **Lambda ハンドラーをコアロジックから分離します。**これにより、関数の単体テストが実行しやすくなります。
+ **依存関係の複雑さを最小限に抑えます。**フレームワークを単純化して、[実行環境](lambda-runtime-environment.md)起動時のロードを高速化します。
+ **デプロイパッケージをランタイムに必要な最小限のサイズにします。**これにより、呼び出しに先立ってデプロイパッケージをダウンロードして解凍する所要時間が短縮されます。

**実行環境の再利用を活用して関数のパフォーマンスを向上させます。**関数ハンドラー外で SDK クライアントとデータベース接続を初期化し、静的なアセットを `/tmp` ディレクトリにローカルにキャッシュします。関数の同じインスタンスで処理された後続の呼び出しは、これらのリソースを再利用できます。これにより、関数の実行時間が短縮され、コストが節約されます。

呼び出し間でデータが漏れるのを防ぐため、実行環境を使用してセキュリティ上の懸念があるユーザーデータ、イベント、またはその他の情報を保存しないでください。関数がハンドラー内のメモリに保存できない変更可能な状態に依存している場合は、ユーザーごとに個別の関数または個別のバージョンの関数を作成することを検討してください。

**keep-alive ディレクティブを使用して永続的な接続を維持します。**Lambda は、時間の経過とともにアイドル状態の接続を消去します。関数を呼び出すときにアイドル状態の接続を再利用しようとすると、接続エラーが発生します。永続的な接続を維持するには、ランタイムに関連付けられている keep-alive ディレクティブを使用します。例については、「[Node.js で Keep-alive を使用して接続を再利用する](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/node-reusing-connections.html)」を参照してください。

**[環境変数](configuration-envvars.md)を使用して、オペレーショナルパラメータを関数に渡します。**たとえば、Amazon S3 バケットに書き込む場合、書き込み先のバケット名はハードコーディングせずに、環境変数として設定します。

Lambda 関数では、**再帰呼び出しを使用しないでください**。関数が自身を呼び出すこともあれば、新たに開始されたプロセスで関数が再度呼び出される可能性もあります。これを行うと意図しないボリュームで関数が呼び出され、料金が急増する可能性があります。意図しない呼び出しがいくつも見つかった場合は、すぐに関数の予約済同時実行数を `0` に設定して、コードを更新している間のすべての関数の呼び出しをスロットリングします。

Lambda 関数コードで**文書化されていない非公開の API を使用しないでください**。AWS Lambda マネージドランタイムでは、Lambda が Lambda の内部 API にセキュリティと機能面の更新を定期的に適用します。これらの内部 API 更新には後方互換性がないことがあり、関数にこれらの非公開 API に対する依存関係がある場合、呼び出しの失敗などの意図しない結果につながります。公開されている API のリストについては、「[API リファレンス](https://docs.aws.amazon.com/lambda/latest/api/welcome.html)」を参照してください。

**冪等性コードを記述します。**関数の記述に冪等性コードを使用すると、重複するイベントが同じ方法で処理されるようになります。コードでは、イベントを適切に検証し、重複するイベントを適切に処理する必要があります。詳細については、「[Lambda 関数を冪等にするにはどうすればよいですか?](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-idempotent/)」を参照してください。

# Lambda コンテキストオブジェクトを使用して Go 関数の情報を取得する
<a name="golang-context"></a>

Lambda では、コンテキストオブジェクトは呼び出し、関数、および実行環境に関する情報を持つメソッドおよびプロパティを提供します。Lambda で関数が実行されると、コンテキストオブジェクトが[ハンドラー](golang-handler.md)に渡されます。ハンドラーでコンテキストオブジェクトを使用するには、オプションでハンドラーへの入力パラメータとして宣言できます。コンテキストオブジェクトは、ハンドラーで以下を実行する場合に必要です:
+ コンテキストオブジェクトが提供する[グローバル変数、メソッド、またはプロパティ](#golang-context-library)のいずれかにアクセスする必要があります。これらのメソッドとプロパティは、[context の呼び出し情報へのアクセス](#golang-context-access) に示すように、関数を呼び出すエンティティの決定や関数の呼び出し時間の測定などのタスクに役立ちます。
+ AWS SDK for Go を使用して、他のサービスに呼び出しを行う必要があります。コンテキストオブジェクトは、これらのほとんどの呼び出しにとって重要な入力パラメータです。詳細については、「[AWS SDK クライアントの初期化と呼び出しでのコンテキストの使用](#golang-context-sdk)」を参照してください。

**Topics**
+ [コンテキストオブジェクトでサポートされている変数、メソッド、プロパティ](#golang-context-library)
+ [context の呼び出し情報へのアクセス](#golang-context-access)
+ [AWS SDK クライアントの初期化と呼び出しでのコンテキストの使用](#golang-context-sdk)

## コンテキストオブジェクトでサポートされている変数、メソッド、プロパティ
<a name="golang-context-library"></a>

Lambda コンテキストライブラリは、次のグローバル変数、メソッド、およびプロパティを提供します。

**グローバル変数**
+ `FunctionName` － Lambda 関数の名前。
+ `FunctionVersion` － 関数の[バージョン](configuration-versions.md)。
+ `MemoryLimitInMB` － 関数に割り当てられたメモリの量。
+ `LogGroupName` － 関数のロググループ。
+ `LogStreamName` — 関数インスタンスのログストリーム。

**context メソッド**
+ `Deadline` — 実行がタイムアウトした日付 (Unix 時間のミリ秒単位) を返します。

**context プロパティ**
+ `InvokedFunctionArn` － 関数を呼び出すために使用される Amazon リソースネーム (ARN)。呼び出し元でバージョン番号またはエイリアスが指定されているかどうかを示します。
+ `AwsRequestID` － 呼び出しリクエストの ID。
+ `Identity` — (モバイルアプリケーション) リクエストを認可した Amazon Cognito ID に関する情報。
+ `ClientContext` — (モバイルアプリケーション) クライアントアプリケーションが Lambda に提供したクライアントコンテキスト。

## context の呼び出し情報へのアクセス
<a name="golang-context-access"></a>

Lambda 関数は、環境と呼び出しリクエストに関するメタデータにアクセスできます。これには、[パッケージのコンテキスト](https://golang.org/pkg/context/)でアクセスできます。ハンドラーにはパラメータとして `context.Context` が含まれている必要があり、Lambda は関数に関する情報をコンテキストの `Value` プロパティに挿入します。`lambdacontext`のコンテキストにアクセスするために、`context.Context` ライブラリをインポートする必要があることに注意してください。

```
package main
 
import (
        "context"
        "log"
        "github.com/aws/aws-lambda-go/lambda"
        "github.com/aws/aws-lambda-go/lambdacontext"
)
 
func CognitoHandler(ctx context.Context) {
        lc, _ := lambdacontext.FromContext(ctx)
        log.Print(lc.Identity.CognitoIdentityPoolID)
}
 
func main() {
        lambda.Start(CognitoHandler)
}
```

上記の例では、`lc` はコンテキストオブジェクトがキャプチャした情報を消費するために使用される変数であり、`log.Print(lc.Identity.CognitoIdentityPoolID)` はその情報を印刷します (この場合は CognitoIdentityPoolID)。

以下の例では、コンテキストオブジェクトを使用して、Lambda 関数の完了にかかる時間をモニタリングする方法を紹介しています。これによって、予期されるパフォーマンスを分析し、必要な場合には関数コードを調整します。

```
package main

import (
        "context"
        "log"
        "time"
        "github.com/aws/aws-lambda-go/lambda"
)

func LongRunningHandler(ctx context.Context) (string, error) {

        deadline, _ := ctx.Deadline()
        deadline = deadline.Add(-100 * time.Millisecond)
        timeoutChannel := time.After(time.Until(deadline))

        for {

                select {

                case <- timeoutChannel:
                        return "Finished before timing out.", nil

                default:
                        log.Print("hello!")
                        time.Sleep(50 * time.Millisecond)
                }
        }
}

func main() {
        lambda.Start(LongRunningHandler)
}
```

## AWS SDK クライアントの初期化と呼び出しでのコンテキストの使用
<a name="golang-context-sdk"></a>

ハンドラーが AWS SDK for Go を使用して他のサービスに呼び出しする必要がある場合は、ハンドラーへの入力としてコンテキストオブジェクトを含めます。AWS では、ほとんどの AWS SDK 呼び出しでコンテキストオブジェクトを渡すことがベストプラクティスです。例えば、Amazon S3 `PutObject` 呼び出しは、コンテキストオブジェクト (`ctx`) を最初の引数として受け入れます:

```
// Upload an object to S3
    _, err = s3Client.PutObject(ctx, &s3.PutObjectInput{
        ...
    })
```

SDK クライアントを適切に初期化するには、コンテキストオブジェクトを使用して正しい設定をロードしてから、その設定オブジェクトをクライアントに渡すこともできます:

```
// Load AWS SDK configuration using the default credential provider chain
    cfg, err := config.LoadDefaultConfig(ctx)
    ...
    s3Client = s3.NewFromConfig(cfg)
```

SDK クライアントをメインハンドラーの外部 (すなわち初期化フェーズ中) で初期化する場合は、プレースホルダーコンテキストオブジェクトを渡すことができます:

```
func init() {
	// Initialize the S3 client outside of the handler, during the init phase
	cfg, err := config.LoadDefaultConfig(context.TODO())
	...
	s3Client = s3.NewFromConfig(cfg)
}
```

この方法でクライアントを初期化する場合は、メインハンドラーからの SDK 呼び出しで正しいコンテキストオブジェクトを渡してください。

# .zip ファイルアーカイブを使用して Go Lambda 関数をデプロイする
<a name="golang-package"></a>

AWS Lambda 関数のコードは、スクリプトまたはコンパイルされたプログラム、さらにそれらの依存関係で構成されます。*デプロイパッケージ*を使用して、Lambda に関数コードをデプロイします。Lambda は、コンテナイメージと .zip ファイルアーカイブの 2 種類のデプロイパッケージをサポートします。

このページでは、Go ランタイムのデプロイパッケージとして .zip ファイルを作成し、AWS マネジメントコンソール、AWS Command Line Interface (AWS CLI)および AWS Serverless Application Model (AWS SAM) を使用して関数コードを AWS Lambda にデプロイするために .zip ファイルを使用する方法について説明します。

Lambda は POSIX ファイルアクセス許可を使用するため、.zip ファイルアーカイブを作成する前に、[デプロイパッケージフォルダのアクセス許可を設定する](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-deployment-package-errors/)必要がある場合があります。

**Topics**
+ [macOS および Linux での .zip ファイルの作成](#golang-package-mac-linux)
+ [Windows での .zip ファイルの作成](#golang-package-windows)
+ [.zip ファイルを使用した Go Lambda 関数の作成と更新](#golang-package-create-function)

## macOS および Linux での .zip ファイルの作成
<a name="golang-package-mac-linux"></a>

以下の手順は、`go build` コマンドを使用して実行ファイルをコンパイルし、Lambda 用の .zip ファイルデプロイパッケージを作成する方法を示しています。コードをコンパイルする前に、GitHub から [Lambda](https://github.com/aws/aws-lambda-go/tree/master/lambda) パッケージをインストールしていることを確認してください。このモジュールは、ランタイムインターフェイスの実装を提供し、ランタイムインターフェイスは Lambda と関数コード間の相互作用を管理します。このライブラリをダウンロードするには、次のコマンドを実行します。

```
go get github.com/aws/aws-lambda-go/lambda
```

関数で AWS SDK for Go を使用している場合は、標準の SDK モジュールセットと、アプリケーションに必要な AWS サービス API クライアントをダウンロードしてください。SDK for Go のインストール方法については、「[AWS SDK for Go V2 の使用開始](https://github.com/aws/aws-sdk-go-v2?tab=readme-ov-file#getting-started)」を参照してください。

### 指定されたランタイムファミリーの使用
<a name="golang-package-mac-linux-al2"></a>

Go は、他のマネージドランタイムとは異なる方法で実装されています。Go は実行可能バイナリにネイティブにコンパイルするため、専用の言語ランタイムは必要ありません。Go 関数を Lambda にデプロイするには、[OS 専用ランタイム](runtimes-provided.md) (`provided` ランタイム ファミリ) を使用します。

**.zip デプロイパッケージを作成するには (macOS/Linux)**

1. アプリケーションの `main.go` ファイルが含まれているプロジェクトディレクトリで、実行ファイルをコンパイルします。次の点に注意してください。
   + 実行ファイルには `bootstrap` という名前をつける必要があります。詳細については、「[ハンドラーの命名規則](golang-handler.md#golang-handler-naming)」を参照してください。
   + ターゲットの[命令セットアーキテクチャ](foundation-arch.md)を設定します。OS のみのランタイムは、arm64 と x86\$164 の両方をサポートします。
   + オプションの `lambda.norpc` タグを使用して、[Lambda](https://github.com/aws/aws-lambda-go/tree/master/lambda) ライブラリの Remote Procedure Call (RPC) コンポーネントを除外することができます。RPC コンポーネントは、Go 1.x ランタイムを使用している場合にのみ必要です。RPC を除外すると、デプロイパッケージのサイズが小さくなります。

   arm64 アーキテクチャの場合:

   ```
   GOOS=linux GOARCH=arm64 go build -tags lambda.norpc -o bootstrap main.go
   ```

   x86\$164 アーキテクチャの場合:

   ```
   GOOS=linux GOARCH=amd64 go build -tags lambda.norpc -o bootstrap main.go
   ```

1. (オプション) Linux では、`CGO_ENABLED=0` set を使用してパッケージをコンパイルする必要がある場合があります。

   ```
   GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -o bootstrap -tags lambda.norpc main.go
   ```

   このコマンドは、標準の C ライブラリ (`libc`) バージョン用の安定したバイナリパッケージを作成します。このパッケージは、Lambda と他のデバイスでは異なる場合があります。

1. 実行可能ファイルを .zip ファイルにパッケージ化して、デプロイパッケージを作成します。

   ```
   zip myFunction.zip bootstrap
   ```
**注記**  
`bootstrap` ファイルは、.zip ファイルのルートに置く必要があります。

1. 関数を作成します。次の点に注意してください。
   + バイナリ名は `bootstrap` にする必要がありますが、ハンドラー名は何でもかまいません。詳細については、「[ハンドラーの命名規則](golang-handler.md#golang-handler-naming)」を参照してください。
   + `--architectures` オプションは、arm64 を使用している場合にのみ必須です。デフォルト値は x86\$164 です。
   + `--role` には、[実行ロール](lambda-intro-execution-role.md)の Amazon リソースネーム (ARN) を指定します。

   ```
   aws lambda create-function --function-name myFunction \
   --runtime provided.al2023 --handler bootstrap \
   --architectures arm64 \
   --role arn:aws:iam::111122223333:role/lambda-ex \
   --zip-file fileb://myFunction.zip
   ```

## Windows での .zip ファイルの作成
<a name="golang-package-windows"></a>

次の手順は、GitHub から Windows 用の [build-lambda-zip](https://github.com/aws/aws-lambda-go/tree/main/cmd/build-lambda-zip) ツールをダウンロードし、実行可能ファイルをコンパイルして、.zip のデプロイパッケージを作成する方法を示しています。

**注記**  
上記を実行していない場合には、[git](https://git-scm.com/) をインストールした上で、お使いの Windows の `git` 環境変数に `%PATH%` の実行可能ファイルを追加します。

コードをコンパイルする前に、GitHub から [Lambda](https://github.com/aws/aws-lambda-go/tree/master/lambda) ライブラリをインストールしていることを確認してください。このライブラリをダウンロードするには、次のコマンドを実行します。

```
go get github.com/aws/aws-lambda-go/lambda
```

関数で AWS SDK for Go を使用している場合は、標準の SDK モジュールセットと、アプリケーションに必要な AWS サービス API クライアントをダウンロードしてください。SDK for Go のインストール方法については、「[AWS SDK for Go V2 の使用開始](https://aws.github.io/aws-sdk-go-v2/docs/getting-started/)」を参照してください。

### 指定されたランタイムファミリーの使用
<a name="golang-package-windows-al2"></a>

Go は、他のマネージドランタイムとは異なる方法で実装されています。Go は実行可能バイナリにネイティブにコンパイルするため、専用の言語ランタイムは必要ありません。Go 関数を Lambda にデプロイするには、[OS 専用ランタイム](runtimes-provided.md) (`provided` ランタイム ファミリ) を使用します。

**.zip デプロイパッケージを作成するには (Windows)**

1. GitHub から **build-lambda-zip** ツールをダウンロードします。

   ```
   go install github.com/aws/aws-lambda-go/cmd/build-lambda-zip@latest
   ```

1. `GOPATH` のツールを使用して、.zip ファイルを作成します。Go のデフォルトのインストールがある場合、このツールは通常 `%USERPROFILE%\Go\bin` に置かれています。それ以外の場合は、Go ランタイムをインストールした場所に移動し、次のいずれかの操作を行います。

------
#### [ cmd.exe ]

   cmd.exe で、ターゲットの[命令セットアーキテクチャ](foundation-arch.md)に応じて、次のいずれかを実行します。OS のみのランタイムは、arm64 と x86\$164 の両方をサポートします。

   オプションの `lambda.norpc` タグを使用して、[Lambda](https://github.com/aws/aws-lambda-go/tree/master/lambda) ライブラリの Remote Procedure Call (RPC) コンポーネントを除外することができます。RPC コンポーネントは、Go 1.x ランタイムを使用している場合にのみ必要です。RPC を除外すると、デプロイパッケージのサイズが小さくなります。

**Example — x86\$164 アーキテクチャの場合**  

   ```
   set GOOS=linux
   set GOARCH=amd64
   set CGO_ENABLED=0
   go build -tags lambda.norpc -o bootstrap main.go
   %USERPROFILE%\Go\bin\build-lambda-zip.exe -o myFunction.zip bootstrap
   ```

**Example — arm64 アーキテクチャの場合**  

   ```
   set GOOS=linux
   set GOARCH=arm64
   set CGO_ENABLED=0
   go build -tags lambda.norpc -o bootstrap main.go
   %USERPROFILE%\Go\bin\build-lambda-zip.exe -o myFunction.zip bootstrap
   ```

------
#### [ PowerShell ]

   PowerShell で、ターゲットの[命令セットアーキテクチャ](foundation-arch.md)に応じて、次のいずれかを実行します。OS のみのランタイムは、arm64 と x86\$164 の両方をサポートします。

   オプションの `lambda.norpc` タグを使用して、[Lambda](https://github.com/aws/aws-lambda-go/tree/master/lambda) ライブラリの Remote Procedure Call (RPC) コンポーネントを除外することができます。RPC コンポーネントは、Go 1.x ランタイムを使用している場合にのみ必要です。RPC を除外すると、デプロイパッケージのサイズが小さくなります。

   x86\$164 アーキテクチャの場合:

   ```
   $env:GOOS = "linux"
   $env:GOARCH = "amd64"
   $env:CGO_ENABLED = "0"
   go build -tags lambda.norpc -o bootstrap main.go
   ~\Go\Bin\build-lambda-zip.exe -o myFunction.zip bootstrap
   ```

   arm64 アーキテクチャの場合:

   ```
   $env:GOOS = "linux"
   $env:GOARCH = "arm64"
   $env:CGO_ENABLED = "0"
   go build -tags lambda.norpc -o bootstrap main.go
   ~\Go\Bin\build-lambda-zip.exe -o myFunction.zip bootstrap
   ```

------

1. 関数を作成します。次の点に注意してください。
   + バイナリ名は `bootstrap` にする必要がありますが、ハンドラー名は何でもかまいません。詳細については、「[ハンドラーの命名規則](golang-handler.md#golang-handler-naming)」を参照してください。
   + `--architectures` オプションは、arm64 を使用している場合にのみ必須です。デフォルト値は x86\$164 です。
   + `--role` には、[実行ロール](lambda-intro-execution-role.md)の Amazon リソースネーム (ARN) を指定します。

   ```
   aws lambda create-function --function-name myFunction \
   --runtime provided.al2023 --handler bootstrap \
   --architectures arm64 \
   --role arn:aws:iam::111122223333:role/lambda-ex \
   --zip-file fileb://myFunction.zip
   ```

## .zip ファイルを使用した Go Lambda 関数の作成と更新
<a name="golang-package-create-function"></a>

 .zip デプロイパッケージを作成したら、このパッケージを使用して新しい Lambda 関数を作成するか、既存の関数を更新できます。.zip パッケージをデプロイするには、Lambda コンソール、AWS Command Line Interface、Lambda API を使用します。AWS Serverless Application Model (AWS SAM) および CloudFormation を使用して、Lambda 関数を作成および更新することもできます。

Lambda の .zip デプロイパッケージの最大サイズは  250 MB (解凍) です。この制限は、Lambda レイヤーを含む、更新するすべてのファイルの合計サイズに適用されることに注意してください。

Lambda ランタイムには、デプロイパッケージ内のファイルを読み取るアクセス許可が必要です。Linux のアクセス権限の 8 進表記では、Lambda には非実行ファイル用に 644 のアクセス権限 (rw-r--r--) が必要であり、ディレクトリと実行可能ファイル用に 755 のアクセス権限 (rwxr-xr-x) が必要です。

Linux と MacOS で、デプロイパッケージ内のファイルやディレクトリのファイルアクセス権限を変更するには、`chmod` コマンドを使用します。例えば、実行可能でないファイルに正しいアクセス許可を付与するには、次のコマンドを実行します。

```
chmod 644 <filepath>
```

Windows でファイルアクセス許可を変更するには、「Microsoft Windows ドキュメント」の「[Set, View, Change, or Remove Permissions on an Object](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc731667(v=ws.10))」を参照してください。

**注記**  
デプロイパッケージのディレクトリにアクセスするために必要なアクセス許可を Lambda に付与しない場合、Lambda はそれらのディレクトリのアクセス許可を 755 (rwxr-xr-x) に設定します。

### コンソールを使用して .zip ファイルの関数を作成、更新する
<a name="golang-package-create-console"></a>

 新しい関数を作成するには、まずコンソールで関数を作成し、次に .zip アーカイブをアップロードする必要があります。既存の関数を更新するには、その関数のページを開き、同じ手順に従って更新した .zip ファイルを追加します。

 .zip ファイルが 50 MB 未満の場合は、ローカルマシンから直接ファイルをアップロードして関数を作成または更新できます。50 MB を超える .zip ファイルの場合は、まず  Amazon S3 バケットにパッケージをアップロードする必要があります。AWS マネジメントコンソール を使用して Amazon S3 バケットにファイルをアップロードする手順については、「[Amazon S3 の開始方法](https://docs.aws.amazon.com/AmazonS3/latest/userguide/GetStartedWithS3.html)」を参照してください。AWS CLI を使用してファイルをアップロードするには、「AWS CLI ユーザーガイド」の「[オブジェクトの移動](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)」を参照してください。

**注記**  
既存のコンテナイメージ関数を変換して .zip アーカイブを使用することはできません。この場合は、新しい関数を作成する必要があります。

**新しい関数を作成するには (コンソール)**

1. Lambda コンソールの [[関数]](https://console.aws.amazon.com/lambda/home#/functions) ページを開き、**[関数の作成]** を選択します。

1. **[一から作成]** を選択します。

1. **[基本的な情報]** で、以下を行います。

   1. **[関数名]** に、関数名を入力します。

   1. [**Runtime (ランタイム)**] で、`provided.al2023` を選択します。

1. (オプション) **[アクセス権限]** で、**[デフォルトの実行ロールの変更]** を展開します。新しい **[実行ロール]** を作成することも、既存のロールを使用することもできます。

1. **[関数の作成]**を選択します。Lambda は、選択したランタイムを使用して基本的な「Hello world」関数を作成します。

**ローカルマシンから  zip アーカイブをアップロードするには (コンソール)**

1. Lambda コンソールの [[関数ページ]](https://console.aws.amazon.com/lambda/home#/functions) で、.zip ファイルをアップロードする関数を選択します。

1. **[コード]** タブを選択します。

1. **[コードソース]** ペインで、**[アップロード元]** をクリックします。

1. **[.zip ファイル]** をクリックします。

1. .zip ファイルをアップロードするには、次の操作を行います。

   1. **[アップロード]** をクリックし、ファイルセレクターで .zip ファイルを選択します。

   1. **[開く]** をクリックします。

   1. **[保存]** をクリックします。

**Amazon S3 バケットから .zip アーカイブをアップロードするには (コンソール)**

1. Lambda コンソールの [[関数ページ]](https://console.aws.amazon.com/lambda/home#/functions) で、新しい .zip ファイルをアップロードする関数を選択します。

1. **[コード]** タブを選択します。

1. **[コードソース]** ペインで、**[アップロード元]** をクリックします。

1. **[Amazon S3 ロケーション]** を選択します。

1. .zip ファイルの Amazon S3 リンク URL を貼り付けて、**[保存]** をクリックします。

### AWS CLI を使用して .zip ファイルで関数を作成、更新する
<a name="golang-package-create-cli"></a>

 [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) を使用して新しい関数を作成したり、.zip ファイルを使用して既存の関数を更新したりできます。[create-function](https://docs.aws.amazon.com/cli/latest/reference/lambda/create-function.html) コマンドと [update-function-code](https://docs.aws.amazon.com/cli/latest/reference/lambda/create-function.html) を使用して、.zip パッケージをデプロイします。.zip ファイルが 50 MB 未満の場合は、ローカルビルドマシン上のファイルの場所から .zip パッケージをアップロードできます。サイズの大きいファイルの場合は、Amazon S3 バケットから .zip パッケージをアップロードする必要があります。AWS CLI を使用して Amazon S3 バケットにファイルをアップロードする方法については、「*AWS CLI ユーザーガイド*」の「[オブジェクトの移動](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)」を参照してください。

**注記**  
AWS CLI を使用して Amazon S3 バケットから .zip ファイルをアップロードする場合、このバケットは関数と同じ AWS リージョン に配置する必要があります。

 AWS CLI を含む .zip ファイルを使用して新しい関数を作成するには、以下を指定する必要があります。
+ 関数の名前 (`--function-name`)
+ 関数のランタイム (`--runtime`)
+ 関数の[実行ロール](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html) (`--role`) の Amazon リソースネーム (ARN)
+ 関数コード内のハンドラーメソッド (`--handler`) の名前

 .zip ファイルの場所も指定する必要があります。.zip ファイルがローカルビルドマシン上のフォルダにある場合は、次のコマンド例に示すように、`--zip-file` オプションを使用してファイルパスを指定します。

```
aws lambda create-function --function-name myFunction \
--runtime provided.al2023 --handler bootstrap \
--role arn:aws:iam::111122223333:role/service-role/my-lambda-role \
--zip-file fileb://myFunction.zip
```

 Amazon S3 バケット内の .zip ファイルの場所を指定するには、以下のコマンド例にある `--code` オプションを使用します。`S3ObjectVersion` パラメータは、バージョン管理下のオブジェクトにのみ使用する必要があります。

```
aws lambda create-function --function-name myFunction \
--runtime provided.al2023 --handler bootstrap \
--role arn:aws:iam::111122223333:role/service-role/my-lambda-role \
--code S3Bucket=amzn-s3-demo-bucket,S3Key=myFileName.zip,S3ObjectVersion=myObjectVersion
```

 CLI を使用して既存の関数を更新するには、`--function-name` パラメータを使用して関数の名前を指定します。関数コードの更新に使用する .zip ファイルの場所も指定する必要があります。.zip ファイルがローカルビルドマシン上のフォルダにある場合は、次のコマンド例に示すように、`--zip-file` オプションを使用してファイルパスを指定します。

```
aws lambda update-function-code --function-name myFunction \
--zip-file fileb://myFunction.zip
```

 Amazon S3 バケット内の .zip ファイルの場所を指定するには、以下のコマンド例にある `--s3-bucket` および `--s3-key` オプションを使用します。`--s3-object-version` パラメータは、バージョン管理下のオブジェクトにのみ使用する必要があります。

```
aws lambda update-function-code --function-name myFunction \
--s3-bucket amzn-s3-demo-bucket --s3-key myFileName.zip --s3-object-version myObject Version
```

### Lambda API を使用して .zip ファイルで関数を作成、更新する
<a name="golang-package-create-api"></a>

 .zip ファイルアーカイブを使用して関数を作成および更新するには、以下の API オペレーションを使用します。
+ [CreateFunction](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html)
+ [UpdateFunctionCode](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionCode.html)

### AWS SAM を使用して .zip ファイルで関数を作成、更新する
<a name="golang-package-create-sam"></a>

 AWS Serverless Application Model (AWS SAM) は、AWS のサーバーレスアプリケーションの構築と実行のプロセスを合理化するのに役立つツールキットです。YAML または JSON テンプレートでアプリケーションのリソースを定義し、AWS SAM コマンドラインインターフェイス (AWS SAM CLI) を使用して、アプリケーションを構築、パッケージ化、デプロイします。AWS SAM テンプレートから Lambda 関数を構築すると、AWS SAM は関数コードと指定した任意の依存関係を含む .zip デプロイパッケージまたはコンテナイメージを自動的に作成します。AWS SAM を使用して Lambda 関数を構築およびデプロイする方法の詳細については、「*AWS Serverless Application Model デベロッパーガイド*」の「[Getting started with AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-getting-started.html)」を参照してください。

AWS SAM を使用して、既存の .zip ファイルアーカイブを使用する Lambda 関数を作成できます。AWS SAM を使用して Lambda 関数を作成するには、.zip  ファイルを Amazon S3 バケットまたはビルドマシンのローカルフォルダに保存します。AWS CLI を使用して Amazon S3 バケットにファイルをアップロードする方法については、「*AWS CLI ユーザーガイド*」の「[オブジェクトの移動](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)」を参照してください。

 AWS SAM テンプレートでは、Lambda 関数は `AWS::Serverless::Function` のリソースにより指定されます。このリソースで次のプロパティを設定し、.zip ファイルアーカイブを使用して関数を作成します。
+ `PackageType` - `Zip` に設定
+ `CodeUri` - 関数コードの Amazon S3 URI、ローカルフォルダへのパス、または [FunctionCode](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-function-functioncode.html) オブジェクトに設定
+ `Runtime` - 選択したランタイムに設定

 AWS SAM では、.zip ファイルが 50 MB を超える場合、この .zip ファイルを最初に Amazon S3 バケットにアップロードする必要はありません。AWS SAM では、ローカルビルドマシン上の場所から、最大許容サイズ 250 MB (解凍) の .zip パッケージをアップロードできます。

 AWS SAM で .zip ファイルを使用して関数をデプロイする方法の詳細については、「*AWS SAM デベロッパーガイド*」の「[AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)」を参照してください。

**例: provided.al2023 を使って Go 関数を構築するために AWS SAM を使用**

1. 次のプロパティで AWS SAM テンプレートを作成します。
   + **[BuildMethod]**: アプリケーションのコンパイラを指定します。`go1.x` を使用します。
   + **[ランタイム]**: `provided.al2023` を使用します。
   + **[CodeUri]**: コードへのパスを入力します。
   + **[アーキテクチャ]**: arm64 アーキテクチャ用の `[arm64]` を使用します。x86\$164 命令セットアーキテクチャ用の場合、`[amd64]` を使用するか、または `Architectures` プロパティを削除します。  
**Example template.yaml**  

   ```
   AWSTemplateFormatVersion: '2010-09-09'
   Transform: 'AWS::Serverless-2016-10-31'
   Resources:
     HelloWorldFunction:
       Type: AWS::Serverless::Function
       Metadata:
         BuildMethod: go1.x
       Properties:
         CodeUri: hello-world/ # folder where your main program resides
         Handler: bootstrap
         Runtime: provided.al2023
         Architectures: [arm64]
   ```

1. [sam build](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-build.html) コマンドを使用して、実行ファイルをコンパイルします。

   ```
   sam build
   ```

1. [sam deploy](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-deploy.html) コマンドを使用して、関数を Lambda にデプロイします。

   ```
   sam deploy --guided
   ```

### CloudFormation を使用して .zip ファイルで関数を作成、更新する
<a name="golang-package-create-cfn"></a>

 CloudFormation を使用して、.zip ファイルアーカイブを使用する Lambda 関数を作成できます。.zip ファイルから Lambda 関数を作成するには、最初にファイルを Amazon S3 バケットにアップロードする必要があります。AWS CLI を使用して Amazon S3 バケットにファイルをアップロードする方法については、「*AWS CLI ユーザーガイド*」の「[オブジェクトの移動](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)」を参照してください。

CloudFormation テンプレートでは、Lambda 関数は `AWS::Lambda::Function` のリソースにより指定されます。このリソースで次のプロパティを設定し、.zip ファイルアーカイブを使用して関数を作成します。
+ `PackageType` - `Zip` に設定
+ `Code` - `S3Bucket` および `S3Key` フィールドに Amazon S3 バケット名と .zip ファイル名を入力
+ `Runtime` - 選択したランタイムに設定

 CloudFormation が生成する .zip ファイルは、4 MB を超えることはできません。CloudFormation で .zip ファイルを使用して関数をデプロイする方法の詳細については、「*CloudFormation ユーザーガイド*」の「[AWS::Lambda::Function](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html)」を参照してください。

# コンテナイメージを使用して Go Lambda 関数をデプロイする
<a name="go-image"></a>

Go Lambda 関数のコンテナイメージを構築するには 2 つの方法があります。
+ [AWS の OS 専用ベースイメージを使用する](#go-image-provided)

  Go は、他のマネージドランタイムとは異なる方法で実装されています。Go は実行可能バイナリにネイティブにコンパイルするため、専用の言語ランタイムは必要ありません。[OS 専用のベースイメージ](images-create.md#runtimes-images-provided)を使用して、Lambda 用の Go イメージを構築します。イメージに Lambda との互換性を持たせるには、イメージに `aws-lambda-go/lambda` パッケージを含める必要があります。
+ [非 AWS ベースイメージを使用する](#go-image-other)

  Alpine Linux や Debian など、別のコンテナレジストリの代替ベースイメージを使用することもできます。組織が作成したカスタムイメージを使用することもできます。イメージに Lambda との互換性を持たせるには、イメージに `aws-lambda-go/lambda` パッケージを含める必要があります。

**ヒント**  
Lambda コンテナ関数がアクティブになるまでの時間を短縮するには、「Docker ドキュメント」の「[マルチステージビルドを使用する](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#use-multi-stage-builds)」を参照してください。効率的なコンテナイメージを構築するには、「[Dockerfiles を記述するためのベストプラクティス](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/)」に従ってください。

このページでは、Lambda のコンテナイメージを構築、テスト、デプロイする方法について説明します。

## Go 関数をデプロイするための AWS ベースイメージ
<a name="go-image-base"></a>

Go は、他のマネージドランタイムとは異なる方法で実装されています。Go は実行可能バイナリにネイティブにコンパイルするため、専用の言語ランタイムは必要ありません。[OS 専用のベースイメージ](images-create.md#runtimes-images-provided)を使用して、Go 関数を Lambda にデプロイします。


| 名前 | 識別子 | オペレーティングシステム | 廃止日 | 関数の作成をブロックする | 関数の更新をブロックする | 
| --- | --- | --- | --- | --- | --- | 
|  OS 専用ランタイム  |  `provided.al2023`  |  Amazon Linux 2023  |   2029 年 6 月 30 日   |   2029 年 7 月 31 日   |   2029 年 8 月 31 日   | 
|  OS 専用ランタイム  |  `provided.al2`  |  Amazon Linux 2  |   2026 年 7 月 31 日   |   2026 年 8 月 31 日   |   Sep 30, 2026   | 

Amazon Elastic コンテナレジストリ公開ギャラリー: [gallery.ecr.aws/lambda/provided](https://gallery.ecr.aws/lambda/provided)

## Go 用ランタイムインターフェイスクライアント
<a name="go-image-clients"></a>

`aws-lambda-go/lambda` パッケージには、ランタイムインターフェイスの実装が含まれています。イメージで `aws-lambda-go/lambda` を使用する方法の例については、[AWS の OS 専用ベースイメージを使用する](#go-image-provided) または [非 AWS ベースイメージを使用する](#go-image-other) を参照してください。

## AWS の OS 専用ベースイメージを使用する
<a name="go-image-provided"></a>

Go は、他のマネージドランタイムとは異なる方法で実装されています。Go は実行可能バイナリにネイティブにコンパイルするため、専用の言語ランタイムは必要ありません。[OS 専用のベースイメージ](images-create.md#runtimes-images-provided)を使用して、Go 関数のコンテナイメージを構築します。


| タグ | ランタイム | オペレーティングシステム | Dockerfile | 非推奨 | 
| --- | --- | --- | --- | --- | 
| al2023 | OS 専用ランタイム | Amazon Linux 2023 | [GitHub の OS 専用ランタイムの Dockerfile](https://github.com/aws/aws-lambda-base-images/blob/provided.al2023/Dockerfile.provided.al2023) |   2029 年 6 月 30 日   | 
| al2 | OS 専用ランタイム | Amazon Linux 2 | [GitHub の OS 専用ランタイムの Dockerfile](https://github.com/aws/aws-lambda-base-images/blob/provided.al2/Dockerfile.provided.al2) |   2026 年 7 月 31 日   | 

これらのベースイメージの詳細については、Amazon ECR Public Gallery の「[provided](https://gallery.ecr.aws/lambda/provided)」を参照してください。

[aws-lambda-go/lambda](https://github.com/aws/aws-lambda-go) パッケージを Go ハンドラに含める必要があります。このパッケージにより、ランタイムインターフェイスを含む、Go のプログラミングモデルが実装されます。

### 前提条件
<a name="go-custom-prerequisites"></a>

このセクションの手順を完了するには、以下が必要です。
+ [AWS CLI バージョン 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [Docker](https://docs.docker.com/get-docker) (最小バージョン 25.0.0)
+ Docker [buildx プラグイン](https://github.com/docker/buildx/blob/master/README.md)。
+ Go

### provided.al2023 ベースイメージからイメージを作成する
<a name="go-custom-create"></a>

**`provided.al2023` ベースイメージを使用して Go 関数をビルドしデプロイするには**

1. プロジェクト用のディレクトリを作成し、そのディレクトリに切り替えます。

   ```
   mkdir hello
   cd hello
   ```

1. 新しい Go モジュールを初期化します。

   ```
   go mod init example.com/hello-world
   ```

1. **Lambda** ライブラリを新しいモジュールの依存関係として追加します。

   ```
   go get github.com/aws/aws-lambda-go/lambda
   ```

1. 「`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)
   }
   ```

1. テキストエディタを使用して、プロジェクトディレクトリに Dockerfile を作成します。
   + 次の Dockerfile の例では、「[マルチステージビルド](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#use-multi-stage-builds)」が使用されます。これにより、各ステップで異なるベースイメージを使用できます。「[Go ベースイメージ](https://hub.docker.com/_/golang)」など、1 つのイメージを使用し、コードをコンパイルして実行可能なバイナリを構築できます。その後、最後の `FROM` ステートメントで `provided.al2023` など別のイメージを使用し、Lambda にデプロイするイメージを定義できます。ビルドプロセスは最終デプロイイメージとは分離されているため、最終イメージにはアプリケーションの実行に必要なファイルのみが含まれます。
   + オプションの `lambda.norpc` タグを使用して、[Lambda](https://github.com/aws/aws-lambda-go/tree/master/lambda) ライブラリの Remote Procedure Call (RPC) コンポーネントを除外することができます。RPC コンポーネントは、Go 1.x ランタイムを使用している場合にのみ必要です。RPC を除外すると、デプロイパッケージのサイズが小さくなります。
   + この例の Dockerfile には [USER 命令](https://docs.docker.com/reference/dockerfile/#user)が含まれていないことに注意してください。コンテナイメージを Lambda にデプロイすると、最小特権のアクセス許可を付与したデフォルトの Linux ユーザーを Lambda が自動的に定義します。これは標準の Docker 動作とは異なります。標準の動作とは、`USER` 命令を指定しなかったときに `root` ユーザーのデフォルトとなる動作のことです。  
**Example — マルチステージビルド 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
   FROM public.ecr.aws/lambda/provided:al2023
   COPY --from=build /helloworld/main ./main
   ENTRYPOINT [ "./main" ]
   ```

1. Docker イメージを「[Docker の構築](https://docs.docker.com/engine/reference/commandline/build/)」コマンドで構築します。次の例では、イメージを `docker-image` と名付けて `test` [タグ](https://docs.docker.com/engine/reference/commandline/build/#tag)を付けます。Lambda互換のイメージを作成するには、 `--provenance=false` オプションを使用する必要があります。

   ```
   docker buildx build --platform linux/amd64 --provenance=false -t docker-image:test .
   ```
**注記**  
このコマンドは、ビルドマシンのアーキテクチャに関係なく、コンテナが Lambda の実行環境と互換性があることを確認する `--platform linux/amd64` オプションを特定します。ARM64 命令セットアーキテクチャを使用して Lambda 関数を作成する場合は、代わりに `--platform linux/arm64` オプションを使用するようにコマンドを変更してください。

### (オプション) イメージをローカルでテストする
<a name="go-custom-test"></a>

[ランタイムインターフェイスエミュレーター](https://github.com/aws/aws-lambda-runtime-interface-emulator/)を使用して、イメージをローカルでテストします。`provided.al2023` ベースイメージには、ランタイムインターフェイスエミュレーターが含まれています。

**ローカルマシンでランタイムインターフェイスエミュレーターを実行するには**

1. **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` でローカルエンドポイントを作成します。

1. 新しいターミナルウィンドウから、**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!"}'
   ```

1. コンテナ ID を取得します。

   ```
   docker ps
   ```

1. 「[docker kill](https://docs.docker.com/engine/reference/commandline/kill/)」コマンドを使用してコンテナを停止します。このコマンドでは、`3766c4ab331c` を前のステップのコンテナ ID で置き換えます。

   ```
   docker kill 3766c4ab331c
   ```

### イメージのデプロイ
<a name="go-custom-deploy"></a>

**Amazon ECR にイメージをアップロードして Lambda 関数を作成するには**

1. 「[get-login-password](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/get-login-password.html)」コマンドを実行して 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-stdin 111122223333.dkr.ecr.us-east-1.amazonaws.com
   ```

1. 「[create-repository](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/create-repository.html)」コマンドを使用して Amazon ECR にリポジトリを作成します。

   ```
   aws ecr create-repository --repository-name hello-world --region us-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"
           }
       }
   }
   ```

1. 前のステップの出力から `repositoryUri` をコピーします。

1. 「[docker tag](https://docs.docker.com/engine/reference/commandline/tag/)」コマンドを実行して、最新バージョンとしてローカルイメージを Amazon ECR リポジトリにタグ付けします。このコマンドで:
   + `docker-image:test` は、Docker イメージの名前と[タグ](https://docs.docker.com/engine/reference/commandline/build/#tag)です。これは、`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
   ```

1. 「[docker push](https://docs.docker.com/engine/reference/commandline/push/)」コマンドを実行して Amazon ECR リポジトリにローカルイメージをデプロイします リポジトリ URI の末尾には必ず `:latest` を含めてください。

   ```
   docker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. まだ作成済みでない場合、関数に「[実行ロールの作成](lambda-intro-execution-role.md#permissions-executionrole-api)」を実行してください。次のステップではロールの Amazon リソースネーム (ARN) が必要です。

1. 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 \
     --role arn:aws:iam::111122223333:role/lambda-ex
   ```
**注記**  
イメージが Lambda 関数と同じリージョンに配置されていれば、別の AWS アカウントのイメージを使用して関数を作成することができます。詳細については、「[Amazon ECR クロスアカウント許可](images-create.md#configuration-images-xaccount-permissions)」を参照してください。

1. 関数を呼び出します。

   ```
   aws lambda invoke --function-name hello-world response.json
   ```

   次のような結果が表示されます。

   ```
   {
     "ExecutedVersion": "$LATEST", 
     "StatusCode": 200
   }
   ```

1. 関数の出力を確認するには、`response.json` ファイルをチェックします。

関数コードを更新するには、イメージを再構築し、新しいイメージを Amazon ECR リポジトリにアップロードしてから、[update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) コマンドを使用してイメージを Lambda 関数にデプロイする必要があります。

Lambda は、イメージタグを特定のイメージダイジェストに解決します。これは、関数のデプロイに使用されたイメージタグを Amazon ECR 内の新しいイメージを指すように変更しても、Lambda は新しいイメージを使用するように自動的に関数を更新しないことを意味します。

新しいイメージを同じ Lambda 関数にデプロイするには、Amazon ECR のイメージタグが同じままであっても、[update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) コマンドを使用する必要があります。次の例では、`--publish` オプションが最新のコンテナイメージを使用して関数の新しいバージョンを作成しています。

```
aws lambda update-function-code \
  --function-name hello-world \
  --image-uri 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
  --publish
```

## 非 AWS ベースイメージを使用する
<a name="go-image-other"></a>

非 AWS ベースイメージからも、Go 用のコンテナイメージを構築できます。次のステップでは、Dockerfile の例で [Alpine ベースイメージ](https://hub.docker.com/_/golang/)を使用しています。

[aws-lambda-go/lambda](https://github.com/aws/aws-lambda-go) パッケージを Go ハンドラに含める必要があります。このパッケージにより、ランタイムインターフェイスを含む、Go のプログラミングモデルが実装されます。

### 前提条件
<a name="go-alt-prerequisites"></a>

このセクションの手順を完了するには、以下が必要です。
+ [AWS CLI バージョン 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [Docker](https://docs.docker.com/get-docker) (最小バージョン 25.0.0)
+ Docker [buildx プラグイン](https://github.com/docker/buildx/blob/master/README.md)。
+ Go

### 代替ベースイメージからイメージを作成する
<a name="go-alt-create"></a>

**Alpine ベースイメージを使用して Go 関数をビルドおよびデプロイするには**

1. プロジェクト用のディレクトリを作成し、そのディレクトリに切り替えます。

   ```
   mkdir hello
   cd hello
   ```

1. 新しい Go モジュールを初期化します。

   ```
   go mod init example.com/hello-world
   ```

1. **Lambda** ライブラリを新しいモジュールの依存関係として追加します。

   ```
   go get github.com/aws/aws-lambda-go/lambda
   ```

1. 「`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)
   }
   ```

1. テキストエディタを使用して、プロジェクトディレクトリに Dockerfile を作成します。次の Dockerfile の例では、[Alpine ベースイメージ](https://hub.docker.com/_/golang/)を使用しています。この例の Dockerfile には [USER 命令](https://docs.docker.com/reference/dockerfile/#user)が含まれていないことに注意してください。コンテナイメージを Lambda にデプロイすると、最小特権のアクセス許可を付与したデフォルトの Linux ユーザーを Lambda が自動的に定義します。これは標準の Docker 動作とは異なります。標準の動作とは、`USER` 命令を指定しなかったときに `root` ユーザーのデフォルトとなる動作のことです。  
**Example 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" ]
   ```

1. Docker イメージを「[Docker の構築](https://docs.docker.com/engine/reference/commandline/build/)」コマンドで構築します。次の例では、イメージを `docker-image` と名付けて `test` [タグ](https://docs.docker.com/engine/reference/commandline/build/#tag)を付けます。Lambda互換のイメージを作成するには、 `--provenance=false` オプションを使用する必要があります。

   ```
   docker buildx build --platform linux/amd64 --provenance=false -t docker-image:test .
   ```
**注記**  
このコマンドは、ビルドマシンのアーキテクチャに関係なく、コンテナが Lambda の実行環境と互換性があることを確認する `--platform linux/amd64` オプションを特定します。ARM64 命令セットアーキテクチャを使用して Lambda 関数を作成する場合は、代わりに `--platform linux/arm64` オプションを使用するようにコマンドを変更してください。

### (オプション) イメージをローカルでテストする
<a name="go-alt-test"></a>

[ランタイムインターフェイスエミュレーター](https://github.com/aws/aws-lambda-runtime-interface-emulator/)を使用して、イメージをローカルでテストします。[エミュレーターはイメージに組み込むことも](https://github.com/aws/aws-lambda-runtime-interface-emulator/?tab=readme-ov-file#build-rie-into-your-base-image)、次の手順を使用してローカルマシンにインストールすることもできます。

**ローカルマシンにランタイムインターフェイスエミュレーターをインストールして実行するには**

1. プロジェクトディレクトリから次のコマンドを実行して、GitHub からランタイムインターフェイスエミュレーター (x86-64 アーキテクチャ) をダウンロードし、ローカルマシンにインストールします。

------
#### [ Linux/macOS ]

   ```
   mkdir -p ~/.aws-lambda-rie && \
       curl -Lo ~/.aws-lambda-rie/aws-lambda-rie https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie && \
       chmod +x ~/.aws-lambda-rie/aws-lambda-rie
   ```

   arm64 エミュレータをインストールするには、前のコマンドの GitHub リポジトリ URL を次のように置き換えます。

   ```
   https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie-arm64
   ```

------
#### [ PowerShell ]

   ```
   $dirPath = "$HOME\.aws-lambda-rie"
   if (-not (Test-Path $dirPath)) {
       New-Item -Path $dirPath -ItemType Directory
   }
         
   $downloadLink = "https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie"
   $destinationPath = "$HOME\.aws-lambda-rie\aws-lambda-rie"
   Invoke-WebRequest -Uri $downloadLink -OutFile $destinationPath
   ```

   arm64 エミュレーターをインストールするには、`$downloadLink` を次のように置き換えます。

   ```
   https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie-arm64
   ```

------

1. **docker run** コマンドを使用して、Docker イメージを起動します。次の点に注意してください。
   + `docker-image` はイメージ名、`test` はタグです。
   + `/main` は Dockerfile からの `ENTRYPOINT` です。

------
#### [ Linux/macOS ]

   ```
   docker run --platform linux/amd64 -d -v ~/.aws-lambda-rie:/aws-lambda -p 9000:8080 \
       --entrypoint /aws-lambda/aws-lambda-rie \
       docker-image:test \
           /main
   ```

------
#### [ PowerShell ]

   ```
   docker run --platform linux/amd64 -d -v "$HOME\.aws-lambda-rie:/aws-lambda" -p 9000:8080 `
   --entrypoint /aws-lambda/aws-lambda-rie `
   docker-image:test `
       /main
   ```

------

   このコマンドはイメージをコンテナとして実行し、`localhost:9000/2015-03-31/functions/function/invocations` でローカルエンドポイントを作成します。
**注記**  
ARM64 命令セットアーキテクチャ用に Docker イメージをビルドした場合は、`--platform linux/amd64` の代わりに `--platform linux/arm64` オプションを使用してください。

1. イベントをローカルエンドポイントにポストします。

------
#### [ Linux/macOS ]

   Linux および macOS では、次の `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!"}'
   ```

------
#### [ PowerShell ]

   PowerShell で次の `Invoke-WebRequest` コマンドを実行します。

   ```
   Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{}' -ContentType "application/json"
   ```

   このコマンドは、空のイベントで関数を呼び出し、応答を返します。サンプル関数コードではなく独自の関数コードを使用している場合は、JSON ペイロードを使用して関数を呼び出すことをお勧めします。例:

   ```
   Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{"payload":"hello world!"}' -ContentType "application/json"
   ```

------

1. コンテナ ID を取得します。

   ```
   docker ps
   ```

1. 「[docker kill](https://docs.docker.com/engine/reference/commandline/kill/)」コマンドを使用してコンテナを停止します。このコマンドでは、`3766c4ab331c` を前のステップのコンテナ ID で置き換えます。

   ```
   docker kill 3766c4ab331c
   ```

### イメージのデプロイ
<a name="go-alt-deploy"></a>

**Amazon ECR にイメージをアップロードして Lambda 関数を作成するには**

1. 「[get-login-password](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/get-login-password.html)」コマンドを実行して 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-stdin 111122223333.dkr.ecr.us-east-1.amazonaws.com
   ```

1. 「[create-repository](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/create-repository.html)」コマンドを使用して Amazon ECR にリポジトリを作成します。

   ```
   aws ecr create-repository --repository-name hello-world --region us-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"
           }
       }
   }
   ```

1. 前のステップの出力から `repositoryUri` をコピーします。

1. 「[docker tag](https://docs.docker.com/engine/reference/commandline/tag/)」コマンドを実行して、最新バージョンとしてローカルイメージを Amazon ECR リポジトリにタグ付けします。このコマンドで:
   + `docker-image:test` は、Docker イメージの名前と[タグ](https://docs.docker.com/engine/reference/commandline/build/#tag)です。これは、`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
   ```

1. 「[docker push](https://docs.docker.com/engine/reference/commandline/push/)」コマンドを実行して Amazon ECR リポジトリにローカルイメージをデプロイします リポジトリ URI の末尾には必ず `:latest` を含めてください。

   ```
   docker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. まだ作成済みでない場合、関数に「[実行ロールの作成](lambda-intro-execution-role.md#permissions-executionrole-api)」を実行してください。次のステップではロールの Amazon リソースネーム (ARN) が必要です。

1. 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 \
     --role arn:aws:iam::111122223333:role/lambda-ex
   ```
**注記**  
イメージが Lambda 関数と同じリージョンに配置されていれば、別の AWS アカウントのイメージを使用して関数を作成することができます。詳細については、「[Amazon ECR クロスアカウント許可](images-create.md#configuration-images-xaccount-permissions)」を参照してください。

1. 関数を呼び出します。

   ```
   aws lambda invoke --function-name hello-world response.json
   ```

   次のような結果が表示されます。

   ```
   {
     "ExecutedVersion": "$LATEST", 
     "StatusCode": 200
   }
   ```

1. 関数の出力を確認するには、`response.json` ファイルをチェックします。

関数コードを更新するには、イメージを再構築し、新しいイメージを Amazon ECR リポジトリにアップロードしてから、[update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) コマンドを使用してイメージを Lambda 関数にデプロイする必要があります。

Lambda は、イメージタグを特定のイメージダイジェストに解決します。これは、関数のデプロイに使用されたイメージタグを Amazon ECR 内の新しいイメージを指すように変更しても、Lambda は新しいイメージを使用するように自動的に関数を更新しないことを意味します。

新しいイメージを同じ Lambda 関数にデプロイするには、Amazon ECR のイメージタグが同じままであっても、[update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) コマンドを使用する必要があります。次の例では、`--publish` オプションが最新のコンテナイメージを使用して関数の新しいバージョンを作成しています。

```
aws lambda update-function-code \
  --function-name hello-world \
  --image-uri 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
  --publish
```

# Go Lambda 関数のレイヤーを操作する
<a name="golang-layers"></a>

Go で書かれた Lambda 関数の依存関係を[レイヤー](chapter-layers.md)で管理するという方法はお勧めしません。Go で書かれた Lambda 関数が単一の実行可能ファイルにコンパイルされて、関数をデプロイしたときにそのファイルが Lambda に渡されるためです。この実行可能ファイルには、コンパイルされた関数コードがそのすべての依存関係と共に含まれています。レイヤーを使用すると、このプロセスが複雑になります。そのうえ、他に必要なアセンブリがあれば、初期化フェーズ中にいちいちメモリにロードしなければならないため、コールドスタート時間が長くなります。

Go ハンドラーで外部の依存関係を使用する場合は、その依存関係をデプロイパッケージに直接含めます。これにより、デプロイプロセスが簡素化されるうえ、組み込みの Go コンパイラの最適化機能を活かせます。AWS SDK for Go のように依存関係を関数にインポートして使用する方法の例については、「[Go の Lambda 関数ハンドラーの定義](golang-handler.md)」を参照してください。

# Go Lambda 関数のログ記録とモニタリング
<a name="golang-logging"></a>

AWS Lambda は、ユーザーに代わって Lambda 関数を自動的にモニタリングし、Amazon CloudWatch にログを送信します。Lambda 関数には、関数のインスタンスごとに CloudWatch Logs ロググループとログストリームが用意されています。Lambda ランタイム環境は、各呼び出しの詳細をログストリームに送信し、関数のコードからのログやその他の出力を中継します。詳細については、「[Lambda 関数ログを CloudWatch Logs に送信する](monitoring-cloudwatchlogs.md)」を参照してください。

このページでは、AWS Command Line Interface、Lambda コンソール、または CloudWatch コンソールを使用して、Lambda 関数のコードからログ出力を生成する方法、およびアクセスログを生成する方法について説明します。

**Topics**
+ [ログを返す関数の作成](#golang-logging-output)
+ [Lambda コンソールでログを表示する](#golang-logging-console)
+ [CloudWatch コンソールでの ログの表示](#golang-logging-cwconsole)
+ [AWS Command Line Interface (AWS CLI) を使用してログを表示する](#golang-logging-cli)
+ [ログの削除](#golang-logging-delete)

## ログを返す関数の作成
<a name="golang-logging-output"></a>

関数コードからログを出力するには、[fmt パッケージ](https://golang.org/pkg/fmt/)のメソッドか、`stdout` または `stderr` に書き込む任意のログ記録のライブラリを使用します。以下の例では、[ログパッケージ](https://golang.org/pkg/log/)を使用しています。

**Example [main.go](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-go/function/main.go) － ログ記録**  

```
func handleRequest(ctx context.Context, event events.SQSEvent) (string, error) {
  // event
  eventJson, _ := json.MarshalIndent(event, "", "  ")
  log.Printf("EVENT: %s", eventJson)
  // environment variables
  log.Printf("REGION: %s", os.Getenv("AWS_REGION"))
  log.Println("ALL ENV VARS:")
  for _, element := range os.Environ() {
    log.Println(element)
  }
```

**Example ログの形式**  

```
START RequestId: dbda340c-xmpl-4031-8810-11bb609b4c71 Version: $LATEST
2020/03/27 03:40:05 EVENT: {
  "Records": [
    {
      "messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78",
      "receiptHandle": "MessageReceiptHandle",
      "body": "Hello from SQS!",
      "md5OfBody": "7b27xmplb47ff90a553787216d55d91d",
      "md5OfMessageAttributes": "",
      "attributes": {
        "ApproximateFirstReceiveTimestamp": "1523232000001",
        "ApproximateReceiveCount": "1",
        "SenderId": "123456789012",
        "SentTimestamp": "1523232000000"
      },
      ...
2020/03/27 03:40:05 AWS_LAMBDA_LOG_STREAM_NAME=2020/03/27/[$LATEST]569cxmplc3c34c7489e6a97ad08b4419
2020/03/27 03:40:05 AWS_LAMBDA_FUNCTION_NAME=blank-go-function-9DV3XMPL6XBC
2020/03/27 03:40:05 AWS_LAMBDA_FUNCTION_MEMORY_SIZE=128
2020/03/27 03:40:05 AWS_LAMBDA_FUNCTION_VERSION=$LATEST
2020/03/27 03:40:05 AWS_EXECUTION_ENV=AWS_Lambda_go1.x
END RequestId: dbda340c-xmpl-4031-8810-11bb609b4c71
REPORT RequestId: dbda340c-xmpl-4031-8810-11bb609b4c71	Duration: 38.66 ms	Billed Duration: 243 ms	Memory Size: 128 MB	Max Memory Used: 54 MB	Init Duration: 203.69 ms	
XRAY TraceId: 1-5e7d7595-212fxmpl9ee07c4884191322	SegmentId: 42ffxmpl0645f474	Sampled: true
```

Go ランタイムは、呼び出しごとに `START`、`END`、および `REPORT` の各行を記録します。レポート行には、次の詳細が示されます。

**REPORT 行のデータフィールド**
+ **RequestId** － 呼び出しの一意のリクエスト ID。
+ **所要時間** － 関数のハンドラーメソッドがイベントの処理に要した時間。
+ **課金期間** － 呼び出しの課金対象の時間。
+ **メモリサイズ** － 関数に割り当てられたメモリの量。
+ **使用中の最大メモリ** － 関数によって使用されているメモリの量。呼び出しが実行環境を共有すると、Lambda はすべての呼び出しで使用される最大メモリを報告します。この動作により、予想よりも高い報告値が発生する可能性があります。
+ **初期所要時間** － 最初に処理されたリクエストについて、ハンドラーメソッド外で関数をロードしてコードを実行するためにランタイムにかかった時間。
+ **XRAY TraceId** － トレースされたリクエストの場合、[AWS X-Ray のトレース ID](services-xray.md)。
+ **SegmentId** － トレースされたリクエストの場合、X-Ray のセグメント ID。
+ **サンプリング済み** － トレースされたリクエストの場合、サンプリング結果。

## Lambda コンソールでログを表示する
<a name="golang-logging-console"></a>

Lambda コンソールを使用して、Lambda 関数を呼び出した後のログ出力を表示できます。

組み込み **Code** エディタからコードがテスト可能である場合、**[実行結果]** でログを確認できます。コンソールのテスト機能を使用して関数を呼び出すと、**[詳細]** セクションで **[ログ出力]** を確認できます。

## CloudWatch コンソールでの ログの表示
<a name="golang-logging-cwconsole"></a>

Amazon CloudWatch コンソールを使用して、すべての Lambda 関数呼び出しのログを表示できます。

**CloudWatch コンソールでログを表示するには**

1. CloudWatch コンソールの [[Log groups (ロググループ)] ページ](https://console.aws.amazon.com/cloudwatch/home?#logs:)を開きます。

1. 機能のロググループを選択します( **/aws/lambda/*関数名***)

1. ログストリームを選択します

各ログストリームは、[関数のインスタンス](lambda-runtime-environment.md)に相当します。ログストリームは、Lambda 関数を更新したとき、および同時呼び出しを処理するために追加のインスタンスが作成されたときに表示されます。特定の呼び出しのログを検索するために、AWS X-Ray を使って関数をインストルメント化することをお勧めします。　 X-Ray は、リクエストとログストリームの詳細をトレースに記録します。

## AWS Command Line Interface (AWS CLI) を使用してログを表示する
<a name="golang-logging-cli"></a>

AWS CLI は、コマンドラインシェルでコマンドを使用して AWS サービスとやり取りするためのオープンソースツールです。このセクションの手順を完了するには、[AWS CLIバージョン 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) が必要です。

[AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) および `--log-type` コマンドオプションを使用して、呼び出しのログを取得します。レスポンスには、`LogResult`フィールドが含まれ、このフィールドには、呼び出しから base64 コードされた最大 4 KB のログが含まれます。

**Example ログ ID を取得します**  
次の例は、`LogResult`という名前の関数の`my-function`フィールドから*ログ ID * を取得する方法を示しています。  

```
aws lambda invoke --function-name my-function out --log-type Tail
```
次のような出力が表示されます。  

```
{
    "StatusCode": 200,
    "LogResult": "U1RBUlQgUmVxdWVzdElkOiA4N2QwNDRiOC1mMTU0LTExZTgtOGNkYS0yOTc0YzVlNGZiMjEgVmVyc2lvb...",
    "ExecutedVersion": "$LATEST"
}
```

**Example ログをデコードします**  
同じコマンドプロンプトで、`base64` ユーティリティを使用してログをデコードします。次の例は、`my-function`の base64 でエンコードされたログを取得する方法を示しています 。  

```
aws lambda invoke --function-name my-function out --log-type Tail \
--query 'LogResult' --output text --cli-binary-format raw-in-base64-out | base64 --decode
```
AWS CLI バージョン 2 を使用している場合、**cli-binary-format** オプションは必須です。これをデフォルト設定にするには、`aws configure set cli-binary-format raw-in-base64-out` を実行します。詳細については、「*AWS Command Line Interface バージョン 2 用ユーザーガイド*」の「[AWS CLI でサポートされているグローバルコマンドラインオプション](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list)」を参照してください。  
以下の出力が表示されます。  

```
START RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8 Version: $LATEST
"AWS_SESSION_TOKEN": "AgoJb3JpZ2luX2VjELj...", "_X_AMZN_TRACE_ID": "Root=1-5d02e5ca-f5792818b6fe8368e5b51d50;Parent=191db58857df8395;Sampled=0"",ask/lib:/opt/lib",
END RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8
REPORT RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8  Duration: 79.67 ms      Billed Duration: 80 ms         Memory Size: 128 MB     Max Memory Used: 73 MB
```
`base64`このユーティリティは、Linux、macOS、および [ Windows の Ubuntu ](https://docs.microsoft.com/en-us/windows/wsl/install-win10) で使用できます。macOS ユーザーは、`base64 -D`を使用する必要があります 。

**Example get-logs.sh スクリプト**  
同じコマンドプロンプトで、次のスクリプトを使用して、最後の 5 つのログイベントをダウンロードします。このスクリプトは `sed` を使用して出力ファイルから引用符を削除し、ログが使用可能になるまで 15 秒待機します。この出力には Lambda からのレスポンスと、`get-log-events` コマンドからの出力が含まれます。  
次のコードサンプルの内容をコピーし、Lambda プロジェクトディレクトリに `get-logs.sh` として保存します。  
AWS CLI バージョン 2 を使用している場合、**cli-binary-format** オプションは必須です。これをデフォルト設定にするには、`aws configure set cli-binary-format raw-in-base64-out` を実行します。詳細については、「*AWS Command Line Interface バージョン 2 用ユーザーガイド*」の「[AWS CLI でサポートされているグローバルコマンドラインオプション](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list)」を参照してください。  

```
#!/bin/bash
aws lambda invoke --function-name my-function --cli-binary-format raw-in-base64-out --payload '{"key": "value"}' out
sed -i'' -e 's/"//g' out
sleep 15
aws logs get-log-events --log-group-name /aws/lambda/my-function --log-stream-name stream1 --limit 5
```

**Example macOS および Linux (専用)**  
同じコマンドプロンプトで、macOS と Linux ユーザーが次のコマンドを実行して、スクリプトが実行可能であることを確認する必要があります。  

```
chmod -R 755 get-logs.sh
```

**Example 最後の 5 つのログイベントを取得します**  
同じコマンドプロンプトで、次のスクリプトを実行して、最後の 5 つのログイベントを取得します。  

```
./get-logs.sh
```
次のような出力が表示されます。  

```
{
    "StatusCode": 200,
    "ExecutedVersion": "$LATEST"
}
{
    "events": [
        {
            "timestamp": 1559763003171,
            "message": "START RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf Version: $LATEST\n",
            "ingestionTime": 1559763003309
        },
        {
            "timestamp": 1559763003173,
            "message": "2019-06-05T19:30:03.173Z\t4ce9340a-b765-490f-ad8a-02ab3415e2bf\tINFO\tENVIRONMENT VARIABLES\r{\r  \"AWS_LAMBDA_FUNCTION_VERSION\": \"$LATEST\",\r ...",
            "ingestionTime": 1559763018353
        },
        {
            "timestamp": 1559763003173,
            "message": "2019-06-05T19:30:03.173Z\t4ce9340a-b765-490f-ad8a-02ab3415e2bf\tINFO\tEVENT\r{\r  \"key\": \"value\"\r}\n",
            "ingestionTime": 1559763018353
        },
        {
            "timestamp": 1559763003218,
            "message": "END RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf\n",
            "ingestionTime": 1559763018353
        },
        {
            "timestamp": 1559763003218,
            "message": "REPORT RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf\tDuration: 26.73 ms\tBilled Duration: 27 ms \tMemory Size: 128 MB\tMax Memory Used: 75 MB\t\n",
            "ingestionTime": 1559763018353
        }
    ],
    "nextForwardToken": "f/34783877304859518393868359594929986069206639495374241795",
    "nextBackwardToken": "b/34783877303811383369537420289090800615709599058929582080"
}
```

## ログの削除
<a name="golang-logging-delete"></a>

関数を削除しても、ロググループは自動的には削除されません。ログが無期限に保存されないようにするには、ロググループを削除するか、ログが自動的に削除されるまでの[保存期間を設定](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html#SettingLogRetention)します。

# AWS Lambda での Go コードの作成
<a name="golang-tracing"></a>

Lambda アプリケーションのトレース、デバッグ、最適化を行うために、Lambda は AWS X-Ray と統合されています。X-Ray を使用すると、Lambda 関数や他の AWS のサービスが含まれるアプリケーション内で、リソースを横断するリクエストをトレースできます。

トレースされたデータを X-Ray に送信するには、以下の 2 つの SDK ライブラリのいずれかを使用します。
+ [AWS Distro for OpenTelemetry (ADOT)](https://aws.amazon.com/otel) – 安全で、本番環境に対応し、AWS でサポートされている OpenTelemetry (OTel) SDK のディストリビューションです。
+ [AWS X-Ray SDK for Go](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-go.html) – トレースデータを生成して X-Ray に送信するための SDK。

各 SDK は、テレメトリデータを X-Ray サービスに送信する方法を提供します。続いて、X-Ray を使用してアプリケーションのパフォーマンスメトリクスの表示やフィルタリングを行い、インサイトを取得することで、問題点や最適化の機会を特定できます。

**重要**  
X-Ray および Powertools for AWS Lambda SDK は、AWS が提供する、密接に統合された計測ソリューションの一部です。ADOT Lambda レイヤーは、一般的により多くのデータを収集するトレーシング計測の業界標準の一部ですが、すべてのユースケースに適しているわけではありません。これらのソリューションのいずれかを使用して、X-Ray でエンドツーエンドのトレーシングを実装することができます。選択方法の詳細については、「[Choosing between the AWS Distro for Open Telemetry and X-Ray SDKs](https://docs.aws.amazon.com/xray/latest/devguide/xray-instrumenting-your-app.html#xray-instrumenting-choosing)」( Distro for Open Telemetry または X-Ray SDK の選択) を参照してください。

**Topics**
+ [Go 関数の計測に対する ADOT の使用](#golang-adot)
+ [Go 関数の計測のための X-Ray SDK の使用](#golang-xray-sdk)
+ [Lambda コンソールを使用してトレースを有効化する](#golang-tracing-console)
+ [Lambda API でのトレースのアクティブ化](#golang-tracing-api)
+ [CloudFormation によるトレースのアクティブ化](#golang-tracing-cloudformation)
+ [X-Ray トレースの解釈](#golang-tracing-interpretation)

## Go 関数の計測に対する ADOT の使用
<a name="golang-adot"></a>

ADOT は、Otel SDK を使用してテレメトリデータを収集するために必要なすべてをパッケージ化した、フルマネージド型の Lambda [レイヤー](chapter-layers.md)を提供します。このレイヤーを使用すると、関数コードを変更する必要はなしで、Lambda 関数を計測できます。また、このレイヤーは、OTel でのカスタムな初期化を実行するように構成することもできます。詳細については、ADOT のドキュメントにある「[Lambda 上での ADOT Collector のカスタム設定](https://aws-otel.github.io/docs/getting-started/lambda#custom-configuration-for-the-adot-collector-on-lambda)」を参照してください。

Go ランタイムの場合は、**AWS 管理の Lambda layer for ADOT Go** を追加して、関数を自動的に計測することが可能です。このレイヤーを追加する方法の詳しい手順については、「ADOT ドキュメント」で「[Go に対する AWS Distro for OpenTelemetry Lambda のサポート](https://aws-otel.github.io/docs/getting-started/lambda/lambda-go)」を参照してください。

## Go 関数の計測のための X-Ray SDK の使用
<a name="golang-xray-sdk"></a>

AWS X-Ray SDK for Go を使用して、Lambda 関数がアプリケーション内の他のリソースに対して行う呼び出しの詳細を記録することもできます。SDK を取得するには、`go get` を使用して [GitHub リポジトリ](https://github.com/aws/aws-xray-sdk-go)からダウンロードします。

```
go get github.com/aws/aws-xray-sdk-go
```

AWS SDK クライアントを実装するには、クライアントを `xray.AWS()` メソッドに渡します。その後、このメソッドの `WithContext` バージョンを使用することで、呼び出しをトレースできます。

```
svc := s3.New(session.New())
xray.AWS(svc.Client)
...
svc.ListBucketsWithContext(ctx aws.Context, input *ListBucketsInput)
```

正しい依存関係を追加し、必要なコード変更を行った後、Lambda コンソールまたは API を介して関数の設定でトレースをアクティブにします。

## Lambda コンソールを使用してトレースを有効化する
<a name="golang-tracing-console"></a>

コンソールを使用して、Lambda 関数のアクティブトレースをオンにするには、次のステップに従います。

**アクティブトレースをオンにするには**

1. Lambda コンソールの [[関数ページ]](https://console.aws.amazon.com/lambda/home#/functions) を開きます。

1. 関数を選択します。

1. **[設定]** を選択してから、**[モニタリングおよび運用ツール]** を選択します。

1. **[その他の監視ツール]** で、**[編集]** を選択します。

1. **[CloudWatch Application Signals と AWS X-Ray]** で、**[Lambda サービストレース]** の **[有効]** を選択します。

1. **[保存]** を選択します。

## Lambda API でのトレースのアクティブ化
<a name="golang-tracing-api"></a>

AWS CLI または AWS SDK で Lambda 関数のトレースを設定するには、次の API オペレーションを使用します。
+ [UpdateFunctionConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionConfiguration.html)
+ [GetFunctionConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_GetFunctionConfiguration.html)
+ [CreateFunction](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html)

以下の例の AWS CLI コマンドは、**my-function** という名前の関数に対するアクティブトレースを有効にします。

```
aws lambda update-function-configuration --function-name my-function \
--tracing-config Mode=Active
```

トレースモードは、関数のバージョンを公開するときのバージョン固有の設定の一部です。公開後のバージョンのトレースモードを変更することはできません。

## CloudFormation によるトレースのアクティブ化
<a name="golang-tracing-cloudformation"></a>

CloudFormation テンプレート内で `AWS::Lambda::Function` リソースに対するアクティブトレースを有効化するには、`TracingConfig` プロパティを使用します。

**Example [function-inline.yml](https://github.com/awsdocs/aws-lambda-developer-guide/blob/master/templates/function-inline.yml) － トレース設定**  

```
Resources:
  function:
    Type: [AWS::Lambda::Function](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html)
    Properties:
      TracingConfig:
        Mode: Active
      ...
```

AWS Serverless Application Model (AWS SAM) `AWS::Serverless::Function` リソースに、`Tracing` プロパティを使用します。

**Example [template.yml](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-nodejs/template.yml) － トレース設定**  

```
Resources:
  function:
    Type: [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)
    Properties:
      Tracing: Active
      ...
```

## X-Ray トレースの解釈
<a name="golang-tracing-interpretation"></a>

関数には、トレースデータを X-Ray にアップロードするためのアクセス許可が必要です。Lambda コンソールでトレースを有効にすると、Lambda は必要な権限を関数の [[実行ロール]](lambda-intro-execution-role.md) に追加します。それ以外の場合は、[AWSXRayDaemonWriteAccess](https://console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess) ポリシーを実行ロールに追加します。

アクティブトレースの設定後は、アプリケーションを通じて特定のリクエストの観測が行えるようになります。[[X-Ray サービスグラフ]](https://docs.aws.amazon.com/xray/latest/devguide/aws-xray.html#xray-concepts-servicegraph) には、アプリケーションとそのすべてのコンポーネントに関する情報が表示されます。次の例は、2 つの関数を持つアプリケーションを示しています。プライマリ関数はイベントを処理し、エラーを返す場合があります。上位 2 番目の関数は、最初のロググループに表示されるエラーを処理し、AWS SDK を使用して X-Ray、Amazon Simple Storage Service (Amazon S3)、および Amazon CloudWatch Logs を呼び出します。

![\[\]](http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/images/sample-errorprocessor-servicemap.png)


X-Ray は、アプリケーションへのすべてのリクエストをトレースするわけではありません。X-Ray は、サンプリングアルゴリズムを適用することで効率的なトレースを行うと同時に、すべてのリクエストについての代表的なサンプルを示します。サンプルレートは 1 秒あたり 1 回のリクエストで、追加リクエストの 5％ です。関数の X-Ray サンプルレートを設定することはできません。

X-Ray では、*トレース*は 1 つ以上の*サービス*によって処理されるリクエストに関する情報を記録します。Lambda はトレースごとに 2 つのセグメントを記録します。これにより、サービスグラフに 2 つのノードが作成されます。次の図は、これら 2 つのノードを強調表示しています。

![\[\]](http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/images/xray-servicemap-function.png)


左に示された 1 つめのノードは、呼び出しリクエストを受信する Lambda サービスを表しています。2 つめのノードは、特定の Lambda 関数を表しています。次の例は、これら 2 つのセグメントを使用したトレースを示しています。いずれも **my-function** と名付けられていますが、1 つは `AWS::Lambda` の起点があり、もう 1 つは `AWS::Lambda::Function` の起点があります。`AWS::Lambda` セグメントにエラーが表示される場合は、Lambda サービスに問題があります。`AWS::Lambda::Function` セグメントにエラーが表示される場合、関数に問題があります。

![\[\]](http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/images/V2_sandbox_images/my-function-2-v1.png)


この例では、`AWS::Lambda::Function` セグメントを展開して、それの 3 つのサブセグメントが表示されています。

**注記**  
AWS は現在、Lambda サービスに変更を実装しています。これらの変更により、AWS アカウント のさまざまな Lambda 関数によって出力されるシステムログメッセージとトレースセグメントの構造と内容にわずかな違いが生じる場合があります。  
ここで示すトレースの例は、古いスタイルの関数セグメントを示しています。古いスタイルのセグメントと新しいスタイルのセグメントの違いについては、次の段落で説明します。  
これらの変更は今後数週間に実装され、中国および GovCloud リージョンを除くすべての AWS リージョンのすべての関数は、新しい形式のログメッセージとトレースセグメントを使用するように移行されます。

古いスタイルの関数セグメントには、次のサブセグメントが含まれます。
+ **初期化** － 関数のロードと[初期化コード](foundation-progmodel.md)の実行に要した時間を表します。このサブセグメントは、関数の各インスタンスが処理する最初のイベントに対してのみ表示されます。
+ **[呼び出し]** - ハンドラーコードの実行に要した時間を表します。
+ **[オーバーヘッド]** - Lambda ランタイムが次のイベントを処理するための準備に要する時間を表します。

新しいスタイルの関数セグメントには `Invocation` サブセグメントが含まれていません。代わりに、顧客サブセグメントが関数セグメントに直接アタッチされます。古いスタイルの関数セグメントと新しいスタイルの関数セグメントの構造の詳細については、「」を参照してください[X-Ray トレースを理解する](services-xray.md#services-xray-traces)。

HTTP クライアントをインストルメント化し、SQL クエリを記録して、注釈とメタデータからカスタムサブセグメントを作成することもできます。詳細については、 「AWS X-Rayデベロッパーガイド」の「[AWS X-Ray SDK for Go](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-python.html)」を参照してください。

**料金**  
X-Ray トレースは、毎月、AWS 無料利用枠で設定された一定限度まで無料で利用できます。X-Ray の利用がこの上限を超えた場合は、トレースによる保存と取得に対する料金が発生します。詳細については、「[AWS X-Ray 料金表](https://aws.amazon.com/xray/pricing/)」を参照してください。