Apex + Webpack で Lambda の配信管理

Apex + Webpack でLambda アプリケーションの配信管理を行う方法を紹介します。

Apex を用いた Lambda 配信管理

Apex は Lambda の実行、デプロイを管理するコマンドラインツールです。

Apex を利用することで、 Lambda関数のデプロイをコマンド経由で実行することが可能になり、 CI 等との組み合わせで自動デプロイ環境を構築する事ができます。

Apex のインストールは curl 経由で行うことができます。以下のコマンドを実行することで、 /usr/local/bin/apex が作成され、 apex コマンドが利用可能になります。

$ curl https://raw.githubusercontent.com/apex/apex/master/install.sh | sudo sh

Apex コマンドは 処理の実行時に、実行環境のローカルにある AWS 認証情報を参照します。 通常は ~/.aws/credentials に格納された AWS 認証情報を利用しますが、 AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_REGION の環境変数を利用することも可能です。

~/.aws/credentialsに複数の profile を定義している場合、 共通のコマンドオプション --profile を利用して、profile 名を指定することも可能です。

Apex Project の作成

apex init コマンドはプロジェクトの雛形を生成します。

$ apex init
             _    ____  _______  __
            / \  |  _ \| ____\ \/ /
           / _ \ | |_) |  _|  \  /
          / ___ \|  __/| |___ /  \
         /_/   \_\_|   |_____/_/\_\



  Enter the name of your project. It should be machine-friendly, as this
  is used to prefix your functions in Lambda.

    Project name: sloths

  Enter an optional description of your project.

    Project description: My slothy project

  [+] creating IAM sloth_lambda_function role
  [+] creating IAM sloth_lambda_logs policy
  [+] attaching policy to lambda_function role.
  [+] creating ./project.json
  [+] creating ./functions

  Setup complete, deploy those functions!

    $ apex deploy

project 名を入力した後、 Lambda の function role を生成し、必要な初期ファイルを生成してくれます。

  • project.json Apex の設定ファイル
  • functions/hello/index.js サンプルの Lambda 関数

作成されたファイルはそのままの状態でデプロイ可能となっています。Lambda 関数のデプロイは apex deployコマンドで実行します。

$ apex deploy

デプロイされた関数の実行は、apex invoke {関数名}コマンドで実行します。

$ apex invoke hello
{"hello":"world"}

デプロイされた関数の状態を確認するには、apex list コマンドが利用可能です。

$ apex list

  bar
    runtime: nodejs
    memory: 128mb
    timeout: 5s
    role: arn:aws:iam::XXXXXXXXXX:role/lambda
    handler: index.handle
    aliases: current@v3, foo@v4

  foo
    runtime: nodejs
    memory: 512mb
    timeout: 10s
    role: arn:aws:iam::XXXXXXXXXXX:role/lambda
    handler: index.handle
    aliases: current@v12

Apex Project の設定

初期状態で作成された project.json は以下のようになっているはずです。

{
  "name": "hoge",
  "description": "",
  "memory": 128,
  "timeout": 5,
  "role": "arn:aws:iam::XXXXXX:role/sample_lambda_function",
  "environment": {}
}

project.json は Apex で管理する全ての関数に対して適用される設定ファイルです。

それぞれの設定項目は、公式サイトのドキュメントから確認することが可能です。

http://apex.run/#fields

各 Lambda 関数は functions フォルダの中に、関数名のフォルダを作成して格納され、 AWS 環境へのデプロイもそれぞれ functions 直下のフォルダ単位で行われます。 フォルダ内では、index.handler がデフォルトのハンドラとなりますが、 設定項目 handler で変更することも可能です。

各 Lambda 関数のフォルダには固有の設定項目として、 function.json を配置することが可能で、 更に ステージごとに function.stage.json function.prod.json を配置することも可能です。

Webpack の導入

Node のプロジェクトにおいて、Apex / Lambda を利用する場合、 Webpack の導入が必要となるケースは多いでしょう。

Webpack を利用せずに 単純に Node で Apex / Lambda を記述する場合、 サンプルのプロジェクトベースではうまくいくものの、開発を始める上で以下のような問題に直面します。

  • Node8.10 に対応したものの、最新の ES 記法の利用可否等は考えたくない
  • node_modules を functions 内で展開しないと 外部モジュールが使えない
  • node_modules を全てzip に含めると配信サイズが肥大化する
  • 複数関数で利用する共通のコード等を functions 外においた際の取扱が困難

Apex で Webpack を利用するには、まず Webpack のインストールを行います。

$ npm i webpack webpack-cli

webpack.config.js は以下のような形で作成します。

const Webpack = require('webpack');

exports.default = {
    entry: './src/index.js',
    target: 'node',
    output: {
        path: process.cwd(),
        filename: 'index.js',
        libraryTarget: 'commonjs2'
    },
    externals: ['aws-sdk'],
    module: {
        rules: []
    },
    mode: (process.env.NODE_ENV =="production")?"production":"development",
    plugins: [
        new Webpack.DefinePlugin({
            'process.env': {
                // 全ての環境変数はWebpack 上で展開されるためここでの定義が必要
                NODE_ENV: JSON.stringify(process.env.NODE_ENV)
            }
        }),
    ],
    devtool: 'inline-source-map'
};

project.json には hooks セクションを追加して、 buildclean のフックを定義します。

{
  // ...
  "hooks": {
    "build": "../../node_modules/.bin/webpack --config ../../webpack.config.js",
    "clean": "rm index.js"
  },
  // ...
}
  • build ビルド実行時に行われる処理。ここでは、Webpack によるビルド処理を行います。
  • clean deploy後に行われる処理。ここでは Webpack 生成物の削除を行います。

これで apex deploy 実行時に 自動的に Node スクリプトファイルがバンドルされるようになりました。

オリジナルのソースを AWS 環境にUPLOADする必要がない場合、 プロジェクトルートまたは、Lambda関数のディレクトリに.apexignore を以下のような形で配置すれば、 配信ファイルから除外することが可能です。

src

投稿一覧へ