フロントエンド開発Blog

オレには鈍器がある

このエントリーをはてなブックマークに追加

Gulp , ansible , compass , vagrant , webpack

VagrantのプロビジョニングとしてAnsibleを使い、フロントエンド開発に必要なnodejsやruby、compass環境を全自動で作れるようにplaybookを作ってみました。コード一式はこちらです。

仮想マシン構築にはVagrantを使用

ubuntuベースのLinux仮想マシンです。仮想マシンの作成にはVagrantを使用しています。Vagrant自体がいまいち分からない方は以前ご紹介しました「windowsでvagrantを導入する」を最初にご覧になっていただくと導入が楽かと思います。

なお、Vagrant自体はMacOSでもWindowsでも変わりなく動作します(ただ、筆者がwindowsなためwindowsベースでの解説になってしまいますがご了承ください)

仮想マシンの内容

  • ruby(rbenv + ruby-build)
  • compass
  • nodejs
  • gulp,webpack

当仮想マシンにはapacheやnginxなどは盛り込んでいません。フロントエンド開発で必要なgulpやwebpackをvagrantでやるという趣旨のため最低限の構成にしています。

使い道

複数マシンを使用しているとnodejsやcompass、gulpやwebpackなどなど、開発に必要なソフトウェアのインストールが非常に面倒です。更に、それぞれのソフトウェアのバージョンを揃えることも考慮するとそこそこ手間がかかります。

また、windowsとMacユーザが入り混じった開発では、gulp環境を揃えておかないとjs-uglifyなどでwindowsとmacとで出力結果が違い、git上で年がら年中コンフリクトを起こすこともありえます。

そういったセットアップの手間を省くこと、複数人で環境をそろえることを目的として作成しました。

導入

プロジェクトディレクトリにansible_frontend_playbookを設置し、$ vagrant upするだけです。

ディレクトリ構成例

/
|- htdocs/ (your web contents.)
|- package.json
|- gulpfile.js
|- webpack.config.js
|- ansible_frontend_playbook
   |- Vagrant
   |- provision.sh
   |- ansible/
      ...

こういう感じに設置します。そしてコマンドプロンプトから$ vagrant sshを実行して仮想マシンにログインします。仮想マシン上の/vagrantというパスがプロジェクトルートディレクトリとつながっています(windowsホストと共有フォルダで共有されている)のでcd /vagrantでプロジェクトルートに移動します。

そのあとはいつもどおりnpm installし、gulpをかけたりwebpackを使ったりします。

windowsでの注意

windowsとLinuxのファイルシステムの差異のため、共有フォルダ上でnpmを使用するときはいくつか制約があります。

  1. 長すぎるパスは取り扱えずにnpm installでこける
  2. シンボリックリンクを取り扱えずにnpm installでこける

windowsの制約上仕方がありません。回避策としては

  • npm3を使う
  • npm installのとき --no-bin-links オプションを使う

通常、npmでパッケージをインストールするとnode_modulesの中にnode_modulesがあってさらにnode_modulesが・・・という入れ子module状態になります。windowsネイティブのnpmであればそこらへんを上手に回避してくれるみたいですが、windowsとの共有フォルダでlinux版npmを実行するとエラーになります。

npmバージョン3以上であれば、node_modulesが入れ子にならずに並列にパッケージが設置されるためパス名が長くなりすぎることがありません。windowsとの共有フォルダでnpmするならnpm3以上を導入しましょう。ちなみにGitHubにあげたやつはデフォルトでnpm3を使いますので特に気にしなくてもOKです。

また、シンボリックリンク問題は --no-bin-links オプションでカンタンに回避できます。これは「シンボリックリンクを使わないでね」というオプションです。そのままですね。これでエラーなくインストールできるかと思います。

・・・と、ここまでは使い方の説明でした。ここからはansible周りにフォーカスしてカンタンに解説を入れたいと思います。

概要

VagrantやAnsibleに詳しい方にとっては釈迦に説法どころの騒ぎじゃないかもしれませんが一応。

  1. Vagrantでubuntuマシンを作成
  2. Vagrantの共有フォルダ設定で、プロジェクトフォルダ(Vagrantfileからみて ../ のフォルダ)と、プロビジョニング用フォルダ(Vagrantfileからみて . )を共有する
  3. Vagrantのプロビジョニングが開始され、プロビジョニングフォルダの中の provision.sh を実行
  4. shell経由で仮想マシンにansibleがインストールされる
  5. ansibleが実行され、セットアップが自動で進む

という流れになっています。ansibleのディレクトリ構成は以下のサイトを参考にしました。

こちらを参考にしつつ私なりに設計してみました。

ansible ファイル構造

