Edited at

AnsibleでHomebrew, Cask, Atomエディターのパッケージを管理する

More than 3 years have passed since last update.


はじめに

HomebrewとHomebrew CaskのパッケージはBrewfileを使う方法もありますが、Brewfileにパッケージを追加して2回目以降の実行ではalready installedとかの警告が多数出てあまり気分がよくありません。また、Atomエディターのパッケージはapmコマンドで管理できますが、これらをまとめてAnsibleで管理すればスッキリできるということで、やってみました。

Ansible用のroleを3個とapmのモジュールを作成し、ansible-galaxy を使ってみた - @znz blogを参考にAnsible Galaxyに登録しましたので、簡単に利用できます。


利用手順


HomebrewとPythonとAnsibleのインストール

xcode-select --install

ここで一度Xcodeを起動してライセンスに同意してください。

ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"

brew install python
brew install ansible


Homebrew, Cask, Atomパッケージ管理用のAnsible roleをダウンロード

ここでは~/ansible-workを作業ディレクトリとします。

mkdir ~/ansible-works

cd ~/ansible-works
ansible-galaxy install --roles-path=. hnakamur.homebrew-packages
ansible-galaxy install --roles-path=. hnakamur.homebrew-cask-packages
ansible-galaxy install --roles-path=. hnakamur.atom-packages


インベントリファイルを作成

Homebrewでインストールした場合は/usr/local/etc/ansible/hostsがインベントリファイルになります。

以下のようにファイルを作ります。

mkdir -p /usr/local/etc/ansible

echo localhost > /usr/local/etc/ansible/hosts


localhost.yamlを作成

下記のような感じでlocalhost.yamlを作成します。使いたいパッケージに合わせて適宜調整してください。


localhost.yaml

- hosts: localhost

connection: local
gather_facts: no
sudo: no
vars:
homebrew_packages_taps:
- homebrew/binary
- homebrew/dupes
homebrew_packages_packages:
- { name: readline }
- { name: openssl, state: linked }
- { name: ansible }
- { name: cmake }
- { name: ctags }
- { name: direnv }
- { name: docker }
- { name: git }
- { name: jq }
- { name: hub }
- { name: imagemagick }
- { name: mercurial }
- { name: mysql }
- { name: packer }
- { name: pkg-config }
- { name: pwgen }
- { name: python }
- { name: reattach-to-user-namespace }
- { name: redis }
- { name: subversion }
- { name: the_silver_searcher }
- { name: tig }
- { name: tmux }
- { name: whois }
- { name: xz }
- { name: vim }
- { name: wget }
- { name: zsh, install_options: disable-etcdir }
homebrew_cask_packages_packages:
- atom
- calibre
- firefox
- google-chrome
- google-japanese-ime
- grandperspective
- hipchat
- iterm2
- java
- keepassx
- kindle
- mysqlworkbench
- skype
- spark
- vagrant
- virtualbox
- zeroxed
atom_packages_packages:
- project-manager
- recent-files
roles:
- hnakamur.homebrew-packages
- hnakamur.homebrew-cask-packages
- hnakamur.atom-packages


ansibleを実行

ansible-playbook localhost.yml


2回目以降の実行結果

% ansible-playbook localhost.yml

PLAY [localhost] **************************************************************

TASK: [hnakamur.homebrew-packages | homebrew_tap tap= state=present] **********
ok: [localhost] => (item=homebrew/binary)
ok: [localhost] => (item=homebrew/dupes)

TASK: [hnakamur.homebrew-packages | homebrew update_homebrew=yes] *************
ok: [localhost]

TASK: [hnakamur.homebrew-packages | homebrew name={{item.name}} state={{item.state|default("latest")}} install_options={{item.install_options|default()}}] ***
ok: [localhost] => (item={'name': 'readline'})
changed: [localhost] => (item={'state': 'linked', 'name': 'openssl'})
ok: [localhost] => (item={'name': 'ansible'})
ok: [localhost] => (item={'name': 'cmake'})
ok: [localhost] => (item={'name': 'ctags'})
ok: [localhost] => (item={'name': 'direnv'})
ok: [localhost] => (item={'name': 'docker'})
ok: [localhost] => (item={'name': 'git'})
ok: [localhost] => (item={'name': 'jq'})
ok: [localhost] => (item={'name': 'hub'})
ok: [localhost] => (item={'name': 'imagemagick'})
ok: [localhost] => (item={'name': 'mercurial'})
ok: [localhost] => (item={'name': 'mysql'})
ok: [localhost] => (item={'name': 'packer'})
ok: [localhost] => (item={'name': 'pkg-config'})
ok: [localhost] => (item={'name': 'pwgen'})
ok: [localhost] => (item={'name': 'python'})
ok: [localhost] => (item={'name': 'reattach-to-user-namespace'})
ok: [localhost] => (item={'name': 'redis'})
ok: [localhost] => (item={'name': 'subversion'})
ok: [localhost] => (item={'name': 'the_silver_searcher'})
ok: [localhost] => (item={'name': 'tig'})
ok: [localhost] => (item={'name': 'tmux'})
ok: [localhost] => (item={'name': 'whois'})
ok: [localhost] => (item={'name': 'xz'})
ok: [localhost] => (item={'name': 'vim'})
ok: [localhost] => (item={'name': 'wget'})
ok: [localhost] => (item={'install_options': 'disable-etcdir', 'name': 'zsh'})

TASK: [hnakamur.homebrew-cask-packages | homebrew_tap tap=caskroom/cask state=present] ***
ok: [localhost]

TASK: [hnakamur.homebrew-cask-packages | homebrew name=brew-cask state=latest] ***
ok: [localhost]

TASK: [hnakamur.homebrew-cask-packages | homebrew_cask name= state=installed] ***
ok: [localhost] => (item=atom)
ok: [localhost] => (item=calibre)
ok: [localhost] => (item=firefox)
ok: [localhost] => (item=google-chrome)
ok: [localhost] => (item=google-japanese-ime)
ok: [localhost] => (item=grandperspective)
ok: [localhost] => (item=hipchat)
ok: [localhost] => (item=iterm2)
ok: [localhost] => (item=java)
ok: [localhost] => (item=keepassx)
ok: [localhost] => (item=kindle)
ok: [localhost] => (item=mysqlworkbench)
ok: [localhost] => (item=skype)
ok: [localhost] => (item=spark)
ok: [localhost] => (item=vagrant)
ok: [localhost] => (item=virtualbox)
ok: [localhost] => (item=zeroxed)

TASK: [hnakamur.atom-packages | apm name= state=latest] ***********************
ok: [localhost] => (item=project-manager)
ok: [localhost] => (item=recent-files)

PLAY RECAP ********************************************************************
localhost : ok=7 changed=1 unreachable=0 failed=0

homebrewモジュールでstate=linkと指定した場合は常にchanged=1となってしまうのがイマイチですが、それ以外はchangedにならずokが並んでいい感じです。