目次

    【2025年版】Goとサーバーレス実践ガイド:AWS Lambda, Google Cloud Functions, Azure Functions徹底比較
    GoサーバーレスAWS LambdaGoogle Cloud FunctionsAzure Functionsクラウド

    2025-06-17

    guid

    【2025年版】Goとサーバーレス実践ガイド:AWS Lambda, Google Cloud Functions, Azure Functions徹底比較

    Warning

    注意:この記事は2025年6月時点の情報に基づいて執筆されています。クラウドベンダーのアップデートにより、ランタイムバージョン、CLIオプション、サポート期限などが変更される可能性があります。実装前には必ず各社の公式ドキュメントで最新情報をご確認ください。

    高速な起動、小さなバイナリサイズ、効率的な並行処理。Go言語の特性は、まるでサーバーレスのためにあるようです。サーバー管理から解放され、コードに集中できるサーバーレスアーキテクチャは、現代の開発者にとって魅力的な選択肢となっています。

    この記事では、3大クラウドプラットフォーム(AWS Lambda、Google Cloud Functions、Azure Functions)を舞台に、Goを使ったサーバーレスアプリケーション開発の第一歩を、具体的なコード例と共にガイドします。

    AWS Lambda編:最も成熟したエコシステム

    特徴

    AWS Lambdaは最も成熟したサーバーレスプラットフォームとして、豊富な機能と詳細な設定オプションを提供します。あらゆるユースケースに対応できる柔軟性が最大の魅力です。

    実装例

    aws-lambda-go ライブラリを使用した基本的なハンドラの実装方法を見てみましょう。

    go
    1package main
    2
    3import (
    4    "context"
    5    "encoding/json"
    6    "github.com/aws/aws-lambda-go/events"
    7    "github.com/aws/aws-lambda-go/lambda"
    8)
    9
    10func handler(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
    11    // リクエストボディの解析
    12
    13    var requestBody map[string]interface{}
    14    if err := json.Unmarshal([]byte(request.Body), &requestBody); err != nil {
    15        return events.APIGatewayProxyResponse{
    16            StatusCode: 400,
    17            Headers:    map[string]string{"Content-Type": "application/json"},
    18            Body:       `{"error": "Invalid JSON"}`,
    19        }, nil
    20    }
    21
    22    // レスポンスの作成
    23
    24    responseBody := map[string]interface{}{
    25        "message": "Hello from AWS Lambda with Go!",
    26        "input":   requestBody,
    27        "method":  request.HTTPMethod,
    28        "path":    request.Path,
    29    }
    30
    31    body, _ := json.Marshal(responseBody)
    32
    33    return events.APIGatewayProxyResponse{
    34        StatusCode:      200,
    35        Headers:         map[string]string{"Content-Type": "application/json"},
    36        Body:            string(body),
    37        IsBase64Encoded: false,
    38    }, nil
    39}
    40
    41// 補足: API Gateway HTTP API (v2) を使う場合は events.APIGatewayV2HTTPRequest / APIGatewayV2HTTPResponse を利用する例も多いです。
    42// 簡易例: APIGatewayV2 を使う場合は以下のように handler のシグネチャと戻り値を変更します
    43/*
    44func handlerV2(ctx context.Context, req events.APIGatewayV2HTTPRequest) (events.APIGatewayV2HTTPResponse, error) {
    45    // JSON 解析例
    46    var payload map[string]interface{}
    47    if err := json.Unmarshal([]byte(req.Body), &payload); err != nil {
    48        return events.APIGatewayV2HTTPResponse{
    49            StatusCode: 400,
    50            Headers:    map[string]string{"Content-Type": "application/json"},
    51            Body:       `{"error":"Invalid JSON"}`,
    52        }, nil
    53    }
    54    respBody, _ := json.Marshal(map[string]interface{}{
    55        "message": "Hello from Lambda v2 with Go!",
    56        "input":   payload,
    57    })
    58    return events.APIGatewayV2HTTPResponse{
    59        StatusCode:      200,
    60        Headers:         map[string]string{"Content-Type": "application/json"},
    61        Body:            string(respBody),
    62        IsBase64Encoded: false,
    63    }, nil
    64}
    65*/
    66// 詳細は公式ドキュメント(https://docs.aws.amazon.com/lambda/latest/dg/services-apigatewayhttp.html)を参照してください。
    67
    68func main() {
    69    lambda.Start(handler)
    70}

    デプロイ方法

    Goコードをクロスコンパイルし、ZIPに固めてAWS CLIやSAM(Serverless Application Model)でデプロイします。

    重要: Go 1.xマネージドランタイムは廃止されたため、カスタムランタイムを使用する必要があります。執筆時点ではprovided.al2provided.al2023が正式サポート中です。実行可能ファイルはbootstrapという名前でビルドしてください。

    注意: Lambdaマネージドランタイムではhandler名がGo関数へのエントリポイントですが、カスタムランタイムでは実行可能ファイル名がbootstrapである点にご注意ください。

    bash
    1# クロスコンパイル(Linux環境用、バイナリサイズ最適化)
    2
    3CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -trimpath -o bootstrap main.go
    4
    5# ARM64版(Graviton2向け)
    6# CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags="-s -w" -trimpath -o bootstrap main.go
    7
    8# ZIPファイル作成
    9
    10zip function.zip bootstrap
    11
    12# AWS CLIでデプロイ(事前にIAMロールの作成が必要)
    13# 推奨:provided.al2を使用(執筆時点で正式サポート中)
    14# 注意:執筆後に新ランタイム(provided.al2023など)が正式リリースされた場合は、この値を差し替えてください。
    15# 最新ランタイムの一覧は AWS マネジメントコンソールや公式ドキュメントで確認してください。
    16# CLI コマンドは AWS CLI のバージョンによって名称が異なる可能性があります(`aws lambda list-runtimes` 等)ので、公式ドキュメントで最終確認を行ってください。
    17aws lambda create-function \
    18  --function-name go-lambda-function \
    19  --runtime provided.al2 \
    20  --role arn:aws:iam::YOUR_ACCOUNT:role/lambda-execution-role \
    21  --handler bootstrap \
    22  --zip-file fileb://function.zip \
    23  --environment Variables='KEY1=value1,KEY2=value2'
    24
    25# 注意:シェルによってはクォートが必要
    26# Bash/Zsh: --environment Variables='KEY1=value1,KEY2=value2'
    27# PowerShell: --environment Variables="KEY1=value1,KEY2=value2"
    28# または環境変数をJSONファイルで指定(推奨)
    29# aws lambda create-function ... --environment file://env-vars.json

    IAMロール設定例:

    bash
    1# Lambda実行用の基本IAMロールを作成
    2
    3aws iam create-role --role-name lambda-execution-role \
    4  --assume-role-policy-document '{
    5    "Version": "2012-10-17",
    6    "Statement": [
    7      {
    8        "Effect": "Allow",
    9        "Principal": {"Service": "lambda.amazonaws.com"},
    10        "Action": "sts:AssumeRole"
    11      }
    12    ]
    13  }'
    14
    15# または、ポリシーJSONをファイルに保存して指定(推奨)
    16# aws iam create-role --role-name lambda-execution-role \
    17#   --assume-role-policy-document file://trust-policy.json
    18
    19# 基本実行ポリシーをアタッチ
    20aws iam attach-role-policy \
    21  --role-name lambda-execution-role \
    22  --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

    詳細な移行ガイドについては、AWS公式ドキュメントをご参照ください。

    パフォーマンス最適化: コールドスタート対策として、Provisioned ConcurrencyやLambda Extensionsの活用も検討してください。これらの機能により、本格的な本番環境でのレスポンス性能を大幅に改善できます。

    IaC(Infrastructure as Code)例:

    yaml
    1# SAMテンプレート例(template.yaml)
    2# 注意:執筆後に新ランタイム(provided.al2023など)が正式リリースされた場合は、Runtime値を差し替えてください。
    3AWSTemplateFormatVersion: '2010-09-09'
    4Transform: AWS::Serverless-2016-10-31
    5
    6Resources:
    7  GoLambdaFunction:
    8    Type: AWS::Serverless::Function
    9    Properties:
    10      CodeUri: .
    11      Handler: bootstrap
    12      Runtime: provided.al2  # 最新ランタイムは公式ドキュメントで確認
    13      Architectures:
    14        - x86_64  # または arm64
    15      ProvisionedConcurrencyConfig:
    16        ProvisionedConcurrencyLevel: 5  # 本番環境では負荷に応じて適切な値を設定
    17      Environment:
    18        Variables:
    19          KEY1: value1
    20          KEY2: value2

    コンテナイメージでのデプロイ例:

    dockerfile
    1# Dockerfile(公式イメージ使用例)
    2FROM public.ecr.aws/lambda/go:1
    3COPY bootstrap ${LAMBDA_TASK_ROOT}/bootstrap
    4CMD [ "bootstrap" ]
    5
    6# より小さいイメージを目指す場合(自己責任でライブラリ依存などを考慮)
    7# FROM scratch
    8# COPY bootstrap /bootstrap
    9# ENTRYPOINT ["/bootstrap"]

    ECRプッシュ手順例:

    bash
    1# ECRリポジトリ作成(必要に応じて --region ap-northeast-1 等を指定)
    2aws ecr create-repository --repository-name go-lambda-repo --region ap-northeast-1
    3
    4# 既存リポジトリ確認(重複エラー回避)
    5# aws ecr describe-repositories --repository-names go-lambda-repo --region ap-northeast-1
    6
    7# Dockerイメージをビルド・タグ付け
    8docker build -t go-lambda-repo .
    9docker tag go-lambda-repo:latest <AWS_ACCOUNT_ID>.dkr.ecr.<region>.amazonaws.com/go-lambda-repo:latest
    10
    11# ECRにログイン
    12aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <AWS_ACCOUNT_ID>.dkr.ecr.<region>.amazonaws.com
    13
    14# イメージをプッシュ
    15docker push <AWS_ACCOUNT_ID>.dkr.ecr.<region>.amazonaws.com/go-lambda-repo:latest
    16
    17# Lambdaにコンテナイメージとしてデプロイ
    18aws lambda create-function \
    19  --function-name go-lambda-container \
    20  --package-type Image \
    21  --code ImageUri=<AWS_ACCOUNT_ID>.dkr.ecr.<region>.amazonaws.com/go-lambda-repo:latest \
    22  --role arn:aws:iam::<AWS_ACCOUNT_ID>:role/lambda-execution-role
    23
    24# 注意:コンテナイメージ最適化(マルチステージビルド、ビルドキャッシュ活用等)の詳細は
    25# 公式ドキュメントや専門記事を参照してください

    Google Cloud Functions編:標準ライブラリとの高い親和性

    特徴

    Google Cloud Functionsはnet/http標準に準拠しており、Goの標準的な書き方と親和性が高いのが特徴です。GCPの他サービスとの連携もスムーズに行えます。

    実装例

    http.HandlerFuncとして関数を実装する方法を示します。Goの標準ライブラリの知識がそのまま活かせることが分かります。

    go
    1package function
    2
    3import (
    4    "encoding/json"
    5    "log"
    6    "net/http"
    7)
    8
    9type RequestData struct {
    10    Name    string `json:"name"`
    11    Message string `json:"message"`
    12}
    13
    14type ResponseData struct {
    15    Status  string      `json:"status"`
    16    Data    RequestData `json:"data"`
    17    Service string      `json:"service"`
    18}
    19
    20// HelloWorld はHTTPトリガーで実行される関数
    21
    22func HelloWorld(w http.ResponseWriter, r *http.Request) {
    23    // CORSヘッダーの設定
    24    w.Header().Set("Access-Control-Allow-Origin", "*")
    25    w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
    26    w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
    27    w.Header().Set("Content-Type", "application/json")
    28
    29    // OPTIONSリクエストの処理
    30
    31    if r.Method == "OPTIONS" {
    32        w.WriteHeader(http.StatusOK)
    33        return
    34    }
    35
    36    var requestData RequestData
    37
    38    // POSTリクエストの場合、JSONボディを解析
    39
    40    if r.Method == "POST" {
    41        if err := json.NewDecoder(r.Body).Decode(&requestData); err != nil {
    42            http.Error(w, "Invalid JSON", http.StatusBadRequest)
    43            return
    44        }
    45    } else {
    46        // GETリクエストの場合、クエリパラメータから取得
    47        requestData.Name = r.URL.Query().Get("name")
    48        requestData.Message = r.URL.Query().Get("message")
    49    }
    50
    51    // デフォルト値の設定
    52    if requestData.Name == "" {
    53        requestData.Name = "World"
    54    }
    55    if requestData.Message == "" {
    56        requestData.Message = "Hello from Google Cloud Functions!"
    57    }
    58
    59    response := ResponseData{
    60        Status:  "success",
    61        Data:    requestData,
    62        Service: "Google Cloud Functions",
    63    }
    64
    65    if err := json.NewEncoder(w).Encode(response); err != nil {
    66        log.Printf("Error encoding response: %v", err)
    67        http.Error(w, "Internal Server Error", http.StatusInternalServerError)
    68        return
    69    }
    70}

    デプロイ方法

    **gcloud functions deploy**コマンド一発でソースコードからデプロイできる手軽さが魅力です。

    注意: Go Modulesを使用している場合は、go.modgo.sumファイルがプロジェクトルートに配置されていることを確認してください。プライベートリポジトリの依存関係がある場合は、vendoringの使用を検討してください。

    ローカルテスト:

    bash
    1# Functions Frameworkを使用したローカルテスト
    2
    3go mod init my-function
    4go get github.com/GoogleCloudPlatform/functions-framework-go/funcframework@latest
    5go mod tidy
    6
    7# ローカルサーバーを起動
    8
    9export FUNCTION_TARGET=HelloWorld
    10go run main.go
    11
    12# 別ターミナルでテスト
    13
    14curl http://localhost:8080

    Functions Framework使用時の完全な例:

    go
    1package main
    2
    3import (
    4    "encoding/json"
    5    "log"
    6    "net/http"
    7    "os"
    8
    9    "github.com/GoogleCloudPlatform/functions-framework-go/funcframework"
    10)
    11
    12type RequestData struct {
    13    Name    string `json:"name"`
    14    Message string `json:"message"`
    15}
    16
    17type ResponseData struct {
    18    Status  string      `json:"status"`
    19    Data    RequestData `json:"data"`
    20    Service string      `json:"service"`
    21}
    22
    23func HelloWorld(w http.ResponseWriter, r *http.Request) {
    24    // CORSヘッダーの設定
    25
    26    w.Header().Set("Access-Control-Allow-Origin", "*")
    27    w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
    28    w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
    29    w.Header().Set("Content-Type", "application/json")
    30
    31    // OPTIONSリクエストの処理
    32    
    33    if r.Method == "OPTIONS" {
    34        w.WriteHeader(http.StatusOK)
    35        return
    36    }
    37
    38    var requestData RequestData
    39
    40    // POSTリクエストの場合、JSONボディを解析
    41
    42    if r.Method == "POST" {
    43        if err := json.NewDecoder(r.Body).Decode(&requestData); err != nil {
    44            http.Error(w, "Invalid JSON", http.StatusBadRequest)
    45            return
    46        }
    47    } else {
    48        // GETリクエストの場合、クエリパラメータから取得
    49        requestData.Name = r.URL.Query().Get("name")
    50        requestData.Message = r.URL.Query().Get("message")
    51    }
    52
    53    // デフォルト値の設定
    54    if requestData.Name == "" {
    55        requestData.Name = "World"
    56    }
    57    if requestData.Message == "" {
    58        requestData.Message = "Hello from Google Cloud Functions!"
    59    }
    60
    61    response := ResponseData{
    62        Status:  "success",
    63        Data:    requestData,
    64        Service: "Google Cloud Functions",
    65    }
    66
    67    if err := json.NewEncoder(w).Encode(response); err != nil {
    68        log.Printf("Error encoding response: %v", err)
    69        http.Error(w, "Internal Server Error", http.StatusInternalServerError)
    70        return
    71    }
    72}
    73
    74func main() {
    75    funcframework.RegisterHTTPFunction("/", HelloWorld)
    76    port := "8080"
    77    if p := os.Getenv("PORT"); p != "" {
    78        port = p
    79    }
    80    log.Fatal(funcframework.Start(port))
    81}

    必要なモジュール取得:

    bash
    1go get github.com/GoogleCloudPlatform/functions-framework-go/funcframework

    デプロイ:

    bash
    1# ===== 1st Gen(レガシー/維持運用用)=========================
    2#   1st Gen で利用できる最新 Go は 1.21
    3gcloud functions deploy go-cloud-function \
    4  --region=asia-northeast1 \
    5  --runtime=go121 \
    6  --trigger-http \
    7  --entry-point HelloWorld \
    8  --allow-unauthenticated
    9  
    10  # ===== 2nd Gen(推奨)========================================
    11#   Go 1.23 ランタイムで HTTP 関数をデプロイ
    12
    13gcloud functions deploy go-cloud-function \
    14  --gen2 \
    15  --region=asia-northeast1 \
    16  --runtime=go123 \      # ← 最新 GA。go122 も利用可
    17  --trigger-http \
    18  --entry-point HelloWorld \
    19  --allow-unauthenticated \
    20  --set-env-vars KEY1=value1,KEY2=value2
    21
    22# ランタイム候補を確認(必ず実行して最新状況を把握)
    23gcloud functions runtimes list --gen2
    24# デプロイ状況の確認
    25gcloud functions describe go-cloud-function

    最新のGoランタイムサポート状況については、Cloud Functions公式ドキュメントをご確認ください。2025年6月時点では、Go 1.23もサポートされているため、--runtime go123の使用も可能です。

    注意: ランタイムバージョンは頻繁に更新されるため、デプロイ前に以下のコマンドで最新のサポート状況を確認してください:

    bash
    1# 利用可能なランタイム一覧を確認
    2gcloud functions runtimes list

    運用のヒント: 本番環境では、Cloud BuildやGitHub Actionsを使ったCI/CDパイプラインの構築、Secret Managerを使った機密情報の管理、VPCコネクタを使った内部リソースへの安全なアクセスなども検討してください。

    CI/CD例(GitHub Actions):

    yaml
    1# .github/workflows/deploy.yml
    2name: Deploy to Cloud Functions
    3on:
    4  push:
    5    branches: [main]
    6jobs:
    7  deploy:
    8    runs-on: ubuntu-latest
    9    steps:
    10      - uses: actions/checkout@v4
    11      - uses: google-github-actions/auth@v2
    12        with:
    13          credentials_json: ${{ secrets.GCP_SA_KEY }}  # GitHub SecretsにGCPサービスアカウントJSONを登録
    14      - uses: google-github-actions/setup-gcloud@v2
    15      - run: |
    16          gcloud functions deploy go-cloud-function \
    17            --runtime go123 \
    18            --trigger-http \
    19            --entry-point HelloWorld \
    20            --allow-unauthenticated

    注意: GitHub ActionsでGCPにデプロイする場合は、リポジトリのSecretsにサービスアカウントのJSONキーをGCP_SA_KEYとして登録し、credentials_json: ${{ secrets.GCP_SA_KEY }}で参照してください。サービスアカウントには roles/cloudfunctions.developerroles/iam.serviceAccountUserroles/storage.admin(アーティファクトアップロード用)など、最小権限を付与するよう検討してください。

    Azure Functions編:Visual Studio Codeとの親和性

    特徴

    Azure FunctionsはVisual Studio Codeとの親和性が高く、ローカルでの開発・デバッグが容易です。多様なトリガーに対応しており、エンタープライズ環境での活用に適しています。Goはカスタムハンドラーとしてサポートされます。

    実装例

    function.jsonでの設定と、HTTPトリガーで動作するGo関数のコード例を示します。

    まず、function.jsonファイルを作成します:

    json
    1{
    2  "bindings": [
    3    {
    4      "authLevel": "anonymous",
    5      "type": "httpTrigger",
    6      "direction": "in",
    7      "name": "req",
    8      "methods": ["get", "post"]
    9    },
    10    {
    11      "type": "http",
    12      "direction": "out",
    13      "name": "res"
    14    }
    15  ]
    16}

    次に、Go関数を実装します:

    go
    1package main
    2
    3import (
    4    "encoding/json"
    5    "log"
    6    "net/http"
    7    "os"
    8)
    9
    10// 注意:InvokeRequest/InvokeResponseのフィールドは、Azure Functionsのバージョンや
    11// バインディング設定によって変動するため、必ず公式ドキュメント掲載のスキーマ例を参照してください
    12
    13type InvokeRequest struct {
    14    Data     map[string]json.RawMessage
    15    Headers  map[string]string
    16    Identities []map[string]interface{}
    17    Method   string
    18    Query    map[string]string
    19    Url      string
    20}
    21
    22type InvokeResponse struct {
    23    Outputs     map[string]interface{}
    24    Logs        []string
    25    ReturnValue interface{}
    26}
    27
    28type HttpResponseData struct {
    29    StatusCode int               `json:"statusCode"`
    30    Headers    map[string]string `json:"headers"`
    31    Body       string            `json:"body"`
    32}
    33
    34func azureFunctionHandler(w http.ResponseWriter, r *http.Request) {
    35    var invokeRequest InvokeRequest
    36    
    37    // リクエストボディの解析
    38
    39    if err := json.NewDecoder(r.Body).Decode(&invokeRequest); err != nil {
    40        log.Printf("Error decoding request: %v", err)
    41        http.Error(w, err.Error(), http.StatusBadRequest)
    42        return
    43    }
    44
    45    // HTTPリクエストデータの取得
    46
    47    var requestBody map[string]interface{}
    48    if bodyData, exists := invokeRequest.Data["req"]; exists {
    49        if err := json.Unmarshal(bodyData, &requestBody); err != nil {
    50            log.Printf("Error unmarshaling request body: %v", err)
    51        }
    52    }
    53
    54    // レスポンスデータの作成
    55
    56    responseData := map[string]interface{}{
    57        "message": "Hello from Azure Functions with Go!",
    58        "method":  invokeRequest.Method,
    59        "query":   invokeRequest.Query,
    60        "body":    requestBody,
    61        "service": "Azure Functions",
    62    }
    63
    64    responseBody, _ := json.Marshal(responseData)
    65
    66    httpResponse := HttpResponseData{
    67        StatusCode: 200,
    68        Headers: map[string]string{
    69            "Content-Type": "application/json",
    70        },
    71        Body: string(responseBody),
    72    }
    73
    74    // Azure Functions形式のレスポンス
    75    
    76    invokeResponse := InvokeResponse{
    77        Outputs: map[string]interface{}{
    78            "res": httpResponse,
    79        },
    80        Logs: []string{
    81            "Go function executed successfully",
    82        },
    83    }
    84
    85    w.Header().Set("Content-Type", "application/json")
    86    json.NewEncoder(w).Encode(invokeResponse)
    87}
    88
    89func main() {
    90    listenAddr := ":8080"
    91    if val, ok := os.LookupEnv("FUNCTIONS_CUSTOMHANDLER_PORT"); ok {
    92        listenAddr = ":" + val
    93    }
    94
    95    http.HandleFunc("/api/GoFunction", azureFunctionHandler)
    96    log.Printf("Go server listening on %s", listenAddr)
    97    log.Fatal(http.ListenAndServe(listenAddr, nil))
    98}

    デプロイ方法

    Azure Functions Core Toolsfuncコマンド)を使ったデプロイ手順を解説します。

    注意: カスタムハンドラーを使用する場合は、host.jsoncustomHandlerの設定が必要です。また、InvokeRequest/InvokeResponseの正確なスキーマについては、Azure Functions公式ドキュメントをご参照ください。

    bash
    1# Azure Functions プロジェクトの初期化
    2func init --worker-runtime custom
    3
    4# host.jsonの設定例(customHandlerの指定)
    5# 注意:最新のAzure Functions Core Toolsではhost.jsonのschemaが更新されている可能性があるため、
    6# 公式ドキュメントのサンプルを都度確認してください
    7# {
    8#   "version": "2.0",
    9#   "logging": {
    10#     "applicationInsights": {
    11#       "samplingSettings": {
    12#         "isEnabled": true
    13#       }
    14#     }
    15#   },
    16#   "customHandler": {
    17#     "defaultExecutablePath": "handler",
    18#     "arguments": []
    19#   }
    20# }
    21
    22# Goバイナリのビルド(バイナリサイズ最適化)
    23CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o handler main.go
    24
    25# ローカルでの実行
    26func start
    27
    28# Azureへのデプロイ(事前にリソースグループとFunction Appの作成が必要)
    29func azure functionapp publish your-function-app-name

    Azure リソース作成例:

    bash
    1# リソースグループの作成
    2az group create --name myResourceGroup --location japaneast
    3
    4# ストレージアカウントの作成
    5az storage account create \
    6  --name mystorageaccount \
    7  --resource-group myResourceGroup \
    8  --location japaneast \
    9  --sku Standard_LRS
    10
    11# Application Insightsの作成
    12az monitor app-insights component create \
    13  --app MyFuncAppInsights \
    14  --resource-group myResourceGroup \
    15  --location japaneast
    16
    17# Function Appの作成(Consumption プラン)
    18# 注意:最新のCLIオプションは公式ドキュメントで確認してください
    19az functionapp create \
    20  --resource-group myResourceGroup \
    21  --consumption-plan-location japaneast \
    22  --runtime custom \
    23  --functions-version 4 \
    24  --name my-go-function-app \
    25  --storage-account mystorageaccount \
    26  --os-type Linux
    27
    28# 例: マネージドIDを自動付与する場合
    29# az functionapp create \
    30#   --resource-group myResourceGroup \
    31#   --consumption-plan-location japaneast \
    32#   --runtime custom \
    33#   --functions-version 4 \
    34#   --name my-go-function-app \
    35#   --storage-account mystorageaccount \
    36#   --os-type Linux \
    37#   --assign-identity
    38
    39# Application Insightsの接続設定
    40# 注意:最新では APPLICATIONINSIGHTS_CONNECTION_STRING 環境変数を設定するケースがあるので、公式ドキュメントを確認してください
    41az functionapp config appsettings set \
    42  --name my-go-function-app \
    43  --resource-group myResourceGroup \
    44  --settings APPINSIGHTS_INSTRUMENTATIONKEY=$(az monitor app-insights component show --app MyFuncAppInsights --resource-group myResourceGroup --query instrumentationKey -o tsv)
    45
    46# Connection String を使用する場合の例:
    47# az functionapp config appsettings set \
    48#   --name my-go-function-app \
    49#   --resource-group myResourceGroup \
    50#   --settings APPLICATIONINSIGHTS_CONNECTION_STRING="<接続文字列>"

    セキュリティと運用: 本番環境では、Managed Identityを使った認証、Key Vaultを使った機密情報の管理、適切なプラン選択(Consumption vs Premium)によるコスト最適化なども重要な検討事項です。

    モニタリングとログ: Application Insightsを有効にすることで、関数の実行状況、パフォーマンスメトリクス、エラーログを詳細に監視できます。また、Azure DevOpsやGitHub Actionsを使ったCI/CDパイプラインの構築により、継続的なデプロイメントも実現できます。

    3大クラウドサーバーレス比較まとめ

    各プラットフォームの特徴を一目で理解できるよう、比較表を提示します。

    比較軸AWS LambdaGoogle Cloud FunctionsAzure Functions
    プログラミングモデル専用SDK (aws-lambda-go)標準http.HandlerFuncカスタムハンドラー (function.json + HTTP サーバ)
    デプロイ単位ZIP (bootstrap バイナリ) / コンテナイメージ (ECR)ソースコード / ZIP / コンテナイメージ (Artifact Registry)ソースコード / ZIP / コンテナ(Azure Container Registry 経由)
    エコシステム非常に広大で成熟GCPサービス群と強力連携Microsoftエコシステムと親和性高
    Goサポートの歴史長い長い比較的新しい(Custom Handler)
    コールドスタート対策Provisioned Concurrency・Lambda Extensions2nd Gen では常駐インスタンス(同時実行数設定でウォームアップ数確保)Premium プラン・Always On機能(Consumption プランでは限定的)
    開発体験AWS SAM/CDK豊富シンプルで直感的・2nd Gen推奨(VPCコネクタ改善・課金モデル最適化)VS Code統合が優秀

    Go × サーバーレス実践のコツ

    シングルバイナリの活用

    Goの最大の利点であるシングルバイナリを活用し、不要なファイルを含めずコンパイル後のバイナリのみをデプロイすることで、起動時間を大幅に短縮できます。ビルド時にCGO_ENABLED=0を指定することで、静的リンクされたバイナリを生成し、依存関係の管理も簡素化され、デプロイパッケージのサイズも最小限に抑えられます。

    注意: 外部Cライブラリを使う場合はCGO_ENABLEDを使えないケースがあるため、その場合は別途対応が必要です。CGO必須の場合は交差コンパイルの設定や、動作環境向けのビルド環境整備(例えばコンテナ内ビルドなど)を検討してください。

    コールドスタート対策

    依存関係を最小限に保つことが重要です。重いライブラリの初期化は関数の外で行い、AWS LambdaのProvisioned ConcurrencyやLambda Extensionsなどの機能を活用してコールドスタートを回避しましょう。Lambda Extensionsでは、OpenTelemetryの初期化やシークレット取得などの処理をサイドカー的に先行実行できます。また、接続プールの適切な管理により、データベース接続のオーバーヘッドも削減できます。

    注意: Extensionsの実装は事前に動作検証が必要。Cold Startを減らすためのテクニックは様々だが、過度な最適化がかえってコスト増加となる場合もあるので注意してください。

    Google Cloud Functionsでは2nd Genの常駐インスタンス機能を活用し、Azure Functionsでは、バイナリサイズの最適化(不要なライブラリの除去)とPremium プランでのAlways On機能が特に効果的です。

    環境変数での設定管理

    12-Factor Appの原則に従い、設定をコードから分離することが重要です。APIキー、データベース接続文字列、外部サービスのエンドポイントなどは環境変数で管理し、各クラウドプラットフォームの暗号化機能(AWS KMS、Google Secret Manager、Azure Key Vault)を活用してセキュリティを確保しましょう。ローカル開発時は、godotenvなどのライブラリを活用して設定ファイルを管理することも検討してください。

    セキュリティ注意: 本番環境では.envファイルをリポジトリにコミットしないよう注意し、機密情報は必ずクラウドのシークレット管理サービスを使用してください。

    モニタリング・ログ管理

    本番環境では適切なモニタリングとログ管理が不可欠です。構造化ログ(JSON形式)での出力を推奨し、トレーシング情報を含める場合はOpenTelemetry Go SDKの活用も検討してください。

    構造化ログライブラリ例: Zap、Zerolog、slog(Go 1.21+)などの高性能ログライブラリの活用を検討してください。OpenTelemetryの簡易セットアップ例については公式ドキュメントや関連記事を参照してください。

    • AWS: CloudWatch LogsとCloudWatch Metricsを活用し、構造化ログ(JSON形式)での出力を推奨
    • GCP: Cloud LoggingとCloud Monitoringで関数の実行状況を監視、ログレベルの適切な設定
    • Azure: Application InsightsとAzure Monitor Logsを有効化し、パフォーマンスメトリクスとエラー追跡を実装

    セキュリティのベストプラクティス

    最小権限の原則に従ったアクセス制御を実装しましょう。

    • AWS: Lambda実行ロールには必要最小限の権限のみを付与、マネージドポリシーやカスタムポリシーの分割管理を推奨。VPC内配置時はENI初期遅延とセキュリティグループ管理に注意
    • GCP: Cloud Functions実行時のサービスアカウントに必要最小限の権限を設定、IAMロールの適切な管理
    • Azure: Managed IdentityとKey Vault連携時の権限設定、Function Appのアクセス制御設定

    テスト戦略

    サーバーレス関数の品質を保つため、包括的なテスト戦略を採用しましょう。

    • ユニットテスト: ハンドラ関数のロジック部分を分離してテスト
    • 統合テスト: LocalStack(AWS)、Functions Framework(GCP)、Azure Functions Core Tools(Azure)などのエミュレータを活用
    • E2Eテスト: CI/CDパイプラインでの自動テスト実行、本番環境に近い条件でのテスト

    注意: LocalStack等で動作確認する際は、本番環境とバージョン差異・挙動差異がある可能性を理解したうえで利用してください。

    まとめ:クラウドを味方につけ、価値の高いエンジニアへ

    どのクラウドプラットフォームもGoをサーバーレスで実行するための強力な基盤を提供しており、最終的な選択は既存の技術スタックや要件に依存します。AWS Lambdaは豊富な機能と成熟したエコシステム、Google Cloud Functionsは標準ライブラリとの親和性とシンプルさ、Azure FunctionsはMicrosoftエコシステムとの統合性がそれぞれの強みです。

    サーバーレスアーキテクチャとクラウドネイティブ技術への習熟は、現代のGoエンジニアにとって必須のスキルセットです。これらの技術を身につけることで、スケーラブルで保守性の高いアプリケーションを効率的に開発できるようになり、市場価値の高いエンジニアとして活躍できるでしょう。

    私たちGoForceは、このようなモダンな開発スキルを持つフリーランスエンジニアと、彼らの力を求める先進的なプロジェクトを繋ぐことに特化しています。あなたのクラウドスキルを、次の挑戦で活かしませんか。ぜひ一度、私たちにご相談ください。

    次のステップは行動です。
    🔗 Go × サーバーレス案件を探す ▶ GoForce
    今すぐチェックして自分の市場価値を確認しましょう。

    会員登録はこちら

    最適なGo案件を今すぐチェック!

    会員登録

    生年月日 *

    /

    /

    Go経験年数 *

    /

    利用規約プライバシーポリシーに同意してお申し込みください。