[小ネタ]AWS Lambdaのデプロイ先を切り替える #アドカレ2015

2015.12.25

AWS Lambdaについて

AWS Lambdaとは

まずは簡単に説明を。
AWS Lambdaは、イベント発生時にコードを実行し、リソースを自動的に管理するサービスです。
「Lambda関数」とよばれる関数を定義したコードをアップロードすることで、
AWS Lambdaがコードを実行するサーバーの管理を行ってくれます。
(現在はNode,Java,PythonでLambda関数を定義することが可能)
以前であればサーバサイドでプログラムを動かすには、EC2を用意してそこで実行する必要がありましたが、
AWS Lambdaを使えばそれも不要になります。

なお、lambdaの基本についての詳細はこのへんをご確認ください。

環境構築方法

今回使用した動作環境は以下のとおりです。

  • OS : MacOS X 10.10.5
  • Node : v4.1.2
  • aws-cli : 1.9.15
  • gulp : 3.9.0

AWSアカウントを用意し、AWSコンソールにアクセスできるようにしておいてください。
また、aws-cliもインストールし、アカウント設定を行っておいてください。

GulpでAWS Lambdaのデプロイ

Lambdaを使ったアプリのデプロイ方法

Lambda関数を定義するには、AWSコンソール上で直接コードを記述するか、zipファイルをアップロードする必要があります。

lambda-deploy

試しにlambda関数を使ってみるくらいならこの方法で問題ないのですが、
実際に何度も関数を更新したりする場合には毎回手動でアップロードするのは面倒です。
それを簡単にするため、Gulpを使用する方法があります。

GulpをつかったAWS Lambdaのデプロイ

では、GulpをつかってLambda関数をデプロイしてみましょう。   「node-aws-lambda」というモジュールを使い、Gulpでアップロードします。
ここ」を参考にプログラムや設定ファイルを記述していきます。

まずはaws-lambda-testディレクトリを用意し、下記のようなtest.jsファイルを作成します。

//aws-lambda-test/test.js
exports.handler = function (event, context) {
    console.log("hello AWS Lambda");
    context.done(null, 'success test1');
};

そして、上記参考URLにあるとおり、 

  • 必要なnodeモジュールのインストール
  • 出力ディレクトリ作成
  • IAMロールの作成とPolicyファイルの作成

を行います。

次に、下記のようなgulpfile.jsを作成します。

//gulpfile.js
var gulp = require('gulp');
var zip = require('gulp-zip');
var del = require('del');
var install = require('gulp-install');
var runSequence = require('run-sequence');
var awsLambda = require('node-aws-lambda');

gulp.task('clean', function(cb) {
  del(['./dist', './dist.zip'], cb);
});

gulp.task('js', function() {
  gulp.src('config/*',{ base: '.' }).pipe(gulp.dest('dist/'));
  return gulp.src(['test.js'])
    .pipe(gulp.dest('dist/'));
});

gulp.task('node-mods', function() {
  return gulp.src('./package.json')
    .pipe(gulp.dest('dist/'))
    .pipe(install({production: true}));
});

gulp.task('zip', function() {
  return gulp.src(['dist/**/*', '!dist/package.json'])
    .pipe(zip('dist.zip'))
    .pipe(gulp.dest('./'));
});

gulp.task('upload', function(callback) {
  awsLambda.deploy('./dist.zip', require("./lambda-config.js"), callback);
});

gulp.task('deploy', function(callback) {
  return runSequence(
    ['clean'],
    ['js', 'node-mods'],
    ['zip'],
    ['upload'],
    callback
  );
});

最後にAWS Lambdaの設定を記述した、lambda-config.jsを作成します。

//lambda-config.js
module.exports = {
    region: '<リージョン>',
    handler: 'test.handler',
    role: '<IAMのarn>',
    functionName: '<関数名>',
    timeout: <タイムアウト秒数>
}

これでGulpを使ってLambda関数をデプロイする準備が整いました。
下記コマンドを実行して、AWSにデプロイしてみましょう。

% gulp deploy
・
・

デプロイが成功したらAWSコンソールで対象リージョンのLambdaを確認してみてください。
test関数が登録されており、Testボタンを押せばその場で実行することも可能です。

デプロイ先を指定してAWS Lambdaのデプロイ

上記デプロイ方法の問題

Gulpを使って簡単にLambda関数をデプロイすることができましたが、
実際の開発では、「開発用」「本番用」など、複数の環境にデプロイすることが多々あります。
そういった場合、上記の方法だと、設定ファイルをいちいち書き換えなければいけないので、非常に手間がかかりますが、
少し修正するだけで複数環境へデプロイできるようになるので、その手法について紹介します。

aws-cliでプロファイルを作成

aws-cliでは複数のcredentialを定義して使い分けることができるので、必要な分だけデプロイ先のプロファイルを作成します。
~/.aws/credentialsを、下記例を参考に記述してください。

・
・
[lambda-dev]
aws_access_key_id = <dev用アクセスキー>
aws_secret_access_key = <dev用シークレットキー>
[lambda-prod]
aws_access_key_id = <prod用アクセスキー>
aws_secret_access_key = <prod用シークレットキー>

ここでは「lambda-dev」(開発用)と「lambda-prod」(本番用)の、2つのプロファイルを用意しました。

Gulpを実行するシェルを作成

binディレクトリを作成し、その中にシェルスクリプトを作成します。

% mkdir bin
% touch bin/upload-lambda.sh

bin/upload-lambda.shを下記内容で記述します。

#!/bin/sh

if [ $# -ne 1 ]; then
  echo デプロイ環境を指定してください
  exit 1
fi

cd `dirname $0` || exit 1
cd ../

export AWS_DEFAULT_PROFILE=$1
gulp deploy

やっていることは単純で、AWS_DEFAULT_PROFILE環境変数に任意のプロファイルを指定するだけです。
下記のようにすれば、開発環境用アカウントを使用してデプロイします。

//lambda-devプロファイルを使用してデプロイ
% bin/upload-lambda.sh lambda-dev

まとめ

さて今回は、Gulp(node-aws-lambda)をつかってAWS Lambdaをアップロードする際に、
環境を切り替える方法について紹介しました。
これで簡単に開発用・本番用などの複数環境にデプロイすることができると思います。

なお、この方法だと環境毎にプロパティファイルやlambda-config.js等の設定ファイルまで切り替えることはできません。
その方法についてはまた別の記事で紹介する予定です。

参考サイトなど