【要するに】osxcでMacの環境の構成を記述管理する【MacでAnsible】

ANSIBLE

よく訓練されたアップル信者、都元です。個人的な話になりますが、少し前にMacbookを新調しました。それまで利用していたMacbookは、Time Capsule経由でバックアップ-リストア経由で何台も渡り歩いてきた、最初に手に入れたMacから脈々と受け継がれる秘伝のタレ状態でした。MacPortsでパッケージを管理していた時代もありましたし、Homebrew Caskも導入していませんでした。

マシンを新調するにあたって、再びバックアップ-リストアを行えば、今までどおりの環境をそのまま移行できます。しかし、モダンなサーバ環境構築で取り入れられているInfrastructure As Codeを自分のクライアント環境でも実現できないか、と考えました。

記述に依る定義

サーバ環境の構成をコードで記述するメリットとしては、構築の自動化と再現性の高さを挙げることが多いと思います。要するに開発環境と本番環境で同じ構成が保証でき、また、Auto ScalingやPhoenix Serverと呼ばれる性質を持たせたい場合に有利となります。

しかし、クライアント環境というのは同時に複数の環境を展開をすることは無いため、自動化のメリットは薄いように思うかもしれません。が、筆者は「環境が記述してある(described)」であることが重要だと考えています。

サーバ・クライアントにかかわらず、システムの状態は記述により定義されるべきです。もちろんそれは「コードによって記述・定義してある」ことが望ましいですが、最悪「ドキュメントによって記述・定義してある」状態でも構いません。とにかく「誰かの頭の中にある」とか、「もうセットアップ済みでマシンイメージを取ってあるから気にする必要はない」とか、そういう制御不能な状態を避けるために、とにかく記述による定義を正としたいのです。

と、いう考え方は、クライアント環境にも当てはまる話題です。たとえ自分しか使わない環境であったとしても、過去の自分はこの環境に何をインストールしてどのような設定をしたのか、把握しておきたい。私はそう感じます。まぁ、人それぞれだと思いますけどね。

Mac OSX環境構築自動化ツールいろいろ

さて、そんな感じで色々調べてみた結果、もちろん同じようなことを考える人は多いようです。古くは(ってそんなに古くないですが)BoxenというPuppetベースの管理ツールが話題になったようです。

またBrew Bundle (Brewfile)によるパッケージインストール管理(設定までは細かく管理できない)も見つかりました。

その他色々な仕組みがあるようで、そしてそれぞれ、オワコンだとか2012年までだとか、興味深い議論が盛り上がっているようです。ともあれ本稿では、それぞれの比較評価はせず、たまたま筆者都元が採用したosxcというツールについてご紹介したいと思います。

screenshot_2015-06-22_21.08.26

osxcの導入

まずいきなりなんですが、罠を避ける必要があります。いかにもosxcの導入を解説するメインページの顔をしたコレは、旧バージョンの解説です。osxcを調べていて xc-* という記述が出てきたらひとまず罠を疑いましょう。

導入解説として我々が読むべきドキュメントはこっちです。

さて、「環境を全て記述したい」とは言えど、osxcの導入前にいくつかコマンドを走らせなければなりません。Step1〜6は、一度だけ実施する前準備です。この部分はコードとして記述しませんが、「ドキュメントとして記述・定義してある」状態で進めます。

ドキュメントとしては既にosxc/starterのページに記述済みであるため、あらためて自分で書く必要はないとしてしまうと考えるのも一つ。あとはこのブログ記事自体をドキュメントだと考えるのも一つでしょう。

ともあれ、下記のようにコマンドを実行して行きます。

  1. Mac App StoreからXCodeをインストールする。
  2. コマンドラインから下記を実行し、ライセンス条項に同意する。
    $ sudo xcodebuild -license
    
  3. XCodeのCommand Line Toolをインストールする。
    $ xcode-select --install
    
  4. easy_installでpipを導入し、pipでAnsibleを導入する。
    $ sudo easy_install pip; sudo pip install ansible
    
  5. 自分のアカウントにosxc/starterリポジトリをフォークする。都元は、そのままstarterという名前ではなく、分かりやすdai0304/osxc-starter という名前でフォークしました。

  6. フォークしたリポジトリをローカルマシン上にcloneする。

    $ git clone https://github.com/dai0304/osxc-starter.git ~
    
  7. cloneしたディレクトリにcdし、必要に応じて環境定義ファイル configuration.ymlinstallation.yml を書き換えたり書き換えなかったりする。まずは眺めるくらいでも。
    $ cd ~/osxc-starter
    $ less configuration.yml
    $ less installation.yml
    
  8. 下記コマンドを実行することにより、上記の環境定義ファイルを実環境に適用する。
    $ ansible-galaxy install -r requirements.yml && ansible-playbook desktop.yml
    

    sudo を利用している場合は、下記のように -K オプションをつける。

    $ ansible-playbook desktop.yml -K
    
  9. 以降、環境定義を変更したくなったら、定義ファイルを更新(Step7)しては適用(Step8)を繰り返す。

