[Serverless Framework]デプロイ時にLambdaの環境変数にコミットIDを含める

2020.09.10

どうも!大阪オフィスの西村祐二です。

個人的にServerless Frameworkを使ってLambdaを管理することが多いです。

日々保守運用していると、Lambda上で動くコードのバグを修正したり、機能追加したり、または切り戻したり、特定のLambdaだけ更新したりなど、全Lambdaが同じバージョンで動いていない状況になるときがあります。

そんな中、何か異常があり調査したいときに、デプロイしたLambdaがどういった状態か確認するときにGitのコミットIDが紐付いていると調査時に役立つときがあります。

そこで今回はデプロイ時にコミットIDを環境変数に含める方法を備忘録を兼ねてブログにしたいと思います。

コミットIDを環境変数に含める方法

早速、結論ですが、

Serverless Frameworkではデプロイ前に設定したJSを実行することができるので、コミットIDを取得するJSを作成し、環境変数に含めます。

JSからコミットIDを取得するサンプルコードです。適時、変更してください。

conf/commitId.js

module.exports.getCommitId = async () => {
  const execSync = require('child_process').execSync;
  const cmd = 'git log -n 1 --format=%H,%cd';
  const result = execSync(cmd).toString().split(',');
  const commitID = result[0];
  return commitID;
};

serverless.ymlは下記のように設定することで外部ファイルのJavascriptを参照することができます。

serverless.yml

.
.
.
provider:
  name: aws
  .
  .
  .
  environment:
    COMMIT_ID: ${file(./conf/commitId.js):getCommitId}
  .
  .
  .

https://www.serverless.com/framework/docs/providers/aws/guide/variables/#reference-variables-in-javascript-files

この状態でデプロイするとLambdaの環境変数にコミットIDが含まれた状態でデプロイされます。

試してみる

環境

Node.js: 12.18.2

Lambdaランタイム:Python3.8

Serverless Framework: 1.82.0

プロジェクト作成

$ mkdir demo
$ cd demo
$ sls create -t aws-python3

ファイル修正

コミットIDを取得するためのJSファイルを作成します。

conf/commitId.js

module.exports.getCommitId = async () => {
  const execSync = require('child_process').execSync;
  const cmd = 'git log -n 1 --format=%H,%cd';
  const result = execSync(cmd).toString().split(',');
  const commitID = result[0];
  return commitID;
};

serverless.ymlを修正します。今回2つのLambda関数を管理することとします。

serverless.yml

service: var-test
frameworkVersion: "1"

provider:
  name: aws
  runtime: python3.8
  region: ap-northeast-1

  environment:
    COMMIT_ID: ${file(./conf/commitId.js):getCommitId}

functions:
  hello:
    handler: handler.hello
  hello2:
    handler: handler.hello

コミット

コミットIDを生成するためにgit commitします。

$ git init
$ git add .
$ git commit -am "first commit"

デプロイ

準備ができたので、Lambdaをデプロイします。

$ sls deploy

デプロイが完了したらマネージメントコンソールに移動してデプロイしたLambdaの環境変数を確認します。

下記のようにコミットIDが含まれていたら成功です。

特定のLambdaだけ更新したときどうなるか

ファイルを修正して、特定のLambdaだけ更新してみます。

handler.py

import json


def hello(event, context):
    body = {
        "message": "Go Serverless v1.0! Your function executed successfully!!!!",
        "input": event
    }

    response = {
        "statusCode": 200,
        "body": json.dumps(body)
    }

    return response

    # Use this code if you don't use the http event with the LAMBDA-PROXY
    # integration
    """
    return {
        "message": "Go Serverless v1.0! Your function executed successfully!",
        "event": event
    }
    """

コード修正したらコミットします。

$ git commit -am "update"

hello関数だけデプロイしてみます。

$ sls deploy -f hello

マネージメントコンソールを確認すると、helloだけが更新されて、コミットIDも更新されていました。

おまけ:CodeBuild上で実行するとき

CI/CDなどの仕組みを構築する際に、CodeBuildでServerless Frameworkを使ってLambdaをデプロイするときもあるかと思います。

その際は下記のようにCodeBuildの環境変数を取得することでコミットIDを取得できます。

module.exports.getCommitId = async () => {
  if (process.env.CODEBUILD_SOURCE_VERSION) {
    return process.env.CODEBUILD_RESOLVED_SOURCE_VERSION;
  }
  const execSync = require('child_process').execSync;
  const cmd = 'git log -n 1 --format=%H,%cd';
  const result = execSync(cmd).toString().split(',');
  const commitID = result[0];
  return commitID;
};

CodeBuildの環境変数については下記ドキュメントを参照ください。 https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/build-env-ref-env-vars.html

さいごに

Serverless Frameworkを使ったLambdaのデプロイ時にLambdaの環境変数にコミットIDを含める方法を紹介しました。

誰かの参考になれば幸いです。