
初めまして。crowdworks.jpのSREチームに所属しています @ciloholic です。
入社してかれこれ1年経ちますが、筆を執る機会がなかったため、今回が初エンジニアブログとなります。
この記事では、入社して3か月ほど行なっていた「AWS Lambda周りのメンテナンスコスト削減」の取り組みを紹介していきます。
背景
crowdworks.jpでは、多くのエンジニアがさまざまなGitHubリポジトリに色々な言語でLambdaを活用してきました。GitHubリポジトリは30個以上、使用言語はNode.js / Ruby / Goとさまざま、CI/CDもCircleCI / GitHub Actionsとバラバラです。
SREチームでは、定期的に各種言語のEOL対応やライブラリのアップデート作業を行なっているのですが、GitHubリポジトリもそれぞれ異なる、使用言語もCI/CDもバラバラだったので、メンテナンスコストが多くかかっていました。
問題点と解決策
上記のような背景があり、Lambda周りで多くの問題が発生していたため、それぞれの問題に対する解決策を練ることにしました。
(1)乱立したGitHubリポジトリ
GitHubリポジトリが多いとメンテナンスが困難になるため、まとめられるGitHubリポジトリは1つにまとめるようにしました。いわゆる、モノレポ構成です。
(2)バラついてる使用言語
大半のLambdaがGoで書かれていたこともあり、できるだけGoに寄せるようにしました。一部はNode.jsやRubyで実装されていますが、書き換えコストが高かったため、今後の課題としています。
Ruby3.2のLambdaランタイムが遅くとも2023年6月末頃とのコメントがあったので、もしかしたらGoへの書き換えではなく、Ruby3.2のLambdaランタイムへの移行になるかもしれません。
(3)バラついてるCI/CD
CI/CDでそこまで複雑な処理をしていない、かつ、GitHubとCircleCIを連携させるメリットも無いので、GitHub Actionsに寄せるようにしました。
2023年3月時点で、最近ではGitHub Actions Importerという移行ツールが登場しているため、より簡単に移行できるようになりました。
(4)バラついてるデプロイツール
古くからLambdaをデプロイしている場合、デプロイツールも時代によって移り変わります。
crowdworks.jpでは、ApexやServerless Frameworkが使用されていました。Apexは現在だとアーカイブされていたり、Serverless Frameworkは裏でAWS CloudFormationを使用していてTerreformとの相性が悪かったりと問題が多くあったため、よりシンプルなLambdaのデプロイツールである「lambroll」に統一することにしました。
結果
途中で色々試行錯誤しましたが、最終的に落ち着いたモノレポ構成です。
. ├── .github │ ├── actions │ │ ├── deploy │ │ ├── deploy_go │ │ └── deploy_ruby │ └── workflows │ ├── lambda_1_deploy_production.yml │ └── lambda_2_deploy_production.yml ├── .lambroll-version ├── lambda_1 └── lambda_2
lambrollのバージョン
lambrollのバージョンを変更しやすくするため、.lambroll-versionに記載しています。GitHub Actions内では、.lambroll-versionを参照するようにしています。
├── .lambroll-version => 0.14.2(2023年3月時点で最新)
デプロイのワークフロー
デプロイのワークフローについて、下記にサンプルコードを載せています。詳細はサンプルコード内のコメントに記載しています。
# .github/workflows/lambda_1_deploy_production.yml
name: deploy production
permissions:
contents: read
id-token: write
on:
push:
branches:
- main
paths:
# lambda_1の変更をトリガーに起動する
- 'lambda_1/**'
- '!lambda_1/README.md'
# デプロイが連続で起動しないように同時デプロイを禁止しています
# https://docs.github.com/ja/actions/using-jobs/using-concurrency
concurrency:
group: lambda-1-deploy-production
jobs:
deploy_production:
runs-on: ubuntu-latest
timeout-minutes: 5
environment:
name: production
steps:
- uses: actions/checkout@v3
# Lambdaのデプロイは、処理内容が共通だったため、Composite Actionに切り出しています
# https://docs.github.com/ja/actions/creating-actions/creating-a-composite-action
# GoやRubyは、言語ごとにビルドや前処理が異なるため、Composite Actionを分けて作成しています
- name: deploy
uses: ./.github/actions/deploy
with:
working-directory: lambda_1
app-name: lambda-1
stage: production
aws-account-id: 123456789
# .github/actions/deploy/action.yml
name: deploy
permissions:
contents: read
id-token: write
inputs:
working-directory:
required: true
description: 作業ディレクトリの指定
app-name:
required: true
description: アプリケーション名
stage:
required: true
description: デプロイ先の環境名
aws-account-id:
required: true
description: デプロイ先のAWSアカウントID
runs:
using: composite
steps:
# .lambroll-versionのバージョンを取得する
- name: set environment variables
shell: bash
run: echo "LAMBROLL_VERSION=v`cat .lambroll-version`" >> $GITHUB_ENV
# AWSへのアクセスは、OIDC認証を使用しています
# https://docs.github.com/ja/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services
- name: configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-region: ap-northeast-1
role-to-assume: arn:aws:iam::${{ inputs.aws-account-id }}:role/${{ inputs.app-name }}-${{ inputs.stage }}-deploy
role-session-name: github-actions-${{ github.run_id }}
# lambrollは、公式で配布されているアクションを使用しています
# https://github.com/fujiwara/lambroll#github-actions
- uses: fujiwara/lambroll@v0
with:
version: ${{ env.LAMBROLL_VERSION }}
- name: deploy
shell: bash
working-directory: ${{ inputs.working-directory }}
run: デプロイ処理は省略
最後に
今回の対応以前は、デプロイツールが古過ぎてデプロイできない、また長らく触っていなかったため、ビルドが失敗するなどの事故が多発していましたが、今回の対応によりかなり改善できたと思います。すべてのLambdaをGoにする課題が残っているので、まだまだ改善活動を続けていく所存です。
We're hiring!
crowdworks.jpでは、サービスが持続的に成長するために改善し続けるエンジニアを募集しています! ご興味ある方は、ぜひお気軽にご連絡ください。