Blog

Goで実装した複数のバッチを効率よくGitHub Actionsでデプロイする方法

この記事は、リレーブログ企画「CI/CD」の記事です。

はじめに

ニフティでWEBサービスの開発・運用を担当している渡邊です。

Goで実装した複数のバッチをAWS Lambdaにデプロイする機会があったので、そのときに実装した内容を紹介していきます。

構成

GitHub Actionsを使ってデプロイを実装しています。

Lambdaはコンテナベースでバッチを管理し、GitHub ActionsによってECRへプッシュします。

通常、LambdaをECRのプッシュをトリガーに自動更新すにはEventBridgeが必要ですが、今回は管理を簡素化するため、Lambdaの更新もGitHub Actionsで直接行うことにしました。

ディレクトリ構成

以下のようなディレクトリ構造でバッチを実装することを想定します。

cmd/ディレクトリの下に、各バッチのメインロジックがそれぞれのディレクトリに配置される構成です。

各バッチディレクトリにDockerfileを設置し、それぞれのロジックが独立したLambda(バッチ)として実行されます。

.github内にデプロイを行うワークフローを配置しています。

Dockerfileの中身

ワークフロー

今回は例として3つのバッチを作成するようになっていますが、実際に運用するときは数十個以上のバッチを管理することもあります。そのため、GitHub Actionsのワークフローは再利用できるように作っていきます。

さらに、今回の構成では Arm64 向けにビルドすることで、実行環境でのパフォーマンス向上を目指します。

ワークフローを作る前に、リポジトリに以下の設定が必要です。

  • AWS_ACCESS_IAM_ROLE
    • AWSへのアクセスをOIDCで行うため
    • AWS_REGION
      • ECRとLambdaをデプロイするリージョン
    • AWS_ECR_REGISTRY_URI
      • ECRのレジストリURI

まず、ECRへイメージをプッシュするワークフローを作ります。

ARM64で動くバッチにするための方法を2パターン紹介します。

ビルド

Linux x86_64で動かす場合

GitHub Actions のデフォルトの実行環境は Linux x86_64 です。そのため、Arm64 向けにビルドを行うには クロスコンパイルが必要になります。

Go の場合、公式にクロスコンパイルがサポートされているため、環境変数を指定することで比較的簡単に Arm64 向けのバイナリを作成できます。

また、Docker イメージのように OS/アーキテクチャが密接に関係する場合には、QEMU(マルチプラットフォームイメージのビルド)を用いたエミュレーションとDocker Buildxを使ってマルチアーキテクチャ対応のビルドを行う方法が有効です。

以下がワークフローの処理になります。

メリット

  • GitHub Actionsの毎月の無料利用枠内で実行できるため、コストを抑えられる

デメリット

  • QEMUを使用してArm64環境をエミュレートするため、ネイティブのArm64環境でのビルドと比べて処理が遅くなる

Arm64ランナーを使う場合

2024/06/03にGitHub ActionsにArm64ランナーが追加されました。

そのため、QEMUが不要になり、直接ビルドを行えるようになりました。

以下がQEMUを使わないワークフローになります。

パブリックリポジトリの場合はubuntu-24.04-armを、プライベートリポジトリの場合はArm64のランナーを作成して指定します。

メリット

  • QEMUを使っていないため、より高速にビルドを行える

デメリット

  • プライベートリポジトリではLarge Runner扱いのため、無料利用枠外の扱いになってしまう(2025/04/02現在)

Lambdaへのデプロイ

aws cliを使ってLambdaファンクションを更新します。

メイン処理

先ほど作成した再利用可能なワークフローを呼び出します。

Dockerのイメージ名とファイルパスを指定し、各バッチごとにこの設定を作成することでデプロイ環境が完成します。

実行

今回は特定ブランチへのpushをトリガーとしてワークフローが実行されるように設定しました。

以下が、実際にデプロイした際の実行結果です。

QEMUを使った場合

Arm64ランナーを使った場合

検証に使ったバッチでは、Arm64ランナーを使うことで処理が少し速くなりました。

コードの大きさによってはもっと大きな差が出てくると思います。早くプライベートリポジトリでも無料利用枠ないで使えるようになるといいですね。

最後に

今回はGoで作成したバッチをLambdaに効率よくデプロイする方法を紹介しました。

GitHub Actionsは再利用可能なワークフローを作成することができるので、今回のようなデプロイ先が違うだけで、内部処理が一緒の場合は非常に役立ちます。

また、今回のように複数のバッチをコンテナベースで管理することで、環境の統一性が保たれ、メンテナンス性も向上します。

次回は、IWS さんです。
今回と同じくGitHub Actionsを使ったデプロイ方法を紹介してくれるようなので、楽しみです!

ニフティでは、
さまざまなプロダクトへ挑戦する
エンジニアを絶賛募集中です!
ご興味のある方は以下の採用サイトより
お気軽にご連絡ください!

ニフティに興味をお持ちの方は
キャリア登録をぜひお願いいたします!

connpassでニフティグループに
参加いただくと
イベントの
お知らせが届きます!