#はじめに
これまで静的ページ配信のために、AWSコンソールからS3の設定を行い、ファイルをアップしていました。数が増えてきて毎回ぽちぽちやるのは大変になり、自動化できたら楽だなあというのと、静的コンテンツとはいえバージョン管理したいよね、という要望が出てきたので、AWS Lambdaを使ってBacklogとS3を連携して、コンテンツのアップロードを自動化するシステムを作ってみました。
#使うサービス
- Lambda
- API Gateway
- S3
- Backlog (SVN)
- 今回は図の②③④を紹介します。
- バージョン管理にgitでなく、svnを使うのはデザイナーさんやディレクターさんでも使えるようにです。
- Lambda, Gatewayの設定とBacklogのwebhookについては↓を参照。
http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/getting-started.html
http://www.backlog.jp/help/adminsguide/webhook-setting/userguide2493.html
#描いた
var async = require('async');
var request = require('request');
var aws = require('aws-sdk');
aws.config.update({
accessKeyId: 'your_key',
secretAccessKey: 'your_secret_key',
region: 'your_region'
});
var s3 = new aws.S3({ apiVersion: '2006-03-01' });
exports.handler = function(event, context) {
var project = event.project.projectKey;
var root = '';
getDir(project, root, function(dir1){
getDir(project, dir1, function(dir2){
putContent(project, dir1 + dir2);
});
});
};
/**
* ディレクトリ名を返す関数
**/
function getDir(project, dir, callback){
var exec = require('child_process').exec;
var cmd = "curl --user your_username:your_password https://your_domain.backlog.jp/svn/" + project + "/" + dir + " | grep href | grep -oE '\"([^\.]*)\"' | sed -e 's/\"//g'";
exec(cmd, function(error, stdout, stderr) {
dirs = stdout.split('\n');
var i = 0;
async.whilst(function start(){
return i < dirs.length;
}, function main(done){
callback(dirs[i]);
i++;
done();
}, function result(err){
if (err) console.error(err);
});
})
}
/**
* S3にアップする関数
**/
function putContent(project, dir){
var exec = require('child_process').exec;
var cmd = "curl --user your_username:your_password https://your_domain.backlog.jp/svn/" + project + "/" + dir + "| grep href | grep -oE '\".*\..*\"' | sed -e 's/\"//g' | grep -v ../";
var files = [];
exec(cmd, function(error, stdout, stderr) {
files = stdout.split('\n');
var i = 0;
async.whilst(function start(){
return i < files.length;
}, function main(done){
if(files[i] != ""){
var key = files[i];
var options = {
url: 'https://your_domain.backlog.jp/svn/' + project + '/' + dir + key,
auth: {
user: "your_username",
password: "your_password"
}
};
if(/.*image.*/.test(dir + key)){
options['encoding'] = null;
}
request.get(options, function (error, response, body) {
if (!error && response.statusCode == 200) {
var params = {
ACL: 'public-read',
Bucket: 'your_bucket',
Key: dir + key,
Body: body,
};
if (/.*html.*/.test(dir + key)) {
params['ContentType'] = 'text/html';
} else if (/.*css.*/.test(dir + key)) {
params['ContentType'] = 'text/css';
} else if (/.*js.*/.test(dir + key)) {
params['ContentType'] = 'text/javascript';
} else {
params['ContentType'] = response.headers['content-type'];
}
s3.putObject(params, function(err, data) {
if(err) console.log(err);
});
} else {
console.log('error: '+ response.statusCode);
}
})
}
i++;
done();
}, function result(err){
if (err) console.error(err);
});
})
}
#できたこと
Backlogのsvnリポジトリにコミットするだけで、リポジトリ内のファイルがS3にコピーされるようになりました。これでファイルの公開をデザイナーさんだけでできるようになります。
#苦労した点
-
backlogからのwebhookで返ってくる情報が少ない
-
公式サイトにはgitのwebhookのサンプルしか書いてなかったが、実際に返ってきたjsonはサンプルと違う、情報が少ない
-
svnはより少ない
-
画像のアップロード
-
S3にアップした画像が壊れていると表示されて困っていたが、requestモジュールで画像を取得するときは以下の設定が必要だった
`options['encoding'] = null;`
#まとめ
- Lambda, node.jsなどなどきちんと使うの初めてで色々苦労しましたが、新しいサービスを積極的に使えるのは面白かったです。Lambdaの使い途はまだまだあるので、どんどん使っていければと思います!