/
│  provision.sh
│  Vagrantfile
│
└─ansible
    │  local.yml ・・・サーバ個別のエントリーポイント
    │  localhost ・・・サーバホスト設定ファイル(ansibleコマンド実行時に指定)
    │  master.yml ・・・マスタープレイブック
    │
    ├─group_vars
    │      all ・・・変数を集約したファイル
    │
    └─roles ・・・ansibleタスク
        │
        ├─common
        │
        ├─gem
        │
        ├─node
        │
        ├─npm
        │
        ├─rbenv
        │
        ├─ruby
        │
        └─ruby-multi
  • master.ymlをエントリーポイントとする
  • master.ymlにはセットアップするサーバ単位に分けられた子エントリーポイントをincludeする
  • 変数は極力外だしにする(group_varsディレクトリ)
  • group_vars/all には全サーバで共有する変数を格納
  • 今回は使わなかったが必要に応じて group_vars/local とか group_vars/apserver など個別の変数ファイルを用意
  • rolesディレクトリ内にはそれぞれミドルウェア単位、機能単位で分割されたタスクを置く

今回はlocalサーバ1台だけですが、サーバ台数が増えても対応できるようにちょっと気合入れてみました。

group_vars/allに書いた内容はそれぞれのrole内で変数として使用できます。ソフトウェアのバージョン指定などを変数化しておくことで、変数ファイルを編集するだけで自分好みの構成にできるようになります。

roles/HOGEHOGE/main.ymlを直接書き換えればいいじゃないか・・・と思うかもしれませんが、「ロジックに手を入れるのは極力さける」ことでtypoによる動作不良を未然に防ぐことができます。また、単純に変数ファイルに集約されていればあちこち探さなくてよいから楽、という側面もありますね。

ansible エントリーポイント

localサーバ構築のエントリーポイントはlocal.ymlになります。このファイルは非常にシンプルで

---
- hosts: 127.0.0.1
  connection: local
  roles:
    - role: common
    - role: rbenv              # rbenv,ruby,ruby-multi playbook
    - role: ruby-multi         # Special thanks: leucos/ansible-rbenv-playbook
      versions: $ruby_versions # Github: https://github.com/leucos/ansible-rbenv-playbook
    - role: gem
    - role: node
    - role: npm

このように何のroleを実行するか、しか書いてません。それぞれのタスクはrolesファイルに委譲します。

  • common: apt-getで最初にインストールしておきたいパッケージを導入
  • rbenv: rbenvを導入
  • ruby-multi: rbenv経由でrubyをインストール
  • gem: gemでcompassとかインストール
  • node: nodeインストール
  • npm: gulpとかwebpackをglobalにインストール

ansible 変数について

group_vars/allに変数を集約しています。ざっと項目を解説します。

user:
  name: vagrant

vagrantユーザ名を格納します。vagrantじゃない場合は別のユーザ名にしますが、vagrantなのでそのままにします。

essentialpkg:
  - git
  - vim
  - curl
  - build-essential
  - libssl-dev
  - libffi-dev

common roleで使ってます。apt-getで最初にインストールするソフトウェアをリスト形式で書きます。

gempkgs:
  - compass

gem roleで使います。gem installしたいものリストです。

npmpkgs:
  - webpack
  - gulp

npm roleで使用します。npm install -g HOGEHOGEのパッケージリストを記述します。

# Which versions we want to install (see `rbenv install -l`)
ruby_versions:
    - 2.1.10

# The default version (used with `rbenv global`)
ruby_default: "2.1.10"

rbenvおよびrubyのセットアップに使います。rubyのバージョンを記載します。

node_version: 6.x

nodejsのバージョンを書きます。メジャーバージョン.xの形式で、最新版を取得してくれます。

ansible のよいところ

githubでansibleと検索すると分かりますが、いろんな方がいろんなroleを公開してくれています。roleというのはchefでいうレシピのようなものです。

今回、rbenvの導入で躓いて時間がかかりそうだったためleucosさんのお力をお借りしました。

自分で書くとなると大変だなーと思った矢先偶然見つけてありがたく導入させていただきました。このようにいろんな人の力を借りることができるのがansibleの強みのひとつですね。chefもまぁそうでしたがchefよりも導入が楽で、基本rolesフォルダにそのままぶっこんで変数をちょちょっと書き換えるだけです。楽チン!

あれこれとroleをかき集めることで「オラにroleをわけてくれ~~」ってやってすんごい仮想サーバが作れちゃったりします。

Vagrantとansibleを併用してみた雑感

ansibleのプレイブックを作るとき、どうしてもトライアルアンドエラーが必要になるかと思いますが、Vagrantを使っているとsaharaプラグインでカンタンにrollbackができるため何度でも試行できます。

ansibleはあまり詳しくなかったため何度もrollbackしてはvagrant provisionを実行して精査していきました。そういう面でも、巻き戻し可能なVagrantとの親和性はよかったかなと思います。

ページトップへ

関連ページ

ページトップへ