Edited at

AWS Lambda を作成・更新するための gulpfile 雛形

More than 3 years have passed since last update.

Lambda をいろいろな用途で使い出すと function の登録や更新が面倒なので、自分が使い回している gulpfile の雛形を晒しておきます。


機能

lambda.yml という設定ファイルに環境毎の lambda の設定情報を記載しておきます。

gulp build --env={production|development} で、コードの build、zip化、function 登録・更新までを自動で行います。


必要なもの

package.json の devDependencies には、


  • del

  • gulp

  • gulp-awslambda

  • gulp-install

  • gulp-load-plugins

  • gulp-rename

  • gulp-zip

  • js-yaml

  • run-sequence

  • yargs

が必要です。


dependencies にある場合は、省略可。



雛形


gulpfile.js

const gulp = require('gulp')

const $ = require('gulp-load-plugins')()
const argv = require('yargs').argv
const env = argv.env || 'development'

gulp.task('build', () =>
require('run-sequence')('clean', 'lambda')
)

gulp.task('clean', (done) =>
require('del')(['build/*', '!build/node_modules', 'dist/*'], done)
)

gulp.task('prepareCode', () =>
gulp.src('src/**/*.js')
.pipe(gulp.dest('build'))
)

gulp.task('prepareConfig', () =>
gulp.src(`config/${env}.yml`)
.pipe($.rename('default.yml'))
.pipe(gulp.dest('build/config'))
)

gulp.task('preparePackages', () =>
gulp.src('./package.json')
.pipe(gulp.dest('build'))
.pipe($.install({production: true}))
)

gulp.task('lambda', ['prepareCode', 'prepareConfig', 'preparePackages'], () => {
const lambdaConfig = require('js-yaml').safeLoad(require('fs').readFileSync('lambda.yml', 'utf8'))[env]

return gulp.src(['build/**', '!build/package.json'])
.pipe($.zip('lambda.zip'))
.pipe($.awslambda(lambdaConfig.lambda, lambdaConfig.config))
.pipe(gulp.dest('dist'))
})



lambda.yml

default:

config: &config
region: ap-northeast-1
lambda: &default
Handler: lambda.handler
Runtime: nodejs4.3
MemorySize: 128
Timeout: 60

production:
config:
<<: *config
profile: production
lambda:
<<: *default
FunctionName: {FUNCTION_NAME}
Description: {DESCRIPTION}
Role: {ROLE_ARN}

development:
config: *config
lambda:
<<: *default
FunctionName: {FUNCTION_NAME}-dev
Description: {DESCRIPTION}
Role: {ROLE_ARN}



やってること


  • clean

build 用フォルダの削除。


  • prepareCode

ソースファイル(src/*/.js)を build 以下にコピーする。


  • prepareConfig

環境用設定ファイル(config/*.yml)を選択し、build/config/default.yml としてコピーする。


  • preparePackages

lambda 実行に必要な node_modules を build フォルダにインストールする。


native build が必要なパッケージには非対応。



  • gulp task: lambda

build フォルダ以下を lambda.zip として固めて lambda に登録。

function がない場合は新規に作成、ある場合はコードを反映。登録情報に変更がある場合は更新後にコード反映。


  • gulp task: build

clean 後に lambda 実行。


補足


lambda function 用の設定ファイルが必要

node-config(+ js-yaml)で環境毎の設定ファイルをロードし利用する手法を採用しています。

違うやり方が好きな人は、gulpfile の prepareConfig の部分を適宜修正してください。


lambda.yml の AWS Credential について

config 項に config.region 以外何も指定していない場合、認証情報として awscli の default profile の利用を試みます。

違う profile を指定する場合は、config.profile に profile 名 を指定してください。


Node の AWS SDK は現時点で role_arn に対応していないため、assume-role は自前で行っておく必要があります。

AssumeRole が面倒な人向け簡易 shell script



lambda.yml の Role について

lambda 実行用の IAM Role は事前に awscli もしくは管理コンソールで作成しておき、その ARN を指定します。

IAM Role を作るには、


AssumeRolePolicy.json

{

"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}

上記 AssumeRolePolicy.json を用意して

$ aws iam create-role \

--role-name {LAMBDA_ROLE_NAME} \
--assume-role-policy-document file://AssumeRolePolicy.json

で role 作成。

$ aws iam attach-role-policy \

--role-name {LAMBDA_ROLE_NAME} \
--policy-arn arn:aws:iam::aws:policy/AWSLambdaExecute

で作成した role に管理ポリシーの AWSLambdaExecute を付与。

追加でインラインポリシーを指定したい場合は、


InlinePolicy.json

{

"Version": "2012-10-17",
"Statement": [
{
"Effect":"Allow",
"Action":"sdb:*",
"Resource":"arn:aws:sdb:*"
}
]
}

のような InlinePolicy.json を用意(追加で付与したい権限を設定)して、

$ aws iam put-role-policy \

--role-name {LAMBDA_ROLE_NAME} \
--policy-name {POLICY_NAME} \
--policy-document file://InlinePolicy.json

で追加付与。

Role ARN は、

$ aws iam get-role \

--role-name {LAMBDA_ROLE_NAME} \
--query Role.Arn \
--output text

で確認できます。