JenkinsとGruntを利用したAWS Lambda functionの継続的インテグレーションとデプロイ - Part 1
AWS Lambda functionの開発、テストとデプロイは時に退屈でつまらないプロセスかも知れません。好みのエディタ/IDEでファンクションを書き、その他の追加モジュールとともにパッケージ化し、AWSにアップロードしてコンソールからテストをします。理想としてはローカル環境で開発とテストを行い、レポジトリへのアップロードを行い、そしてCIツールにデプロイさせるでしょう。
この記事では、Grunt(ビルドやパッケージングといったタスクを自動化するために使われるJavaScriptのタスクランナー)とAWS Lambda functionのローカルでの実行とテストのためのgrunt-aws-lambdaプラグインといったツールの使い方をお見せします。
AWSリソースの作成
この記事を通して、AWS Lambda documentationに記述されているCreateThumnailのAWS Lambda functionを使います。このガイドに従うにはローカルの開発環境にImageMagickをインストールする必要があることに注意してください。
Getting Started ガイドにあるStep 1: Create a Lambda Functionに従って、CreateThumbnailというファンクションと適切なIAMロールを作成してください。ファンクションのコードについては後ほどアップロードので気にしないでください。
Step 1.1: Create Buckets and Upload a Sample Objectに従って、入力元と出力先のバケット(例えば、lambdapicsとlambdapicsresized)を作成してください。
開発環境のセットアップ
ローカルの開発環境の準備から始めましょう。
AWS CLIとNode.jsのインストール
まだインストールしていないなら、AWS CLIをインストールして設定し、自分のクレデンシャルを設定します。
# aws configure
選択したプラットフォームの手順に従ってNode.jsをインストールしてください。npmのバージョンが必要なのでNode.jsにはnpmが付属します。
AWS Lambda functionのプロジェクトを作成する
プロジェクト用にディレクトリを作成し、最初のpackage.jsonファイルを作成します。
# mkdir create-thumbs-lambda && cd create-thumbs-lambda
# npm init
package.jsonファイルを編集し、Lambda functionの依存関係(例えばGraphicsMagickやAsync)を追加し、AWS SDK、gruntとgrunt-aws-lambdaをdevDependenciesに追加します。 package.jsonは以下のようになります。
{
"name": "create-thumbs-lambda",
"version": "0.0.1",
"description": "AWS Lambda function to create an image thumbnail",
"main": "CreateThumbnail.js",
"dependencies": {
"gm": "^1.17.0",
"async": "^0.9.0"
},
"devDependencies": {
"aws-sdk": "latest",
"grunt": "0.4.*",
"grunt-aws-lambda": "0.8.0",
"npm": "^2.8.3"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Amazon Web Services Inc.",
"license": "Apache 2.0"
}
最後に必要なNode.jsのモジュールをローカルにインストールします。
# sudo npm install
開発、テスト、繰り返し
では、Lambda functionを作成しましょう。Step 2.1: Create a Lambda Function Deployment Packageからコードを新しいファイルにコピーします。async.waterfallのラストのコールバックを以下のようにするため、Lambda functionを編集します。
function (err) {
if (err) {
msg = 'Unable to resize ' + srcBucket + '/' + srcKey +
' and upload to ' + dstBucket + '/' + dstKey +
' due to an error: ' + err;
} else {
msg = 'Successfully resized ' + srcBucket + '/' + srcKey +
' and uploaded to ' + dstBucket + '/' + dstKey;
}
context.done(err, msg);
}
これはgrunt-aws-lambdaプラグインがfunctionが正常終了したにも関わらず失敗をレポートしてしまうことがないようにしています。CreateThumbnail.jsとしてLambda functionを保存します。
次に、Gruntfile.jsというファイルを以下の内容で作成します。
var grunt = require('grunt');
grunt.loadNpmTasks('grunt-aws-lambda');
grunt.initConfig({
lambda_invoke: {
default: {
options: {
file_name: 'CreateThumbnail.js'
}
}
},
lambda_deploy: {
default: {
function: 'CreateThumbnail'
}
},
lambda_package: {
default: {
}
}
});
grunt.registerTask('deploy', ['lambda_package', 'lambda_deploy'])
grunt-aws-lambdaプラグインはLambda functionの実行をトリガーするイベントを含むevent.jsonファイルが必要です。event.jsonは以下のようになります。
{
"Records":[
{
"eventVersion":"2.0",
"eventSource":"aws:s3",
"awsRegion":"us-east-1",
"eventTime":"1970-01-01T00:00:00.000Z",
"eventName":"ObjectCreated:Put",
"userIdentity":{
"principalId":"AIDAJDPLRKLG7UEXAMPLE"
},
"requestParameters":{
"sourceIPAddress":"127.0.0.1"
},
"responseElements":{
"x-amz-request-id":"C3D13FE58DE4C810",
"x-amz-id-2":"FMyUVURIY8/IgAtTv8xRjskZQpcIZ9KG4V5Wp6S7S/JRWeUWerMUE5JgHvANOjpD"
},
"s3":{
"s3SchemaVersion":"1.0",
"configurationId":"testConfigRule",
"bucket":{
"name":"lambdapics",
"ownerIdentity":{
"principalId":"A3NL1KOZZKExample"
},
"arn":"arn:aws:s3:::lambdapics"
},
"object":{
"key":"amazon-web-services-lambda.jpg",
"size":17565,
"eTag":"59103e49494baafabe627ce8476c9a3e",
"versionId":"096fKKXTRTtl3on89fVO.nfljtsv6qko"
}
}
}
]
}
Lambda functionをテストしてみましょう。アップロード前にエラーなく実行できることがわかるでしょう。
# grunt lambda_invoke
何もエラーがなく全てが実行されたら、このようなメッセージが確認できます。
Message ------- Successfully resized lambdapics/amazon-web-services-lambda.jpg and uploaded to lambdapicsresized/resized-amazon-web-services-lambda.jpg Done, without errors.
エラーなくfunctionが実行されたら、簡単なコマンドでそれをパッケージ化しアップロードできます。
# grunt deploy
まとめ
このウォークスルーではローカル環境でLambda functionを実行するためのGruntとgrunt-aws-lambdaプラグインの使い方をデモしました。次回はJenkinsを使った継続的インテグレーションと継続的デプロイのやり方をお見せします。AWS Lambdaに関する更なる情報はドキュメントを参照ください。
- 翻訳:西谷圭介(原文:Continuous Integration/Deployment for AWS Lambda functions with Jenkins and Grunt – Part 1)
コメント