Slide 1

Slide 1 text

Node.js で CloudFormation の テンプレートを分割管理する

Slide 2

Slide 2 text

自己紹介 藤巻商店(@fujimakishouten) ● 株式会社 Eq ● Debian GNU/Linux をデスクトップ環境で愛用 ● 交互浴が好きで週に5〜6回銭湯に行く ● 恵海人

Slide 3

Slide 3 text

株式会社 Eq について ● サーバーを見られるエンジニアは2名 ● サーバー管理のコストを下げたい ● 小さなチームなので、効率よく開発したい ○ AWS のクラウドサービスを組み合わせて開発 ○ Lambda、APIGateway、DynamoDB などを使用

Slide 4

Slide 4 text

株式会社 Eq について ● 環境構築には CloudFormation を選択 ○ SAM を利用する前提 ○ SAM-Local で Lambda のテストをする予定だった

Slide 5

Slide 5 text

CloudFormation ● テンプレートが大きくなりやすい ○ DynamoDB のオートスケールをしようとすると 5つくらい設定が必要 ○ リソースによっては設定する項目も多い ● ごちゃごちゃして見通しが悪くなる

Slide 6

Slide 6 text

CloudFormation テンプレートを分割して管理したい

Slide 7

Slide 7 text

テンプレートを分割する方法 ● 検索すると2つの方法が見つかった ○ AWS::Include ○ AWS::CloudFormation::Stack ● 予め S3 に置いてあるテンプレートを 読み込んで利用できるらしい

Slide 8

Slide 8 text

テンプレートを分割する方法 ● S3 にテンプレートを置くのが面倒 ○ できればスタックを1つにしたい ○ とりあえず動かして試したいだけなのに、 アップロードする仕組みをつくらないとダメなの?

Slide 9

Slide 9 text

面倒くさいところ ● テンプレートを JSON で書く場合、 プロパティ名をクォートする必要がある ○ JavaScript ならこんな感じで書くことが可能 { Type: 'AWS::S3::Bucket', Properties: { BucketName: 'documents.honoka.io', AccessControl: 'Private' } };

Slide 10

Slide 10 text

Node.js を使ってテンプレートを結合する JavaScript で書いて、 JSON.stringify() すればいいのでは!?

Slide 11

Slide 11 text

Node.js を使ってテンプレートを結合する ./templates/resources/FunctionApi.js module.exports = { Type: 'AWS::Lambda::Function', Properties: { Code: './dest/api', Description: 'honoka.io JSON-RPC 2.0 API', FunctionName: 'honoka-api', Handler: 'index.handler', Role: { 'Fn::GetAtt': ['RoleLambda', 'Arn'] }, Runtime: 'nodejs8.10' } };

Slide 12

Slide 12 text

Node.js を使ってテンプレートを結合する ./templates/resources/index.js module.exports = fs.readdirSync(__dirname).reduce((collection, filename) => { if ('index.js' === filename) { return collection; } const name = filename.replace(path.extname(filename), ''); collection[name] = require(path.resolve(__dirname, name)); return collection; }, {});

Slide 13

Slide 13 text

Node.js を使ってテンプレートを結合する ./templates/index.js const converter = require('../lib/converter/resources'); module.exports = { AWSTemplateFormatVersion: '2010-09-09', Parameters: {}, Conditions: {}, Resources: converter({}, require('./resources')) };

Slide 14

Slide 14 text

Node.js を使ってテンプレートを結合する ./package.json "scripts": { "template": "node -e \"console.log(JSON.stringify(require('./templates'), null, 4));\" > template.json" } npm run template を実行すると、 template.json が出力されるようにしている

Slide 15

Slide 15 text

できるようになったこと ● テンプレートを分割して管理できた ○ サブディレクトリを作ることも可能

Slide 16

Slide 16 text

できるようになったこと ● テンプレートに JavaScript が書ける ○ 環境に合わせて設定ファイルを変えたり const config = require(path.resolve(__dirname, '../../config', process.env.environment)); ○ 外部ファイルを読み込んだり RequestTemplates: { 'application/json': fs.readFileSync(path.resolve(__dirname, '../mapping/JSONRequest')).toString('UTF-8') }

Slide 17

Slide 17 text

まとめ ● 内容がすっきりして、見通しがよくなった ○ 見たい部分だけに注目できる ○ エラーが出ている部分や、 変更が必要な部分が見つけやすくなった ○ テンプレートがきれいに書ける ● 面倒くさく無くなった!

Slide 18

Slide 18 text

まとめ CloudFormation を使っていて、 同じようなことで困っている方の、 参考になれば嬉しいです。

Slide 19

Slide 19 text

参考 URL サンプルを公開しています https://github.com/honokaio/honoka-api-base