大量にある社内の CI/CD 未整備な小規模アプリを SKILLS でなんとかしたい

記事タイトルとURLをコピーする

こんにちは。自称ソフトウェアエンジニアの橋本 (@hassaku_63)です。

ちょっとした社内システム間連携の用途で大量に作られた(似たような構成の)小規模アプリがあり、それらのほとんどが手元に AWS クレデンシャルを必要とする原始的なデプロイしかサポートしていない状況を改善するべく試してみた、という主旨の記事を書きます。

きちんと検証の数をこなしたわけではないので精度は担保しかねるのですが、各々の環境・状況に当てはめてマイナーチェンジしてみたら良いのではないでしょうか、ということでアイデアの投稿をしてみます。

前提

当社では、社内の SaaS 間の連携をするために必要な、小さい Lambda Function (+α) が多く作られています。

開発している人も部署も、それらの開発当時とは状況が異なります。とりあえず今は私がある程度見ることになってはいますが、業務的にクリティカルではないものがほとんどで、かつ他にも面倒見るべき重要なシステムがあるので、それの細かいコードベースについてあまり時間を掛けていられない、という状況が長らく続いていました。

それらの多くは Serverless Framework (v3) と Python を使っていて、作成するリソースは Lambda Function と何か、という感じの構成になっています。Serverless Framework v3 はすでに EoL していて、メジャーバージョンアップなり別の IaC に載せ替えるなりの対応が必要です。個人的には全部 CDK に置き換えたいのですが、数の問題で対応しきるには時間がかかるので、当座の対応として OSS 版にあたる oss-serverless への移行を行っていました。順次ベストエフォートで整備なり移植なり、最低限の EoL 対応なりをしていて、だましだまし回しているような状況でした。

デプロイ方法は手元のマシンから deploy コマンドを直接叩くしかないものがほとんどです。当然これはあまりよろしくないのですが、メンテナとしてアクティブに触る人が他にいるわけでもないので半ば黙認しているような状況にありました。

しかし、ありがたいことに、最近になって開発系のロールとしてレポジトリに関与するメンバーが増える機運が出てきました。

さすがに共用アカウントのクレデンシャルを手元に持たねばデプロイできない運用を(複数名体制で)放置するわけにもいかないので、自分以外のメンバーが触りうるレポジトリに限定しつつ順次 CI/CD を整備し、ローカルPC が共用アカウントのクレデンシャルを持たずに済むような仕組みに変えていく必要が出てきました。

幸い(?)にも対象となりえるアプリは全部似たような構成なので、だったら SKILLS として典型的な実装のやり方を残しておけばよかろう、と思いました。このやり方であれば、私が離任してもノウハウが残りますし、対象の全レポジトリのローラー作戦が完遂できていなくても問題ありません。SKILL さえ入れればいつでも着手可能です。

想定条件

達成すべきゴールは「手元に共用アカウントのクレデンシャルを持たなくてもデプロイできる」仕組みを作ることです。これを達成する最も手っ取り早い手段として GitHub Actions を使うことにしました。

いくつかの前提があります。

  • 中長期で見れば、IaC は CDK など他のものに移植する想定がある(よって Serverless Framework 専用の仕組みに大きなコストをかけたくない)
  • 小規模で、業務的にもミッションクリティカルではないものがほとんど
  • デプロイ先となる共用アカウントはごく少数(OIDC Provider など AWS アカウント側で1回だけ実施すればよい作業は自動化の必要性が薄い)

適用対象となりうるレポジトリについても、いくつか前提を置いています。

  • Serverless Framework (or oss-serverless) プロジェクトのデプロイに特化する
  • 定義してあるリソースは Lambda Functions + α の小規模構成。Lambda Runtime は基本的に Python を使っている
  • デプロイ時に、そのアプリ用に宣言した環境変数をセットしておく必要がある
  • Actions によるデプロイ権限の取得に IAM OIDC Provider を利用する。OIDC Provider は設定済みとする

実装

作った SKILL の内容をほぼそのまま貼ります。(当然ながら)このファイル自体も AI (Kiro) に作らせたものです。

