Mac用開発環境設定をできるだけ自動化してみる / Ansible

先日、MacBook Pro 13インチ Early 2015 を購入したついでに、AnsibleとHomebrewを使って開発ツールやアプリのインストールをできるだけ自動化してみたので、その備忘録を残します。

Xcodeのインストール

何はともあれXcodeが必要なのでターミナルでインストール。

sudo xcodebuild -license

下記を言われた後にダイアログが出たのでインストール。

xcode-select: note: no developer tools were found at '/Applications/Xcode.app', requesting install. Choose an option in the dialog to download the command line developer tools.

一応バージョン確認。

xcodebuild -version

エラーを吐かれる。

error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance

とりあえず下記を実行。

xcode-select --install

インストールはされてる模様。

error: command line tools are already installed, use "Software Update" to install updates

パスを確認。

xcode-select -print-path
/Library/Developer/CommandLineTools

よくわからないのでApp Storeから手動でインストール。
しばらく待つ。3時間ほど。

もう一度バージョン確認。

xcodebuild -version
Xcode 8.1
Build version 8B62

もう一度パスを確認。

xcode-select -print-path
/Applications/Xcode.app/Contents/Developer

通っているパスが変わっている。設定が上書きされている模様。
なお、xcode-select –install はOSをアップデートするたびに実行しないといけないみたい。

Homebrewのインストール

とりあえずMacにデフォルトでインストール済みのrubyを使って…

$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

確認

brew doctor
-bash: brew: command not found

パスを通す必要がある模様

その前に不可視ファイルを見えるようにしなければ。

defaults write com.apple.finder AppleShowAllFiles TRUE

Finderを再起動

killall Finder

これで不可視ファイルが見える。
.bash_profileをユーザーディレ直下に作成して下記を記述。

export PATH=/usr/local/bin:/usr/local/sbin:$PATH

もう一度確認

brew doctor
-bash: brew: command not found

パスが通らない。

…と、ここで、usr/local/Homebrewを確認してみるとディレ内が空な事に気づく。
ググるとXcodeの使用許諾にagreeしないとHomebrewがインストールできないことがわかる。

Xcodeを開いてagree。閉じる。

もう一度Homebrewをインストールしてみる。

$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

もう一度確認

brew doctor
Your system is ready to brew.

usr/local/Homebrewにファイルが存在するし、Homebrewがインストールできたようだ。

Ansibleのインストール

目的はこれだった。

brew install ansible

確認

ansible --version
ansible 2.2.0.0
  config file = 
  configured module search path = Default w/o overrides

インストールできた模様。

Pythonのインストール

MacにはPythonが入っているけど、最新を使いたいので入れておく。

brew install python

確認

python -V
Python 2.7.12

OK。小文字の -vで実行すると、よくわからないことになる。

Homebrew Caskのインストール

プロビジョニングファイルの作成の前にGUIアプリ管理用のCaskをインストール。先に入れておけばインストールしたいアプリのnameを調べられるので。

brew install caskroom/cask/brew-cask

Homebrew Caskオプションの設定を.bash_profileに追記

export HOMEBREW_CASK_OPTS="--appdir=/Applications"

PATH設定の反映

source ~/.bash_profile

プロビジョニングファイルの作成

設定ファイル格納ディレを下記の名前でユーザーディレ直下に作成

mac-provisioning-ansible

cdしてファイル作成していく。

inventoryファイルの作成

echo 'localhost' > hosts

(hostsファイルを作成して’localhost’を記述の意味)

playbookファイルの作成

ファイル名はlocalhost.ymlにしておく。

Macの開発環境構築をAnsibleで自動化する | QUARTETCOM TECH BLOGを参考にさせてもらって、homebrewをアップデートするだけの記述をしてみる。

- hosts: localhost
  connection: local
  gather_facts: no
  sudo: no
  tasks:
    # homebrewをアップデート
    - name update homebrew
    homebrew: update_homebrew=yes

実行してみる。

ansible-playbook -i hosts -vv localhost.yml

動いたけどWARNINGが出る。

[DEPRECATION WARNING]: Instead of sudo/sudo_user, use become/become_user and 
make sure become_method is 'sudo' (default).
This feature will be removed in a 
future release. Deprecation warnings can be disabled by setting 
deprecation_warnings=False in ansible.cfg.

Ansible ver1.9からはsudoをbecomeにすればいいらしい。
記述を変更し、もう一度実行するとWARNINGは出なくなった。
さらにググると書き方そのものがver1.9から色々と変わっていることがわかり、このあと、先人のGitHubを漁ることになる。

nodebrewのインストール

playbookファイルに記述して、nodebrewを自動インストールする前に試しに手動インストールしてみる。

brew install nodebrew

.bash_profileに下記を追記。

export PATH=$HOME/.nodebrew/current/bin:$PATH

nodejs安定版のインストール

A.インストール

nodebrew install-binary stable

ディレクトリが無い、と怒られる。

