初めまして。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では、サービスが持続的に成長するために改善し続けるエンジニアを募集しています! ご興味ある方は、ぜひお気軽にご連絡ください。