Lambda関数をCodeCommitで管理する


概要

Lambda関数のコードを、Gitでソース管理したい。

↓こんな感じでできるんじゃないかと。

データの流れはこんな感じ↓

登場人物

AWSSDKで、ソースを外から突っ込む系は以下のコマンドでできるみたいです。

  • Lambda.createFunction
    Lambda関数の属性値(メモリ・タイムアウト・説明・VPC設定などなど)と、ソースコード(zipにする必要がある)をまとめて送るとLambda関数が作成される。

  • Lambda.updateFunctionCode
    関数名を指定して、ソースコード(zip)を送ると、ソースコードのみが更新(総入れ替え)される。

作ってみた

  • とりあえず、ソースコードの入れ替えができれば良いので、createFunctionは使わずupdateFunctionCodeを使うことにする
  • CodeCommit内レポジトリからソースコードを抽出して、zipでまとめてupdateFunctionCode を実行する感じで。

処理概要

Lambda関数で以下の処理を書きます

  1. 対象のLambda関数名を指定する
  2. CodeCommitレポジトリ内から関数名フォルダ以下のファイル一覧を取得CodeCommit.getFolder
  3. ファイル一覧でループして、ファイル内容を取得するCodeCommit.getFile
  4. zipに固める
  5. updateFunctionCodeを実行する

コード

下準備:zip圧縮を使うので、Layerを準備します。↓を参考に。
【Lambda】zipファイルの圧縮解凍サンプル【nodejs】

宣言部
var AWS = require('aws-sdk')
var lambda = new AWS.Lambda();
var codecommit = new AWS.CodeCommit();
var node_zip = require('node-zip');
CodeCommitリポジトリ中、指定フォルダからファイル一覧を取得する関数
async function listFiles(Folder){
    var pCCm = {
        folderPath: Folder,              
        repositoryName: process.env.CodeCommitRepo  // 環境変数にリポジトリ名
    };
    const ccF = await codecommit.getFolder(pCCm).promise();
    let files = [];
    // ファイル取得
    for(let i=0;i< ccF.files.length;i++){
        // 先頭の関数名を除く
        files.push(ccF.files[i].absolutePath);
    }
    // サブフォルダ→再帰処理
    for(let i=0;i< ccF.subFolders.length;i++){
        let files2 = await listFiles(ccF.subFolders[i].absolutePath);
        files = files.concat(files2);
    }
    return files;
}
本体-ファイル一覧取得
let lstFiles = await listFiles(event.FunctionName);
zip変数へファイル名とファイル中身を設定する
var zip = new node_zip(); // zip変数

    for(let i=0;i< lstFiles.length ;i++){
        var pGet = {
            filePath: lstFiles[i],     // ファイル名
            repositoryName: process.env.CodeCommitRepo,   // 環境変数でリポジトリ名指定
        };

        const cCgf = await codecommit.getFile(pGet).promise();
        // ファイル名先頭の関数名を除いて、zip変数へ突っ込む(ファイル名とファイル中身)
        zip.file(lstFiles[i].slice(event.FunctionName.length + 1), cCgf.fileContent); 
    }
updateFunctionCodeを実行してLambda関数のソースを更新する
    let zipContent = zip.generate({base64: false,compression:'DEFLATE'});

    var pLmd= {
        FunctionName: event.FunctionName, 
        ZipFile: Buffer.from(zipContent, 'binary')
    };
    await lambda.updateFunctionCode(pLmd).promise();

あとがき

意外と短いプログラムでできる様子。。

CLI+バッチのほうが簡単にできそう