B.ホーム直下にディレクトリ作成

$ mkdir ~/.nodebrew
$ mkdir ~/.nodebrew/src

srcディレを.nodebrewディレ内に作る必要あり。

再度実行。

nodebrew install-binary stable

インストールできたようなので、nodeのバージョンを確認。

nodebrew ls
v7.1.0
current: none

C.使用するnodeのバージョンを指定。

nodebrew use v7.1.0

nodeが使えるようになっているか確認するため使用中のバージョンを確認。

node -v
v7.1.0

npmも確認。

npm -v
3.10.9

このあと、ディレクトリ作成B以外のAとCを自動化することにした。

ディレクトリ作成の自動化

2016年12月23日に追記しました。

Bを自動化するため、[ansible]ディレクトリ作成はfileモジュールで! – ADACHIN SERVER Labを参考にnodebrew/tasks/main.ymlに下記を追加しました(ディレクトリリスト変数はlocalhost.ymlに)。

- name: nodebrewインストール用ディレクトリの存在チェック
  stat:
    path: "{{ home_dir }}/{{ nodebrew_dir }}"
  register: nb_directory_created

- name: nodebrewインストール用ディレクトリ作成
  file: 
    path: "{{ home_dir }}/{{ item.name }}"
    state: directory
    mode: 0755
  when: not nb_directory_created.stat.exists
  with_items: "{{ nodebrew_dir }}"

rbenvのインストール

こちらも自動インストールはせず、まずは手動で。

brew install rbenv

.bash_profileに下記を追記。

eval "$(rbenv init -)”

eval “$(rbenv init -)”は、$RBENV_ROOT/shimsをPATHに追加するために必要。

現時点でインストールされるべきrubyの安定版バージョンを調べる。
rbenvでRubyの最新安定版をインストールするワンライナー | mawatari.jpを参考にさせていただいた。

rbenv install -l | grep -v - | tail -1
2.3.3

rubyインストールについてはこのあと、自動化のためのplaybookを作成し、そのまま走らせてみた。
うまくいった。

rbenvのデフォルトルートディレクトリを確認

rbenv root
/Users/(ユーザー名)/.rbenv

使用中のrubyのバージョンを確認(ruby -v でもいい)

rbenv version
ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-darwin16]

ツール類のインストール

よく使うツールを手動インストール

Grunt

sudo npm install -g grunt-cli

Bower

npm install -g bower

このあと、playbookに追加し、テストで走らせる。gemの処理も追加した。

実行コマンドのMakefile化

2016年12月22日に追記しました。

https://github.com/takuan-osho/macbook-provisioning/blob/master/Makefileを参考にさせていただきました。

現時点のlocalhost.yml

見渡しを良くするために、あえてインストールする開発ツールやアプリはlocalhost.ymlに入れてみた。
role分けは、いきなり行ったわけではなく作りながら行った。

nodebrewやrbenvの処理は下記をかなり参考(というかほぼコピー)にさせていただいた。
https://github.com/djyugg/ansible-role-nodebrew/blob/master/tasks/main.yml
https://github.com/hnakamur/ansible-role-osx-rbenv/blob/master/tasks/main.yml

完全自動化までは、ほど遠い。

…というわけで一旦GitHubに上げてます。
https://github.com/skrd/mac-provisioning-ansible

コンフィグファイルの追加

2020年4月13日に追記しました。

下記の警告を消したかったので対応。

[WARNING]: Platform darwin on host localhost is using the discovered Python interpreter at /usr/bin/python, but future
installation of another Python interpreter could change this. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.

ターゲットノード(対象サーバ)で使用するPythonのバージョンを指定できるようになっていたらしい。実行ディレ直下に「ansible.cfg」を追加して、イベントリファイルとPythonのパス指定を記述。

ansible.cfg

[defaults]
inventory = hosts
interpreter_python=/usr/bin/python3

Homebrew-caskとHomebrew-cask-versionsのtap

2018年7月4日に追記しました。

エラーを吐くようになったので下記を修正しました。

エラー内容

failed: [localhost] (item=caskroom/cask) => {"changed": false, "item": "caskroom/cask", "msg": "added: 0, unchanged: 0, error: failed to tap: caskroom/cask"}
failed: [localhost] (item=caskroom/versions) => {"changed": false, "item": "caskroom/versions", "msg": "added: 0, unchanged: 0, error: failed to tap: caskroom/versions"}

localhost.yml

# - caskroom/cask
# - caskroom/versions
- homebrew/cask
- homebrew/cask-versions

brew tap の結果

$ brew tap
homebrew/cask
homebrew/cask-versions

実際にusr/local/Homebrew/Library/Taps/ の中を見てみるとcaskroomディレの中は空。一方、homebrewディレにはhomebrew-caskとhomebrew-cask-versionsディレが存在。brew tapの内容と同じなので素直にlocalhost.ymlでの指定を修正することにしました。環境によっては、この変更が原因でエラーを吐くことがあるかも、です。