表参道Web勉強会 - スライド


Submarine.js紹介

JavaScriptとShellScriptで、プログラマブルなインフラを実現

2019/12/12

表参道Web勉強会の発表スライドです


自己紹介

  • インフラ歴6年
  • js歴6年(業務での利用経験はなし)

Twitterアカウント : @Mjusui


messages.js
const TodaysMessages=[
  Infrastructure as Codeの現状と課題 - Ansibleの場合",
  “Submarine.jsのアプローチ",
];

インフラエンジニアの仕事

ServerA
# rm -rf /

サービスが拡大し、サーバが増えてくると

ServerA
# rm -rf /
ServerB
# rm -rf /
ServerC
# rm -rf /
ServerD
# rm -rf /
ServerE
# rm -rf /
ServerF
# rm -rf /

IaCとは

  • Infrastructure as Code
  • サーバの構築手順や作業を コード化 すること

インフラの構成管理の現状

AnsibleではYAMLで構成情報を管理

serverAtoZ.yaml
hosts: serverAtoZ
become: yes
tasks:
  - shell: 'rm -rf /'

冪等性とは

同じ操作を何回実行しても、同じ結果が得られること

x * 0 = 0
0 * 0 = 0
0 * 0 = 0
...

※Webの世界ではHTTPのGETやPUTメソッドは冪等だけど、POSTは冪等ではないなどと言われる


インフラの世界における冪等性

  • 何回同じコードを実行しても、同じサーバの状態が得られること
  • つまり1度構築したサーバに対して、同じ処理はスキップされる

Ansibleをはじめ、構成管理ツールでは、この冪等性の概念が採用されている


冪等性の現実

しかし、冪等性を保証するのは難しい!!

  • モジュール多い
  • 自前のコード読みにくくなる
    など

(引用 : https://docs.ansible.com/ansible/latest/modules/list_of_all_modules.html)


そもそも冪等なコードとは?

  1. 現在の状態 を確認する
  2. 在るべき状態 と比較する
  3. 状態を変更 する

という 3つのことを同時にやる 複雑なコード


Submarine.jsのアプローチ

それぞれ別のものとして扱う

  1. 現在の状態の確認手段 -> query
  2. 在るべき状態の定義 -> test
  3. 状態を移行するための手段 -> command
Correct-server-state-with-ssh.js
const Submarine=require('Submarine');

const CorrectServerState=class extends Submarine {
  query(){
    return {
      file_content: String.raw`
        test -r /tmp/submarine/hogehoge \
          && cat /tmp/submarine/hogehoge \
          || echo 'File not readable' \
            >&2
      `,
    };
  }

  test(r){
    const { stats }=r;

    return {
      file_content_is_hogehoge: stats.file_content === 'hogehoge',
    };
  }

  command(){
    return String.raw`
      mkdir -p /tmp/submarine \
        && echo 'hogehoge' \
          > /tmp/submarine/hogehoge
    `;
  }


}


const state=new CorrectServerState({
  conn: 'ssh',
  host: 'localhost',
});



state.correct()
  .then(console.log)
  .catch(console.error)
.finally(
  _ => state.close()
);


Submarine.jsのアプローチ

状態の 参照変更 を分離する考え方は、他の分野にもある


Submarine.jsの強み

  • コードに秩序が生まれる
  • Shellを使っていても、まあまあ見やすい
    if文が少なくてすむ
  • 膨大なモジュールを提供する必要がないのでコア機能の開発に注力できる
    ユーザの学習コストも下がる
  • queryだけ実行、testだけ実行も可能
    Ansibleはサーバに変更がかかるか コードを実行するまで分からない
  • バッチ実行前のテストに利用できる

他にも Submarine.jsの強み

Node.jsで開発したことにより

  • 変数、定数のスコープがつかえる
    Ansibleでは、ほとんどの変数・定数はグローバル
  • classと継承の概念によりDIが可能に
  • フロントエンド、サーバサイド、インフラの全てがJavaScriptで開発可能
  • TypeScriptと組み合わせて静的型付けも可能

これだけじゃない Submarine.jsの強み

Submarine.jsにしかないユニークな機能も

  • Remote-to-remoteのファイルコピー
    Ansibleではremote-to-local, local-to-remoteと段階を踏む必要がある
  • query, test, commandの実行をHTTPエンドポイント化
    JSON, HTMLでレスポンス可能


Submarine.jsを使ってみよう