kakakakakku blog

Weekly Tech Blog: Keep on Learning!

blank-go: Go で動く AWS Lambda 関数に入門しよう

AWS Lambda 関数を Go ランタイムで動かす Hello World レベルの初学者コンテンツを探していて,ドキュメントにも載っている blank-go プロジェクトがお手軽に使えて良かったので紹介したいと思う❗️初学者に教えるときに使えるぞ〜 \( 'ω')/

github.com

ちなみに AWS Lambda に入門するための blank-xxx は Go 以外にも Node.js / Python / Java など多くある❗️

docs.aws.amazon.com

blank-go 紹介

blank-go では AWS CLI を使って Go ランタイムで動く AWS Lambda 関数をデプロイできる.実装としては,Amazon SQS のイベント情報(実際に Amazon SQS キューと連携するのではなく event.json を渡す)や AWS Lambda のコンテキスト情報をログ出力する感じで,Go で AWS Lambda 関数を実装するときのお作法なども参考になる.特にコードを書く必要はなく,準備された Shell を実行していく.試すだけならすぐ終わるし簡単❗️

$ ./1-create-bucket.sh
$ ./2-deploy.sh
$ ./3-invoke.sh

docs.aws.amazon.com

登場する代表的なサービス/リソースは以下など.

  • AWS Lambda(blank-go アプリケーション)
  • Amazon S3(デプロイ用)
  • AWS CloudFormation(AWS SAM デプロイ用)
  • Amazon CloudWatch Logs(AWS Lambda 関数のログ出力用)
  • AWS X-Ray(AWS Lambda サービスと AWS Lambda 関数のトレース用)

ちなみに M1 / M2 など Apple Silicon の macOS で実行すると Lambda 関数の実行時に以下のエラーが出る.今回は MacBook Pro (Apple M1 Max) を使っていて遭遇した.

{"errorMessage":"fork/exec /var/task/main: exec format error","errorType":"PathError"}

その場合は ./2-deploy.shgo build コマンドに GOARCH=amd64 を追加する必要がある.Apple Silicon を使っている人ならすぐ気付くとは思うけど,blank-go は初学者コンテンツなので,手順に書いておくと良さそうでプルリクエストも出しておいた.

$ GOOS=linux GOARCH=amd64 go build main.go

github.com

またお掃除用の 4-cleanup.sh を実行すると AWS Lambda 関連だけではなく Amazon S3 と Amazon CloudWatch Logs も含めてすべて消してくれるので,ゴミが残らないのも良かった👍

$ ./4-cleanup.sh

さらに一歩踏み込む(追加課題)

もし blank-go を使って初学者に AWS Lambda x Go を教えるなら,ただ実行するだけではなく,もう少し視野を広げて体験してもらうのが良さそう❗️追加課題的なものを考えながら実際に試してみた.

1. AWS Lambda 関数をローカル実行してみよう✌️

blank-go のデプロイには AWS SAM が使われているため sam local invoke コマンドを実行すれば AWS Lambda 関数を実環境にデプロイせずにローカル実行できる.

$ sam --version
SAM CLI, version 1.78.0

$ sam build

$ sam local invoke -e event.json
Invoking main (go1.x)
Using local image: public.ecr.aws/lambda/go:1-rapid-x86_64.

START RequestId: f5633c0b-79c7-44e2-bdec-4ba460c7a42a Version: $LATEST
(中略)
END RequestId: f5633c0b-79c7-44e2-bdec-4ba460c7a42a
REPORT RequestId: f5633c0b-79c7-44e2-bdec-4ba460c7a42a  Init Duration: 0.87 ms    Duration: 690.84 ms   Billed Duration: 691 ms    Memory Size: 128 MB    Max Memory Used: 128 MB
"{\"FunctionCount\":1,\"TotalCodeSize\":6399551}"

さらに AWS Toolkit for Visual Studio CodeAWS Toolkit for JetBrains を使えば,エディタ上で AWS Lambda 関数のデバッグをすることもできる.AWS Lambda 関数だと開発体験が悪そう...と言われたりもする懸念の一部は解消できると思う.

2. テストを実行してみよう✌️

blank-go の手順では特に紹介されていないけど,function ディレクトリには main_test.go も含まれていて,Go のテストも実行できる.今回のコードは環境変数 AWS_REGION をログ出力する実装になっているため,以下のように実行すれば OK!

$ cd function
$ AWS_REGION='ap-northeast-1' go test
PASS
ok      github.com/awsdocs/aws-lambda-developer-guide/sample-apps/blank-go  0.484s

ちなみにドキュメントに載っているベストプラクティスに Lambda ハンドラーをコアロジックから分離します。 とあって,もう少し工夫するなら main.gohandleRequest() 関数とコアロジックの依存を減らせばもっとテストしやすくなると思う.とは言え,今回の blank-go ではコアロジックと言える実装がないのでこれはこれで OK!

AWS Lambda 関数を実装するときも今までと同じく「テストのしやすさ」という観点は大切だよね〜❗️というディスカッションに繋げられると良いと思う👍

docs.aws.amazon.com

3. GitHub Actions で自動デプロイをしてみよう✌️

blank-go だと AWS CLI (aws cloudformation deploy コマンドなど)をラップした Shell を使ってデプロイをしてるけど,せっかくなら GitHub Actions で自動デプロイする仕組みを作ってみる.blank-go のコードを抜き出して新しく GitHub リポジトリを作って GitHub Actions ワークフロー (.github/workflows/deploy.yml) を以下のように作る.

name: blank-go

on:
  push:
    branches: master

permissions:
  id-token: write
  contents: read

jobs:
  build:
    name: Deploy
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: aws-actions/setup-sam@v2
      - uses: aws-actions/configure-aws-credentials@v2
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          aws-region: ap-northeast-1
      - run: sam build --use-container
      - run: sam deploy

aws cloudformation deploy コマンドじゃなく sam deploy コマンドを使ってデプロイしたり,AWS IAM 権限を取得するところをアクセスキーではなく OpenID Connect (OIDC) の仕組みを使って一時的な認証情報を使ったりという工夫をしている❗️関連する設定は割愛するけど以下のドキュメントなどに載っている👌

docs.github.com

期待通りに自動デプロイできた〜

4. ドキュメントを調べてみよう✌️

などなど📝

まとめ

AWS Lambda x Go に入門できる Hello World レベルのコンテンツ blank-go「さらに一歩踏み込む追加課題」の紹介でした❗️

github.com