gist.github.com

解説

上記の yml は長いので、要約します。要するにこういうことをやっています。

Serverless FrameworkまたはOSS-Serverlessプロジェクト向けに、GitHub Actionsデプロイワークフローを自動生成するスキルです。

プロジェクトのserverless.yml、package.json、.tool-versions等を解析し、Node.js/Pythonバージョン、AWSリージョン、デプロイコマンド、環境変数(${env:}パターン)を自動検出します。

検出した設定値でカスタマイズされた.github/workflows/deploy.ymlを生成し、OIDC認証によりIAMユーザークレデンシャルのローカル配布を不要化します。

ワークフロー生成後は、GitHub EnvironmentsとSecretsの作成(ghコマンド例付き)、IAM Role Trust Policyの更新(リポジトリ許可条件の追加)、必要な権限の確認など、具体的な事後セットアップ手順を提供します

GitHub Actions のワークフローファイルを作成するためには、ベーステンプレート(定数部分)と、プロジェクトごとにバリエーションのある部分(変数部分)をある程度うまく組み合わせる必要がありました。

今回の想定だと、変数部分になるのはだいたい以下のような要素になります。

  • Node.js のバージョン(Serverless Framework の依存関係)
  • Python のバージョン(Lambda Runtime として)
  • 環境変数(デプロイ時または実行環境で参照されるもの)

これらの値は、IaC テンプレート (serverless.yml) などコードベースに存在するファイルたちからある程度収集可能です。ランタイムのバージョンであれば、.tool-versions なども情報源にできます。SKILLS にはできるだけこうした既存ファイルからの情報収集をしてもらうようにしました。

デプロイ時に注入する環境変数は、GitHub の Environment Secrets から供給する形にしました。

レポジトリによっては変数の数 × 環境数で地味に面倒くさいので、gh コマンドを使って必要な Environment と Secret の作成をガイダンスするようにしました。

使ってみた

以下は Actions 作成のリクエストに対する、完了後の Kiro のレスポンスです。長いのでリンクだけ掲載します。

https://gist.github.com/hassaku63/c51476ef069a7dd3492da4fb873c70ec?permalink_comment_id=5994830#gistcomment-5994830

実際に出来上がったものがこちら。

name: Deploy
 
on:
  workflow_dispatch:
    inputs:
      environment:
        description: 'Environment to deploy'
        required: true
        type: choice
        options:
          - dev
          - prod
      branch:
        description: 'Branch to deploy'
        required: false
        default: 'master'
 
permissions:
  id-token: write
  contents: read
 
jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: ${{ inputs.environment }}
    steps:
      - uses: actions/checkout@v6
        with:
          ref: ${{ inputs.branch || 'master' }}
 
      - uses: actions/setup-node@v6
        with:
          node-version: '20'
 
      - uses: actions/setup-python@v6
        with:
          python-version: '3.12'
 
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v6.0.0
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          aws-region: ap-northeast-1
 
      - name: Install dependencies
        run: npm install
 
      - name: Deploy
        run: npx sls deploy --stage ${{ inputs.environment }}

レポジトリの詳細事情まではここでは掲載できませんが、概ねやりたいことがカバーできているな、くらいの感じでした。yml ファイルの見直しもほぼ不要で、そのまま PR にしてしまって差し支えなさそう、ぐらいの感じでした。

まとめ

運用・保守の性格が強い仕事をしているとどうしてもこのような細々したモノがあぶれてしまいます。これらにかかずらって自分の時間の大半を使い潰されるわけにはいかないけど、一方でスタックしすぎると組織にとっても自分のメンタルにも良くないので本音はさっさと一掃したい、のようなジレンマがありました。

AI のパワーでこういった面倒な(しかし技術的には単純な)課題を高い精度でオフロードできるようになってきてますね。個人的には日頃のメンテの一環として済ませておきたい類の活動が追いつかない状況はかなりしんどいので、本当にありがたいです。

この手の技術的要素が単純寄りなタスクなら、AI にかなり信頼して任せられる印象を持っています。私自身の余白を作っていきたいですね。