Edited at

Macの開発環境構築(Ansible + Serverspec + Travis CI)

More than 3 years have passed since last update.


概要

AnsibleでMacの開発環境構築を自動化してみたので、やった事や調べたものをメモしておく。

Boxenみたいなのをansibleでやりたいなぁと思ったのがきっかけ。なのでour-boxen(テンプレ)みたいなのと、それをコピーしてカスタマイズした自分専用のリポジトリの二つを用意した。

blister-packの利用方法はREADME.rstを参照してください。

以下のような事をやった。


  • Mac OSX の開発環境構築をansibleで自動化する。主にhombrew + homebrew-caskで必要なパッケージをインストール

  • Boxenのように、共通部分、個人、プロジェクトに分けて構築内容(role)を管理する。

  • Serverspecでテストする。

  • Travis CIでビルド/テストを実行する


Ansibleで環境構築

[localhost]

127.0.0.1

[localhost:vars]
ansible_connection=local


Roleの管理


  • Boxenのように共通分/個人/プロジェクト毎に、構築内容を分けて管理するようにした。

├── Makefile

├── README.rst
├── Rakefile
├── callback_plugins
├── hosts
├── playbook.yml
├── roles
│   ├── common # <- 共通で使うrole群
│   ├── people # <- 個人毎のrole群
│   └── projects # <- プロジェクト毎のrole群
└── spec
├── common
├── people
├── projects
└── spec_helper.rb


Serverspecでテスト


  • ServerspecでAnsibleでの構築内容をテストできるようにした。


  • envassertとansibleのassertモジュールを使うという選択肢もある。

  • specファイルもcommon/people/projectsで分けるようにした。

  • Serverspecはやりたい事が大概ドキュメントに書いてあるので便利


Travis CIでビルド/テスト


  • Travis CI はビルド環境としてOS X環境を提供してくれる

  • それを使ってビルド/テストをする

  • OS Xを利用する場合は.travis.ymlで明示するだけ

  • homebrew、xcodeなどは事前に入ってるらしい

  • sudoはパスワード無しで実行できるらしいので、ansibleの「-K」オプションを抜かして実行している

language: objective-c

os:
- osx
before_install:
- brew update
- brew install python
- brew install ansible
- ansible-playbook -vv playbook.yml -i hosts
script:
- make test


TIPS


hombrewのupdate/upgrade


  • homebrewのupdateはFormulaやhomebrew自身をアップデートする。

  • upgradeは対象パッケージを再ビルド/インストールする。

  • ansibleのhomebrewモジュールには「update_homebrew」「upgrade_all」というオプションがある。

  • このオプションを適宜変更できるようにinventoryに変数をもたせた。

[localhost]

127.0.0.1

[localhost:vars]
homebrew_update=yes # 常にupdateするためyes。遅いと感じるならnoにする
homebrew_upgrade_all=no # 全パッケージの更新が必要になったらyesにする

homebrewモジュールにそのままパスしてる

- name: Update homebrew

homebrew: update_homebrew={{ homebrew_update }} upgrade_all={{ homebrew_upgrade_all }}


環境変数やパスの参照


  • homebrewなどは「hombrew --prefix」「homebrew --cellar」などでパスを取得できる

  • これをansibleやserverspecにどうやって渡すか。

  • Ansibleの場合 lookup プラグインで、環境変数や、シェルの実行結果などを、参照できる。

  • それを利用してinventoryファイルに定義すると、playbookの中で参照可能

[localhost]

127.0.0.1

[localhost:vars]
home_path={{ lookup('env','HOME') }}
homebrew_prefix={{ lookup('pipe','echo `brew --prefix`') }}
homebrew_cellar={{ lookup('pipe','echo `brew --cellar`') }}

これをroleの中で下記のように利用する

- name: Copy dnsmaq.conf

copy: src=roles/common/dnsmasq/files/dnsmasq.conf dest="{{ homebrew_prefix }}/etc/dnsmasq.conf" backup=yes

Serverspecの場合は何も考えずに、spec_helper.rbに定義した。

require 'serverspec'

set :backend, :exec

def home_path
home_path = `echo ~/`
home_path.chomp
end

def homebrew_prefix
prefix = `brew --prefix`
prefix.chomp
end

def homebrew_cellar
cellar_path = `brew --cellar`
cellar_path.chomp
end


AnsibleのCallbacksプラグインによる完了通知


  • Ansibleを実行すると時間がかかるので、終わったら通知するようにした。

  • AnsibleのCallbacksプラグインを使って、OS Xの通知センターに表示されるようにした。


Travisのビルド時間制限の対応

Travisは以下のような条件でビルドが強制的に終了してしまう。

とりあえずインストールに時間がかかるものは、Travisではスキップするようにした。


  1. TRAVIS_BUILD_SKIPという環境変数を用意

  2. role/specではこの環境変数をチェックして実行しないようにする


  • 本末転倒感がすごいのでより良い方法を探す。


lint的なチェック


  • Ansibleは標準で--syntax-checkをしてくれるオプションがある

  • ansible-lintというライブラリもある。-> tarvisでエラーが出た+大したチェックをしてくれないので今は使用してない

  • serverspecの方は、rubocopを利用している。「--auto-correct」オプションである程度、自動で整形してくれるの良い。

  • Makefileにcheckstyleと定義してチェックできるようにした


プライベートな構築内容の管理


  • 例えばプライベートなプロジェクトのrole/spec群はそれぞれ「private」というディレクトリ以下において、gitignore設定している。

  • プライベート用のYAML(private.yml)を用意して、毎回ansible実行時に、playbook.ymlとprivate.ymlをマージしてる。


githubのリポジトリの取り扱い


  • Travis CI上でansibleのgitモジュールを使ってSSH経由でgithubのリポジトリをcloneするためには秘密鍵が必要

  • その場合、デプロイキーを各リポジトリに設置するか、もしくはHTTPSでcloneするようにする必要がある。面倒なのでだいたいHTTPSにしている。

例: gitモジュールのrepoをhttpsで始まるURLにしている。

- name: Git clone tell-k/sphinxjp.themes.basicstrap
git: repo=https://github.com/tell-k/sphinxjp.themes.basicstrap.git dest=~/Work/python/sphinxjp.themes.basicstrap update=no


余談


  • Travis CI以外は半年くらい同じ構成で試したけど、大きな問題は特になかった。Ansible素晴らしい。

  • Serverspec + Travisでのチェックが割と安心感ある。Serverspecでテスト書くのはなんか楽しい。

  • ライセンスの関係でApp Store経由で購入しているものもあるので、完全自動化は難しそう。

  • 個人/プロジェクト毎みたいな話を書いたけど、ボッチなので自分以外の他に人と共有したり、使ってもらったりした事はない。

  • blister-packていう珍妙な名はBoxenのTOP絵を見てつけた。


代替

Ansibleを利用してMac OS Xの環境構築をするアイディア/ツールは他にもいくつかある。

当初はこれらのツールを利用しようとしたが以下のような理由でやめた。


  • Ansible以外のツール固有の何かを覚えるのが面倒そうだった。

  • Boxenのようにラッパーコマンドがあったりするが、Ansibleのプラグイン機構で代用が効きそうだった。

  • 単純にショートカットとしてのラッパーだったら、Makefileで十分だった。


参考


書籍


Ansible関連


Boxen関連


Homebrew-cask関連


Serverspec関連