echo("備忘録");

IT技術やプログラミング関連など、技術系の事を備忘録的にまとめています。

【Serverless Framework】Serverless Frameworkで外部ファイルの値を読み込み(YAML/JSON/JavaScript)

概要

Serverless Frameworkでは、serverless.ymlだけでなく、外部ファイルに定義を設定して読み込むことも可能です。 そのやり方についてです。

なお、読み込み可能なファイルは、以下の通りです。

serverless.com

YAMLJSONファイルの読み込み

YAMLJSONなど「キー:値」形式のファイルは、以下の方法で読み込みます。

※以下はYAMLで読み込んでいますが、JSONも(構造さえ気をつければ)同じです。

# settings.ymlに以下を定義する
hoge: hogehoge
fuga: fugafuga
# serverless.ymlで上記settings.jsonの値を読み込む
functions:
  exampleFunc:
    handler: exampleFunc.handler
    name: exampleFunc
    tags:
      hoge: ${file(./settings.yml).hoge}
      fuga: ${file(./settings.yml).fuga}

上記のように、外部ファイルの値を読み込みたいキーに対して、値を

${file(外部ファイルのパス).値を読み込みたいキー}

と設定すれば、外部ファイルの値を読み込んでくれます。
※上の例の場合、Lambda関数「exampleFunc」のタグに、

  • 名前:hoge, 値:hogehoge
  • 名前:fuga, 値:fugafuga

という2つのタグが登録されます。

また、上記のように「複数のキーを読み込む」場合、「custom」セクションの独自変数をうまく使うことで、読み込み回数を1回にできます。(下記参照)

# 独自変数「settings」に、settings.ymlの定義を格納する。
custom:
  settings: ${file(./settings.yml)}

# 実際に値を参照する場合、上記のcustom.settingsの各キーを参照すれば、
# キーの値を読み込みできる。
functions:
  exampleFunc:
    handler: exampleFunc.handler
    name: exampleFunc
    tags:
      hoge: ${self:custom.settings.hoge}
      fuga: ${self:custom.settings.fuga}
使いどころ

使いどころとしては、例えば下記ケースです。

  • 条件により、設定値を変更したい
    • 環境(開発/本番) など
  • 各環境の設定値自体は不変(Auroraの接続情報 など)

上記の場合、まず下記のようにフォルダ&ファイルを構成します。

【注意】
 ・ [Root]はserverless.ymlがあるフォルダ
 ・ 各「settings.yml」には環境ごとの定義がされている

  • [Root]
    • [dev]
      • settings.yml
    • [prod]
      • settings.yml

次に、serverless.ymlのcustom.settingsを下記のように設定する。
※${opt:env}は「CLIコマンドの引数envの値を参照する」という、
Serverless Frameworkの独自変数

# 独自変数「settings」に、settings.ymlの定義を格納する。
custom:
  settings: ${file(./${opt:env}/settings.yml)}

最後に、デプロイ時のCLIコマンドで、引数「env」に環境に対応したフォルダ名を指定すればOKです。

> sls deploy --env dev

JavaScriptファイルの読み込み

JavaScriptファイルの読み込み(=関数の戻り値を設定)も、大きな違いはないです。
定義としては、下記の書式となります。

キー: ${file(読み込みjsファイルのパス):戻り値を参照する関数名}

# 例:タグ「hoge」に、settings.jsのgetHoge()関数の戻り値  
# (=デプロイ時の日時情報)を格納する。
functions:
  exampleFunc:
    handler: exampleFunc.handler
    name: exampleFunc
    tags:
      hoge: ${file(./settings.js):getHoge}
// settings.jsでは、「module.exports.関数名」で関数を定義し、
// 設定したい値をreturnすればOK
module.exports.getHoge = () => {
    return new Date().toString();
};

なお、

  • 関数に引数を渡すことはできない
  • 戻り値をJavaScriptオブジェクトにして、そのキーを参照することは可能

のようです。

使いどころ

使いどころとしては、例えば下記ケースです。

  • 毎回値が変わる情報を設定したい
    • デプロイ日時情報など(上記の例のように)
  • serverless.ymlに、生の設定値を書きたくない。
    • Auroraの接続パスワード、外部APIのアクセストークンなどの重要情報
    • 本来、SecretManagerで管理するような情報

上記の場合、まずserverless.ymlでは上記同様、JavaScriptファイルの戻り値を設定するように記載して...

functions:
  exampleFunc:
    handler: exampleFunc.handler
    name: exampleFunc
    tags:
      token : ${file(./token.js):getToken}

実際のJavaScriptでは、生の設定値を記載しなくてよいような処理を施しておけばOKです。(例えば下記のような)

// token.jsの内容
module.exports.getToken = () => {
  
    // crypto-jsは暗号化&複合化を行うライブラリ
    const cryptoJs = require("crypto-js");
    const salt = 'set password salt phrase';
  
    // 「encryptedText」には、「tokenに設定する値を暗号化した値」を  
    // 設定する。
    const encryptedText = "encryptedtoken";
  
    // returnする値(=tokenに設定する値)は、  
    //「encryptedTextを復号化した値」を指定する。
    const decryptedText = cryptoJs.AES.decrypt(encryptedText, salt).toString(cryptoJs.enc.Utf8);
  
    return decryptedText;
};

こうすれば、生の設定値を書かなくて済む分、良くなると思います。

※もちろん下記ケースがあるとばれる可能性があるので、そこは注意です。
(.gitignoreに追加するなど、何かしら対応が必要です)

  • token.jsの内容(暗号化した値、復号化処理の内容など)がばれる
  • token.jsをgitHub等で公開している

まとめ

と、久々にServerless Frameworkに関する情報でした。

実は前回から、Serverless Frameworkに限らず、AWS/IaC/クラウドなどのナレッジがかなりたまってきたので、少しずづ公開したいなあと考えています。

また、近々イベントで登壇するかもしれないので、確定したら合わせて公開します。

てか、もう少し定期的にブログを公開したいなあ。

それでは、また次回。