Diary of a Perpetual Student

Perpetual Student: A person who remains at university far beyond the normal period

lambroll を GitHub Actions で動かすときには明にバージョンを指定しよう

3行

  • lambroll を GitHub Actions 上で実行するには fujiwara/lambroll@v0 が使える
  • input に lambroll の version があるが必ず明に指定しよう
  • そうしないと、default 値として古い lambroll で動いてしまう
- uses: fujiwara/lambroll@v0
  with:
    version: v0.14.2 # <- ココ省略しない!

本文

前置き

前回のエントリ

blog.arthur1.dev

の最後にちらっと紹介した新生アグリコラカードデータベース API

github.com

この API を動かすインフラとして、 AWS Lambda + Amazon API Gateway 構成を選択した。

このあたりの話はまたいつかするとして、この Lambda の deploy を GitHub Actions 上で lambroll を実行することで行っている、というのが本題だ。lambroll は、シンプルに Lambda の deploy と rollback を行えるツールである。

github.com

sfujiwara.hatenablog.com

lambroll on GitHub Actions が動かない…

lambroll を GitHub Actions で利用したいときには、 use 一発でインストールができる action fujiwara/lambroll@v0 が用意されているのでこれを使うとよい。

  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: aws-actions/configure-aws-credentials@v2
        with:
          role-to-assume: arn:aws:iam::0123456789:role/github-actions-role
          aws-region: ap-northeast-1
      - uses: fujiwara/lambroll@v0
      - name: deploy Lambda
        run: |
          lambroll --function ./function.jsonnet --region=ap-northeast-1 \
          --tfstate s3://sample-terraform-states/terraform_states.tfstate deploy

ということで、上のように GitHub Actions の workflow yaml を書いて実行してみたのだが、以下のようなエラーになってしまい deploy ができなかった。

Error: 2023/03/28 0000:00 [error] failed to read tfstate: s3://sample-terraform-states/terraform_states.tfstate: open s3://sample-terraform-states/terraform_states.tfstate: no such file or directory

lambroll には terraform の tfstate に含まれる値を読む機能がついていて、定義ファイルで利用することができる。今回は関数名や ECR のイメージ URI、実行ロールの arn を tfstate から取得するようにしていた。

{
  FunctionName: '{{ tfstate `aws_lambda_function.server.function_name` }}',
  MemorySize: 256,
  Architectures: [
    'arm64'
  ],
  Timeout: 7,
  Role: '{{ tfstate `aws_iam_role.server.arn` }}',
  PackageType: 'Image',
  Code: {
    ImageUri: '{{ tfstate `aws_lambda_function.server.image_uri` }}'
  },
}

S3 などに置いた remote state を読むこともできて、そのためにオプション --tfstate s3://sample-terraform-states/terraform_states.tfstate をつけていた。しかし、エラーメッセージを見るに、この URL で指定しているものがローカルのファイルだと誤認識されているようだ。

解決策: version を明に指定

自分の手元環境でこのコマンドを叩くと正常に deploy できていたので、GitHub Actions のための IAM ロールの設定が間違っているのかなあといろいろ試行錯誤していた。最終的に lambroll の実装を見に行くかとソースコードを読みに行ったところ、解決の手がかりを見つけた。

https://github.com/fujiwara/lambroll/blob/94d3c71cdc46645ade1a97ec29f5a0f7190ef701/action.yml#L1-L4

上記のコードを見ると、version という input があることと、そのデフォルト値が v0.10.0 であることが分かる。このエントリ執筆時の lambroll の最新版は v0.14.2 なので、デフォルト値はそれなりに古いということになる。

そして、 v0.10.0 の時点では S3 に置いた remote state を読む機能がまだ実装されていなかったので、上に示したようなエラーが出てしまった、というわけだ。version を指定できることは知っていたが、未指定の場合は最新版が使われると勝手に思いこんでいた。

ちなみに、コードを見る限りでは、仮に uses: fujiwara/lambroll@v0.14.2 としたしても、デフォルトのバージョン値に影響は与えない。

おまけ: setup-go の観察

デフォルトが最新版だと勘違いした原因は、公式で用意されている actions/setup-*** 系の action がバージョン未指定でもちゃんと最新版で動くと思いこんでいたことにある。

試しに、actions/setup-go でバージョンを指定しなかった場合、どのような仕組みで動作するのかを追ってみた。

https://github.com/actions/setup-go/blob/8dbf352f069be09d9a0b567cc1a9d16a5663fc3a/src/main.ts#L14C6-L59

このあたりのコードを読むと分かる。最新の、というよりは GitHub Actions の実行環境にプリインストールされている go のバージョンが使用されるとようだ。(ということは lambroll action の仕様を勘違いした理由がそもそも嘘だったということになる。)

試しに、version を指定せず go version してみたところ、

go version go1.18.10 linux/amd64

と返ってきた。別に最新ではないし Go 1.20 が出たのでサポートも切れているバージョンのはず。

lambroll に限らず、こういった setup 系の action ではできる限りバージョンを明に指定したほうがよさそうだ。