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:通常は複数のサーバーに対して行うので、若干無理矢理感がありますね