production.log

株式会社リブセンスでエンジニアをやっている星直史のブログです。

@t_wada さんの「Mac の開発環境構築を自動化する (2015 年初旬編)」をAnsible ベストプラクティスに則り書き換えてみた

概要

t-wada.hatenablog.jp

Ansibleでmacの環境構築する際、id:t-wada さんの上記の記事を参考したのですが、 Ansible Best Practicesに沿っていなかったので、書き直してみました。

Ansibleを動かすまで

こちらは、t_wadaさんの記事のままです。

sudo xcodebuild -license
xcode-select --install
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew doctor
brew update
brew install python
brew install ansible

どこを直したのか

twada/macbook-provisioning

hoshinaoshi/macbook-provisioning

本家とforkしたリポジトリを比較しながら、修正した点を挙げていきます。 階層構造も修正しています。

【本家】

.
├── LICENSE
├── README.md
├── hosts
├── localhost.yml

【修正後】

.
├── LICENSE
├── README.md
├── ansible.cfg
├── group_vars
├── hosts
├── localhost.yml
├── roles
│   ├── homebrew
│   │   ├── defaults
│   │   ├── files
│   │   ├── handlers
│   │   ├── meta
│   │   ├── tasks
│   │   │   └── main.yml
│   │   ├── templates
│   │   └── vars
│   │       └── main.yml
│   ├── homebrew-cask
│   │   ├── defaults
│   │   ├── files
│   │   ├── handlers
│   │   ├── meta
│   │   ├── tasks
│   │   │   └── main.yml
│   │   ├── templates
│   │   └── vars
│   │       └── main.yml
│   ├── oh-my-zsh
│   │   ├── defaults
│   │   ├── files
│   │   ├── handlers
│   │   ├── meta
│   │   ├── tasks
│   │   │   └── main.yml
│   │   ├── templates
│   │   └── vars
│   └── ricty
│       ├── defaults
│       ├── files
│       ├── handlers
│       │   └── main.yml
│       ├── meta
│       ├── tasks
│       │   └── main.yml
│       ├── templates
│       └── vars
└── site.yml

*1

site.ymlを作成し、localhost.ymlをinclude

ベストプラクティスではsite.ymlをmaster playbookとします。 また、プロビジョニング対象の役割(production, stagingなど)ごとに実行するroleをまとめたplaybookも作ります。 今回はlocalhost.ymlのみですね。*2

これらのファイルはroleをincludeするだけに留め、ここに細かいタスクを書いていくことはしません。(後述)

ロールの割り振り

元々のlocalhost.ymlのタスクは大きく4つの処理をしています。

  • homebrew
  • homebrew-cask
  • oh-my-zsh
  • ricty

今回はローカル環境のみが対象ですが、複数のプロビジョニング対象があった場合に、個別に差し込めるようにするため、 これらのタスクをrolesディレクトリ配下にそれぞれの役割ごとに分割します。 directory-layout

loclhost.ymlに列挙された変数を各ロールに振り分ける。

loclhost.ymlにhomebrew_taps, homebrew_packages, homebrew_cask_packagesの3つが定義されていましたが、 これらはhomebrewとcaskで使用するので、

  • ./roles/homebrew/vars/main.yml
  • .roles/homebrew-cask/vars/main.yml

に記述します。

./roles/hogehoge/vars/main.ymlに変数を記述すると
./roles/hogehoge/tasks/main.ymlの実行時に自動で変数を読み込み、タスク内で使用することができます。

localhost.ymlに記述されているhandlersはricty用なので、ricty/handlers/main.ymlに移動

localhost.ymlに記述されているhandlerは、よく見るとRicty用の処理であるため、Rictyロールのhandlerとして定義します。 こちらは、varsと同様にhandlerも同role内のhandlerディレクトリに記述していれば、notifyをした際に呼び出されます。

- name: run fc-cache
  shell: fc-cache -vf

localhost.ymlでtasksとして記述された内容をroleに任せる。

これらのファイルはロールをインクルードするだけに留め、ここに細かいタスクを書いていくことはしません。(後述)

ここまでの書き換えで、各ロールにvars, tasks, handlerを分けることができたので、 localhost.ymlではロールをインクルードするだけにします。

---
- name: Setup my MacBook
  hosts: localhost
  connection: local
  gather_facts: no 
  roles:
    - { role: homebrew,      tags: [ homebrew ] }
    - { role: homebrew-cask, tags: [ homebrew-cask ] }
    - { role: oh-my-zsh,     tags: [ oh-my-zsh ] }
    - { role: ricty,         tags: [ ricty ] }

だいぶスッキリしましたね。

また、tagを切っておくと、指定したタグだけ実行 / 指定したタグをスキップなどができるので、追加しておきます。 ansible-playbook site.yml --tags "homebrew,ricty" ansible-playbook site.yml --skip-tags "oh-my-zsh"

playbook実行時の引数を極力減らせるように設定

HOMEBREW_CASK_OPTS="--appdir=/Applications" ansible-playbook -i hosts -vv localhost.yml

実行時にhostsの設定をしたり、HOMEBREW_CASK_OPTSを設定したりするのはめんどくさいので、

ansible.cfgを作成し、デフォルトの動作を設定をします。

[defaults]
hostfile = ./hosts

環境変数については、homebrew-caskのタスクの一部として実行するようにします。

- name: HOMEBREW_CASK_OPTS設定
  shell: export HOMEBREW_CASK_OPTS="--appdir=/Applications"
...後続の処理がずらずら〜

ここまでの設定で、実行時のコマンドが HOMEBREW_CASK_OPTS="--appdir=/Applications" ansible-playbook -i hosts -vv localhost.ymlansible-playbook -vv site.yml となりました。 シンプル!

まとめ

以上でAnsible ベストプラクティスを適用した、Mac の開発環境構築を自動化する (2015 年初旬編)です。

"mac ansible"などで検索すると、localhost.ymlにtasksがばーーーーーっと書かれたplaybookをよく目にする印象があります。

複数のプロビジョニング対象が存在する場合は、ベストプラクティスが有効だと思いますが、 構築する対象がローカル環境のみで、処理(や、ロール)が少ないのであれば、1ファイルにゴリゴリ書いても良いのではないかと感じました。

ただ、実際は、開発スタートをするまでにrbenvの設定をしたり、ミドルウェアの設定をしたりなんだりすると、localhost.ymlが肥大化してしまうのではないかと考えられるため、早め早めにロールだけでも分けて記述するのが落とし所かと思います。

こちらにコードを置いておきます。
https://github.com/hoshinaoshi/macbook-provisioning

今回Ansibleを初めて触ってみたのですが、ymlで書くのが地味に楽でした。
Ansibleの処理も「Ansible {{やりたいコマンド}}」で検索 => 1つ目の記事ではい理解〜というような感じでした。
自分は、初めての技術に触れるときは、初心者用の書籍を購入して、一読するのですが、Ansibleにおいては下記の書籍を買いました。

*1:中身が空のディレクトリは削除しても良いかも

*2:通常は複数のサーバーに対して行うので、若干無理矢理感がありますね