といった感じです。

ansible-playbook を実行すると下記のように最初にrootパスワードを問われ、その後各設定が適用されていきます。しばらく時間がかかりますが、放置しておくだけでOKです。

sudo password:

PLAY [all] ********************************************************************

GATHERING FACTS ***************************************************************
ok: [localhost]

TASK: [osxc.common-env | create the common_env] *******************************
changed: [localhost] => (item=daisuke)

TASK: [osxc.common-env | source this common env from every known dotfile] *****
ok: [localhost] => (item=[u'daisuke', '.bash_profile'])
ok: [localhost] => (item=[u'daisuke', '.bash_login'])
ok: [localhost] => (item=[u'daisuke', '.zshrc'])
ok: [localhost] => (item=[u'daisuke', '.zshenv'])

TASK: [osxc.homebrew | Ensure that homebrew is installed with the script method] ***
ok: [localhost]

(略)

osxcの設定ファイル解説

さて、リポジトリでは色々なファイルが管理してありますが、中身を把握する必要のあるものは、環境定義ファイル configuration.ymlinstallation.yml だけです。まずはデフォルトの状態を確認していきましょう。

configuration.yml

  - role: osxc.repository
    clone_url: https://github.com/robbyrussell/oh-my-zsh.git
    dest: /Users/{{ ansible_user_id }}/.oh-my-zsh

上記のように、osxc.repository を記述することにより、任意のgitリポジトリを指定の場所にcloneできます。{{ ansible_user_id }} の部分はユーザ名に置換されます。

cloneした後にシンボリックリンクを張りたい場合は、linksプロパティを記述することによって実現できます。

筆者はこのリポジトリとは別に、ドットファイルを管理するリポジトリdai0304/dotfilesを別途作成し、cloneにより配備するようにしています。 この辺りをご参考に。

install.yml

このファイルは分かりやすいですね。Homebrew tap するリポジトリや、Homebrew、及び Homebrew Caskでインストールするパッケージをひたすら列挙します。

都元の設定ファイルはこんな感じ。まぁ真似してもあまり意味のないところなので、みなさまのお好みで調整しましょう。

敢えて言えば、osxcで管理できない(頑張ればできるのかもしれませんが…)パッケージインストールは、末尾にコメントとしてメモしてあります。コード管理はできませんが、ドキュメント管理ということで徹底します。

osxconfig.yml

このファイルは、標準のosxcには存在しません。都元が勝手に拡張したファイルです。 configuration.yml 内に書いてしまっても良かったのかもしれませんが、なんとなく質の違うものとして分離させたかったので分けてみました。

新しい設定ファイルを追加した場合は、desktop.ymlの中に増やしたファイルを追加記述しておきましょう。

さて、このファイルで設定したかったのは各種コマンド実行によるOSXの設定です。

  - name: disable the sound effects on boot
    command: /usr/sbin/nvram SystemAudioVolume=" "
    sudo: yes

例えば起動時のジャーンという音を抑止したい場合 /usr/sbin/nvram SystemAudioVolume=" " というコマンドで制御できますが、これを定義しておきました。

  - name: delete localized files
    command: rm -fr {{ item }}
    with_items:
    - /Applications/.localized
    - /Applications/Utilities/.localized
    - /Library/.localized
    - (略)

また、ディレクトリの実体はアルファベットなのに、Finderで見た時に日本語にローカライズされるのが気持ち悪いので、各ディレクトリ内にある .localized ファイルを削除してまわっています。

その他 defaults コマンド実行による設定など、なるべくこのファイルで定義するようにしています。

まとめ

いかがでしたでしょうか。上で触れた通りosxc以外にも、Mac環境を記述するツールが色々あり、これからも新しいツールが出てきそうです。私としてはえいやでosxcを選んだわけですが、結果的になかなか使いやすいな、と思っています。

この設定がGitHubに上がっていれば、新しいMacを手に入れた時や、心機一転マシン内を全てクリーンインストールしたくなった時など、一発で今までの環境を手に入れられるというメリットもあります。

が、前述の通り、自分は「環境が全て記述されている」ことに心地よさを感じています。