Node.js + Github Private Registry
概要
Github Private Registryにより、プライベートなモジュールを簡単に作成することができるようになりました。 今回はGithub Actionsを用いてNPMモジュールをGithub Private registryに登録・利用する方法を紹介します。
モジュール化したいリポジトリの設定
Github Actionの設定
まず、ドキュメントに沿って以下のようなYamlファイルを作成します。
# .github/workflows/release.yml name: Release on: release: types: [created] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 # Setup .npmrc file to publish to npm - uses: actions/setup-node@v1 with: node-version: '14.x' registry-url: 'https://npm.pkg.github.com' - run: yarn - run: yarn publish env: NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Github Actionsではリポジトリに紐付いたGITHUB_TOKEN
が自動的に挿入されます。このトークンはこのGithub Private Registryに対する書き込み権限を持っているので、そのまま使用することができます。
package.jsonの設定
Github Registryを使用する際に、パッケージ名に組織名を入れる必要があります。
{ "name": "@<org name>/<package name>" }
後はNPMのお作法に従って、
npm version patch
でタグを作成し、Github上でリリースを作成すると自動的にPrivate RegistryにPublishしてくれます。リリースはこちらからです。
モジュールを使用したいリポジトリの設定
次にモジュールを使用したいリポジトリ側でインストールできるように設定する必要があります。
.yarnrcの作成
使用したいリポジトリのルート配下に以下のような.yarnrc
を作成します。以下の設定で特定のモジュールのみをGithub Registryから取得することができます。
registry "https://registry.npmjs.org" "@<org name>:registry" "https://npm.pkg.github.com"
ローカルの設定
ローカル開発で使用する場合、Github Registryにアクセスできるようにする必要があります。
Personal access tokensのページからアクセストークンを作成します。権限は read:packages
だけで十分です。
作成したトークンを利用してnpm login
します。
npm login --registry=https://npm.pkg.github.com Username: suguru03 Password: <access token>
ログインが完了すると~/.npmrc
が更新されており、先程のトークンがあることが確認できます。(確認できてしまっていいのかどうか…)
//registry.npmjs.org/:_authToken=<access token>
ここのトークンを書き換える必要があるだけで、npm login
は必須ではないです。
以上の設定で、リポジトリ配下でyarn install
することができるようになります。
CIの設定
Github ActionsでもCirlceCIでも、ローカル開発と同様にアクセストークンを作成する必要があります。
Github Actionsの場合
Github Actionsで自動的に挿入されるGITHUB_TOKEN
は他のGithub Private Registryにアクセスする権限がないため、別途作成する必要があります。
またGTIHUB_TOKEN
は上書きできないため、作成したトークンはNPM_TOKEN
としました。NPM_TOKEN
はOrganization配下のsecretsに入れると、再利用ができて便利かと思います。
以下はstepsの一部抜粋です。
steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: node-version: '14.x' registry-url: 'https://npm.pkg.github.com' - name: yarn install run: yarn env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
CircleCIの場合
CircleCIでは以下のように書きました。
steps: - run: name: npm login command: echo "//npm.pkg.github.com/:_authToken=$NPM_TOKEN" > ~/repo/.npmrc - run: name: yarn install command: yarn workflows: deploy-workflow: jobs: - build: context: node
こちらもGithub Actionsと同様にcontextを使用して他のリポジトリでも使用できるようにしておくと便利かと思います。
また、公式はnpm login
を叩いていますが、実際は叩かずともインストールが可能です。
dependencies: pre: - echo -e "$NPM_USER\n$NPM_PASS\n$NPM_EMAIL" | npm login
まとめ
Node.jsでのGithub Private Registryの使い方について紹介しました。 NPM Private Registryは少しハードルがありましたが、Github Private Registryは無料枠もあり気軽に試せるのでとてもオススメです、是非試してみてください。
リンク
AST + Prettierで快適にコードを一括変換しよう
概要
この記事はQiita Node.js Advent Calendar 2019 5日の記事です。
「Node.jsのプロジェクトにTypeScriptを導入したい」
ちょうど去年の12月に面接で聞かれたことでした。
あなたならどう答えますか?
今回は面接のネタとしても使える、ASTとPrettierを利用してコードを一括変換する方法を紹介します。
ASTとは
AST(Abstract Syntax Tree)とは抽象構文木のことで、コードを抽象化しツリー構造にパースしたものです。 身近なところではTypeScript、Eslint、Prettierなどで使用されています。
コードの変換方法
コードを変換するアプローチは色々ありますが、ASTに出会う前はよく正規表現を利用してコードの変換をしていました。
正規表現による変換
例えば var
を const
に変換するくらいなら正規表現のほうが早いかもしれません。
例1
以下の例を見てみましょう。
// test.js var a = 'a'; var b = 'b'; var c = 'c';
これくらいは余裕ですね。
// 回答例 const str = fs.readFileSync(path.resolve(__dirname, './test.js'), 'utf8'); str.replace(/var/g, 'const')
例2
次の例はだいぶ意地悪なコードですが、まだいけそうな気がします。
var d = 'd'; var variable = 'var var var';
// 回答例 str.replace(/var\s(.+?=)/g, 'const $1')
例3
次の例はいかがでしょう。
/** Goの型宣言 var e =1; C#の型宣言 var e = 1; **/ var e = 1;
まだなんとかなりそうですが…
正規表現でコードを変換する場合、試行錯誤して例外を見つけ、最終的に呪文のような正規表現を書くことになるかと思います。
ASTによる変換
そこで登場するのがASTです。
今回はbabelのパーサを使いコードをASTに変換します。
以下のように実行することでASTを出力することができます。ちなみに util.inspect
を使うことでネスト構造のオブジェクトを展開することができます。
const parser = require('@babel/parser'); console.log(util.inspect(parser.parse(str), false, null));
以下は実行結果よりvar
宣言の部分とコメントの部分の抜粋です。
// var宣言部分 Node { type: 'VariableDeclaration', kind: 'var', ... } // コメント部分 trailingComments: [ { type: 'CommentBlock', value: '*\n Goの型宣言\n var e =1;\n C#の型宣言\n var e = 1;\n*', ... } ]
AST上では var
の宣言とコメントは全く別物として扱われます。また const
定義の部分は以下のような定義になります。
// const宣言部分 Node { type: 'VariableDeclaration', kind: 'const', ... }
var
とconst
を比較したとき、大きな違いは kind
の部分だけになります。
どうですか、AST簡単ですね!
しかし大きな問題があります。 パーサはパースしかしてくれずコードの再形成はしてくれないのです…困った。
Prettierによるコードの再形成
そこでPrettierの出番です。
PrettierはJavaScript界隈では最も有名なコードの整形ツールの一つです。具体的にはコードを特定のパーサでASTに変換し、そのASTを元にコードを整えつつ再形成します。JavaScriptの場合、先程登場した @babel/parser
が使用されています。
今回やりたいことはシンプルで、パース後のASTの var
の部分を const
に変換し、Prettierにコードの再形成をしてもらいたいのです。
そのために作ったツールがprettier-hook
です。このツールは上記の機能をサポートしています。
コードは以下のように書きます。
// hook.js const { Ast, hooks } = require('prettier-hook'); function parse(ast) { // ASTの変換処理 return ast; } hooks.babylon.addHook(parse);
余談ですが、babylon
とはbabel
がモノレポ化前の名残で、現在は@babel/parser
として開発されています。
このparse
関数の中に任意のトラバーサを挟むことができます。
今回はvar
をconst
に変換したいだけなので、コードは以下のように書けます。
function parse(ast) { new Ast() // 変換したいTypeを指定 .set('VariableDeclaration', (parent, key) => { const node = parent[key]; node.kind = 'const'; // varをconstに変換する }) .resolveAst(ast); return ast; }
このAst
のクラスがprettier-hook
のトラバーサになります。
変換したいNode
のtype
を指定すると、そのtype
が現れたときに関数が呼び出され、ASTの変換を可能にしています。
以下のように実行することで、ASTを使用して変換することができます。
npx prettier-hook --require hook.js test.js // or npx prettier-hook --require hook.js --write test.js
// 実行結果 const a = "a"; const b = "b"; const c = "c"; const d = "d"; const variable = "var var var"; /** Goの型宣言 var e =1; C#の型宣言 var e = 1; **/ const e = 1;
ツールの紹介
prettier-hookを利用して作成したツールを軽く紹介します。
JavaScrip2TypeScript
JavaScriptファイルをTypeScriptファイルに変換するツールです。
主な機能は、
- require/exportsをimport/exportに変換
- JSDocのマイグレーション
- クラスの型定義
などがあります。
JSDocの例
/** * @param {number} a * @param {boolean} [b] * @param {string} [c] **/ function test(a, b, c = 1) { return 1; }
/** * @param {number} a * @param {boolean} [b] * @param {string} [c] **/ function test(a: number, b?: boolean, c: string | number = 1) { return 1; }
Classの例
class Test { constructor() { this.num = 1; this.str = 'str'; } getNum() { return this.num; } getStr() { return this.str; } } Test.num = 1;
class Test { static num: number; num: number; str: string; constructor() { this.num = 1; this.str = "str"; } getNum() { return this.num; } getStr() { return this.str; } } Test.num = 1;
ツール作成も含め、1週間弱で400ファイル以上あるプロジェクトをTypeScriptに変換できました。
実際、ツールも完璧ではないのと、アンチパターンのコードが多かったので、変換後に手直しが必要でした。
まとめ
コードを変換する際にASTを利用するアプローチについて紹介しました。 正規表現でコードを変換するコードを書くより、ASTで書くことにより保守性も上がるケースも多いのでは無いかと思います。 ぜひコードを変換する際にはASTを使ってみて、面接でネタにしてくださいね!
リンク
Unity Editor上でのVersion Controlの使い方 〜Perforce編〜
概要
UnityにはBuilt-inのVersionControlという関数があり、これを利用することでシェルコマンドを叩くこと無くGitやPerforceなどにCommit・Submitすることができます。
Unity Editor上からファイルを自動生成・削除、及びPerfoceに反映させるツールを作ったのでその一部を紹介します。
Version Controlの設定
[Project Setitngs] > [Editor]上にVersion Controlという項目を設定します。今回はPerfoceを使用するためPerfoceの設定をしました。
Connectのボタンを押してConnectedになっていることを確認してください。
VersionControlクラスの使い方
まずUnityEditor.VersionControl
をインポートします、C#ではusing
を使用します。
using UnityEditor.VersionControl;
また各関数でassetsのパスが必要となるため、assetsを用意しておきます。
var assetPath = Application.dataPath; var assets = new AssetList { new Asset(assetPath) };
Task
今回使用する関数はどれもUnityEditor.VersionControl.Task
を返します。必要に応じでWait
を呼んでください。
このTaskはawaitableではないため同期処理になりプロセスを専有します。他の作業がブロックされるのでなるべく呼ぶ回数を減らすことをおすすめします。
Checkout
Perfoceではすべてのファイルがreadonlyなので、ファイルを変更する前に必ずcheckoutする必要があります。
そのため必ずWait
を呼ぶ必要があります。
Provider.Checkout(assets, CheckoutMode.Asset).Wait();
PerfoceにはChaneglistという概念があります。 Gitのbranchに似てますが、同時に複数のChangelistを使用することができます。
例えば作業AとBを同時にする必要があり、それぞれを別のChangelistで管理することでSubmitするタイミングを調整することができます。
ここでCheckoutされたファイルは自動的にdefault
のChangelistに入ります。
Add
新しいファイルを追加します。ディレクトリパスを指定することでディレクトリ配下の新規ファイルを追加することができます。
Provider.Add(assets, true).Wait();
これらのファイルはAddコマンドを呼ばない限りPerfoce上で確認することができません。
これがとても厄介で、追加漏れしたファイルは存在しているにも関わらず、Perfoce上で確認ができないため困ることが多々あります。 この追加漏れをチェックするreconcileというコマンドがありますが、かなり不便です。
Delete
既存のファイルを削除します。
Provider.Delete(assets).Wait();
Revert
変更を破棄します。 Perforceの場合、チェックアウトされたすべてのファイルがSubmitの対象になります。そのため変更されてないファイルはUnchangedで破棄する必要があります。
Provider.Revert(assets, RevertMode.Normal).Wait();
Provider.Revert(assets, RevertMode.Unchanged).Wait(); // 未変更のファイルのみを破棄
Submit
変更を反映します。 changeSetのdescriptionはChangelistのdescriptionにリンクします。第四引数はSaveOnlyです。
var changeSet = GetChangeSet();
Provider.Submit(changeSet, assets, changeSet.description, true).Wait();
Submitを2回呼ぶとコネクションが切れることがあるので、2回呼ぶことは避けたほうが良さそうです。 コネクションが切れてしまった場合はProject Settingsからまた有効にする必要があります。
Example
実際のコードではasset配下は範囲が広すぎてパフォーマンス上の懸念があるため、作業範囲を限定します。
この例は、Zipファイルを展開し、Zip内に存在するファイルの追加・変更と存在しないファイルの削除をResources
配下に反映します。
// Zipファイルの展開 using (var archive = new ZipArchive(stream, ZipArchiveMode.Read, true)) { var assetPath = Application.dataPath; var resourcePath = Path.Combine(assetPath, "Resources"); var assets = new AssetList { new Asset(resourcePath) }; // Resource配下をCheckout Provider.Checkout(assets, CheckoutMode.Asset).Wait(); // Zipファイル内に存在するパスのキャッシュ var assetPathSet = new HashSet<string>(); foreach (var entry in archive.Entries) { var destinationPath = Path.Combine(resourcePath, entry.FullName); var dirName = Path.GetDirectoryName(destinationPath); if (dirName != null) { // ディレクトリが存在しない場合エラーになるので作成する Directory.CreateDirectory(dirName); } entry.ExtractToFile(destinationPath, true); // フルパスではなくasset配下のパスが必要なためassetのパスを取得する。これはmetaファイルにも使用される。 assetPathSet.Add(new Asset(destinationPath).assetPath); } // ディレクトリのmeta情報のために追加する assetPathSet.Add(new Asset(resourcePath).assetPath); // ディレクトリ配下の新規ファイルを追加する var addTask = Provider.Add(assets, true); addTask.Wait(); // Zipファイルに存在しないファイルの削除 var deleteAssets = new AssetList(); // addTask.assetListはチェックアウトされているすべてのファイル名を取得できる deleteAssets.AddRange(addTask.assetList.Where(asset => !assetPathSet.Contains(asset.assetPath))); Provider.Delete(deleteAssets).Wait(); // これらのファイルをデータ配下のChangelistに移動させる var changeSet = GetChangeSet("データ"); Provider.Submit(changeSet, addTask.assetList, changeSet.description, true).Wait(); // 未変更のファイルを取り消す Provider.Revert(assets, RevertMode.Unchanged).Wait(); }
まとめ
Unity EditorのVersionControlの使い方について紹介しました。 この順番で呼ばないとうまく動かなかったりハマりどころが多かったりしますが、自動化すると便利なことは多いのでぜひトライしてみてください。
Gitを使いたい。
リンク
FlatBuffers導入
概要
FlatBuffersを導入手順についての記事です。
FlatBufferとは
FlatBuffersとはGoogle社が開発しているクロスプラットフォーム対応のシリアライゼーションライブラリです。主にゲームで使われることを目的として開発されています。Protocol Bufferに似ていますが、大きな違いはバイナリデータをパースせずにシリアライズされたデータを使用するため、高速かつメモリを効率的に使うことができます。
Flatbuffersのインストール
はじめにflatbuffers
をbrewでインストールします。
brewが使えない場合はBuildingのページを参考にインストールすることができます。
brew install flatbuffers
flatc
というコマンドが使えるようになれば準備完了です。
FBSファイルの作成
次にFBSファイルを作成します。FBSファイルとはFlatbuffers用のスキーマ定義ファイルです。これによりバイナリファイルの作成および各言語のparserを生成することができます。
Tutorialを参考にFBSファイルを作成します。
// monster.fbs // Example IDL file for our monster's schema. namespace MyGame.Sample; enum Color:byte { Red = 0, Green, Blue = 2 } union Equipment { Weapon } // Optionally add more tables. struct Vec3 { x:float; y:float; z:float; } table Monster { pos:Vec3; // Struct. mana:short = 150; hp:short = 100; name:string; friendly:bool = false (deprecated); inventory:[ubyte]; // Vector of scalars. color:Color = Blue; // Enum. weapons:[Weapon]; // Vector of tables. equipped:Equipment; // Union. path:[Vec3]; // Vector of structs. } table Weapon { name:string; damage:short; } root_type Monster;
バイナリファイルの作成
バイナリファイルはJSONまたはJSON5のフォーマットを使用します。今回はJSON5を使用してバイナリファイルを生成します。
// monsterdata.json5 { pos: { x: 1, y: 2, z: 3 }, hp: 300, name: 'Orc' }
先程生成したFBSファイルを使用してJSONデータをバイナリファイルに変換します。
flatc -b monster.fbs monsterdata.json5
monsterdata.bin
が生成されればOKです。
JavaScriptで読み込み
今回はJavaScriptファイルをFBSファイルより自動生成し、実際にNode.jsでバイナリファイルを読み込みます。
flatc --js monster.fbs
monster_generated.js
ファイルが生成され、これを使用して実際にバイナリファイルを読み込んでみます。
Nodeの実行環境をTutorialを参考に作成し実行し、ログが出れば成功です。
yarn init -y
yarn add flatbuffers
// example.js const fs = require('fs'); const path = require('path'); const { flatbuffers } = require('flatbuffers'); const { MyGame } = require('./monster_generated'); const filepath = path.resolve(__dirname, 'monsterdata.bin'); const data = new Uint8Array(fs.readFileSync(filepath)); const buf = new flatbuffers.ByteBuffer(data); const monster = MyGame.Sample.Monster.getRootAsMonster(buf); console.log(monster.hp()); // 300 console.log(monster.name()); // Orc
node example.js
まとめ
FlabBuffersの導入をしました。まだベンチマークを計測していないですが、C#クライアントではうまく動いてより良い感じです。またdefault valueを使用することでデータ量を減らすこともできるようなので、ぜひ使っていきたいと思います。
Link
Serverless + AWS Lambda + API Gatewayのヘッダマッピング
概要
AWS Lambda上でリクエストヘッダの取得とレスポンスヘッダの追加をServerless上で設定する方法がわからなくハマったので、それについてまとめました。
リクエストヘッダのマッピング
AWS Lambdaで生のリクエストヘッダを取得するためには、API Gateway上でマッピングテンプレートによりマッピングする必要があります。今回はいくつかのエンドポイントでヘッダ情報をチェックする必要があったため、こちらのドキュメントを参考に以下のように追記しました。
functions: hello: handler: header.hello events: - http: path: hello method: GET request: ${self:custom.request} custom: request: template: application/json: method: $context.httpMethod, body : $input.json('$'), headers: #foreach($param in $input.params().header.keySet()) $param: $util.escapeJavaScript($input.params().header.get($param)) #if($foreach.hasNext),#end #end
これでヘッダ情報が取得できるようになります。
export const hello = async (event, context) => { cosnole.log(event.headers); );
レスポンスヘッダのマッピング
今回、AWS Gatewayのデフォルトはapplication/json
のようで、これをapplication/json; charset=utf-8
に書き換える必要がありました。yaml上で解決したかったのですがうまく解決できず。今回はこちらを参考にコードに追記して解決しました。
export const hello = async (event, context) => ({ statusCode: 200, headers: { 'Content-Type': 'application/json; charset=utf-8', }, body: JSON.stringify({ message: 'Go Serverless v1.0! Your function executed successfully!', input: event, }), });
共通関数の作成
以下の目的のため、共通の関数を作成しました、ソースコードはこちらです。
header.ts
-> src/funcitons/example.ts
に移動し、serverless.yaml
の記述を書き換えます。
functions: hello: handler: src/functions/example.hello events: - http: path: hello method: GET
ディレクトリ構造は以下のような感じです。
|--package.json |--serverless.yml |--src | |--errors.ts | |--functions | | |--example.ts | | |--util.ts |--tsconfig.json |--yarn.lock
次にaws-lambda
の型定義を追加します。
$ yarn add -D @types/aws-lambda
共通関数は以下のように書きました。
import { Handler, Context, APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda'; import { CustomError } from '../errors'; interface HandlerResult { statusCode?: number; // defaultは200 body?: string | object; // JSON.stringifyするのでなんでもOK } type CustomHandler = ( event: APIGatewayProxyEvent, context: Context, ) => void | HandlerResult | Promise<HandlerResult>; export const createAPIGatewayHandler = (handler: CustomHandler): Handler => async ( event: APIGatewayProxyEvent, context: Context, ): Promise<APIGatewayProxyResult> => { try { // check headers const { statusCode = 200, body = '' } = (await handler(event, context)) || {}; return createResponse({ statusCode, body: JSON.stringify(body), // JSON.stringify(undefined)にならないようにbodyを初期化 }); } catch (error) { let { statusCode, message } = error; if (!(error instanceof CustomError)) { // unknownエラーは500エラー statusCode = 500; message = 'Internal Server Error'; } return createResponse({ statusCode, body: JSON.stringify({ message }), }); } }; const createResponse = (response: APIGatewayProxyResult): APIGatewayProxyResult => ({ ...response, headers: { 'Content-Type': 'application/json; charset=utf-8', ...response.headers, }, });
example.ts
は以下のようになり、event
, context
ともに型推論が利くので型定義は不要です。
import { createAPIGatewayHandler } from './util'; export const hello = createAPIGatewayHandler(event => ({ body: { message: 'Go Serverless v1.0! Your function executed successfully!', input: event, }, }));
まとめ
Lambda上でリクエストヘッダ情報のチェック・レスポンスヘッダの書き換えができるようになりました。認証のためのCustom Authorizersという機能もあるのでこちらもまたチェックしてみようと思います。
リンク
Serverless + TypeScript + AWS Lambdaの開発環境構築
概要
Serverless FrameworkとはLambda関数などを開発・デプロイするためのツールです。今回はServerless + TypeScript + AWS Lamdbaのローカル開発環境の導入手順について書きます。
プロジェクトの作成
はじめにServerlessの環境構築をします。今回はAWS LamdbaのNode.jsを利用するため、templateはaws-nodejs
で作成します。pathのサービス名は適宜変更してください。
$ npx serverless create --template aws-nodejs --path my-service _______ __ | _ .-----.----.--.--.-----.----| .-----.-----.-----. | |___| -__| _| | | -__| _| | -__|__ --|__ --| |____ |_____|__| \___/|_____|__| |__|_____|_____|_____| | | | The Serverless Application Framework | | serverless.com, v1.36.0 -------'
ドキュメントにはnpm install -g serverless
と書かれていますが、npxを使用することをオススメします。
このときのserverlessのバージョンはv1.36.0
でした。
次にnpm packageを作成します。Serverlessのライブラリは必須ではないですが、CLIのバージョン固定するためにインストールしておきます。
$ cd my-service $ yarn init $ yarn add -D serverless
ローカル開発環境の構築
次にserverless-offline
のライブラリでローカル環境の構築を行います。
$ yarn add -D serverless-offline
serverless.yml
にserverless-offline
とテスト用にhelloを以下のように追記しておきます。
plugins: - serverless-offline functions: hello: handler: handler.hello events: - http: path: hello method: GET
起動して以下のログが出れば成功です。
$ yarn sls offline start Serverless: Offline listening on http://localhost:3000
package.jsonにスクリプトを追加しておくと便利ですね。
curlで叩いてみます。
$ curl http://localhost:3000/hello {"message":"Go Serverless v1.0! Your function executed successfully!",... }
上記のログが出れば設定完了です。
デプロイ
次にAWS Lambdaへデプロイします。serverless.yml
に以下を追記します。region、profile名を適宜変更してください。
provider: name: aws runtime: nodejs8.10 region: us-west-2 profile: my-service
AWSの認証キーは必要に応じて~/.aws/credentials
に追記します。
[my-service] aws_access_key_id = <your-key-here> aws_secret_access_key = <your-secret-key-here>
以下のコマンドでデプロイします。
$ yarn sls deploy
AWSコンソール上に表示されていれば完了です。
TypeScriptの設定
次にTypeScriptの設定を行います。設定はとてもシンプルです。
$ yarn add -D typescript serverless-plugin-typescript
offlineと同様に以下の記述を追記します。
plugins: - serverless-offline - serverless-plugin-typescript
handler.js
をhandler.ts
に変更し、以下のように書き換え、ローカルサーバが正常に立ち上がれば完了です。
export const hello = async (event, context) => ({ statusCode: 200, body: JSON.stringify({ message: 'Go Serverless v1.0! Your function executed successfully!', input: event, }), });
まとめ
まだ使い始めたばかりですが、Serverless FrameworkでAWS Lambdaの開発・テストがローカル環境で行うことができとても便利です、ぜひ試してみてください。
リンク
MetabaseをElastic Beanstalkにデプロイする
概要
Metabaseを導入したので、それの手順についてまとめます。
Metabaseのデプロイ
こちらのリンクからAWSにデプロイするボタンがあるのですが、うまく動かなかったため今回は手動でセットアップします。
まずはじめにElastic Beanstalkのサーバを構築します。プラットフォームは事前設定済みプラットフォームのDockerを選択します。
次にアプリケーションコードをアップロードします。ソースコードは既にS3上に上がっているためS3のURLを指定します。
https://s3.amazonaws.com/downloads.metabase.com/v0.31.1/metabase-aws-eb.zip
最新バージョンはこちらで確認できます、適宜URLのバージョン部分を書き換えてください。
リージョンのエラーが出る場合はソースコードをローカルにダウンロードし、ローカルファイルからダウンロードしたソースコードを選択しアップロードします。 「更にオプションを追加」をクリックし適宜設定し、環境を構築します。
Auroraの設定
今回は既存のAurora上にMetabase用のDBを作成します。新しくDBを作成する場合はこちらを参考にしてください。
ルートユーザでログインし、Aurora上にMetabase用のデータベースとユーザを作成します。
CREATE DATABASE metabase CHARACTER SET utf8mb4; CREATE USER 'metabase.admin'@'%' IDENTIFIED BY 'password'; GRANT SELECT ON *.* TO 'metabase.admin'@'%' WITH GRANT OPTION;
必要に応じて、対象となるデータベース上にReadonlyユーザを作成してください。
環境変数の設定
スタートガイドに従ってElastic Beanstalk上に環境変数を設定します。上記で生成したユーザを設定してください。
設定を更新して以下の画面が表示されれば準備完了です。
まとめ
Metabaseとても便利そうなのでぜひ使ってみてください。