Playbookを作成する
それでは、実際にNode.jsの開発環境をローカルマシンに構築する基本となるPlaybookを作成します。ディレクトリは前章に習って構成してください。まずは、hostsファイルを作成します。localhostというグループに127.0.0.1(つまり、自分自身)のマシンを追加してください。
[localhost] 127.0.0.1
次に、group_vars/allにあらかじめインストールするNode.jsのバージョン情報を定義します。今回はNode.jsのインストールにnodebrewを使用しますので、同時にnodebrewへのPATHも定義しておきます。
nodejs_version: v0.12.5 nodebrew_path: ~/.nodebrew/current/bin
site.ymlに、localhostに対して後ほど作成するnodejs roleを実行させるように記述します。
- hosts: localhost
connection: local
environment:
PATH: "{{ ansible_env.PATH }}:{{ nodebrew_path }}"
roles:
- nodejs
Ansibleでは基本的に.bash_profileなどでexportされる値は参照できないため、必要に応じて明示的に定義する必要があります。{{ ansible_env }}は環境変数を表し、先ほど定義した変数{{ nodebrew_path }}を連結したものをAnsible実行時の環境変数$PATHとして扱います。Ansibleで扱われる変数についての詳細は、公式ドキュメントのVariablesを参照してください。
Playbookは以下のコマンドで実行します。現時点ではnodejs roleが作成されていないため、エラーとなります。
$ ansible-playbook -i hosts site.yml
get_url moduleを使ってURLからnodebrewを取得する
get_url moduleは、wgetやcurlコマンドに相当するタスクを扱うmoduleです。roles/nodejs/tasks/main.ymlを作成し、以下のように記述します。
- name: download nodebrew
get_url:
url: http://git.io/nodebrew
dest: ~/nodebrew
このように、nameではじまるブロックが1つのタスクとして扱われます。nameはタスク名を表し、自由に設定して構いませんが、同じ名前のタスクが存在しないよう必ず一意の名前にします。また、今回使用されているget_url module固有のオプションについては、下記のとおりです。
| parameter | required | default | 利用可能な値 | 説明 |
|---|---|---|---|---|
| url | yes | HTTP,HTTPS,FTP形式のURLを指定します。 | ||
| dest | yes | 取得したファイルの出力先を指定します。 |
moduleにオプションを渡す際、今回はyml形式で指定していますが、url=http://git.io/nodebrew dest=~/nodebrewのような記述方式もあります。
shell moduleを使ってnodebrew installを実行する
次に、nodebrewとNode.jsのインストールを行います。Ansibleには多くのmoduleが存在しますが、常に適したmoduleが存在するとは限りません。そういった場合に役立つのが、shell moduleです。shell moduleは、文字列として渡した任意のコマンドを/bin/shを通して実行します。
- name: install nodebrew
shell: perl ~/nodebrew setup
- name: install nodejs
shell: nodebrew install-binary {{ nodejs_version }}
- name: swhich version
shell: nodebrew use {{ nodejs_version }}
shell moduleを利用することで、シェルスクリプトに近い形でタスクを定義することができますが、Ansibleではタスクごとにshellが起動されますので、変数などは引き継がれない点に注意してください。また、「Playbookを作成する」でも述べた通り、環境変数が参照されないため、実行開始時にパスの通っていないコマンドは実行することができません。
Registered Variablesを使って、べき等性を保つ
開発環境の継続的な管理を行うためには、初期構築以降もPlaybookの更新を反映するために、繰り返し実行できる状態である必要があります。shell moduleではタスクが機械的に実行されてしまうため、繰り返し実行すべきでないタスクに関しては、registerとwhenを利用したタスク実行制御を行います。今回の場合nodebrew installが実行される際、指定したバージョンのNode.jsがすでにインストール済みの場合、エラーとなってしまいますので、registerとwhenを使って、バージョン判定の処理を加えます。
- name: installed check
shell: nodebrew list | grep {{ nodejs_version }}
ignore_errors: True
register: nodejs_installed
- name: install nodejs
shell: nodebrew install-binary {{ nodejs_version }}
when: nodejs_installed|failed
- name: swhich version
shell: nodebrew use {{ nodejs_version }}
registerは定義するとタスクの実行結果を変数として保持し、whenはregisterの値によってタスクの実行を制御します。installed checkでは、インストール済みのNode.jsのバージョン情報の一覧から{{ nodejs_version }}を探しますが、存在しない場合failedがnodejs_installedに入ります。そうして、nodejs_installedがfailedの場合のみ、install nodejsタスクが実行されることになります。
lineinfile moduleを使って設定ファイルに追記する
次に、lineinfile moduleを使って、.bash_profileにnodebrewが使用するディレクトリにパスを通すための追記します。lineinfile moduleでは非常に多くのオプションがありますが、今回は最もシンプルな例を紹介します。
- name: export nodebrew path
lineinfile:
dest: ~/.bash_profile
state: present
create: yes
line: 'export PATH={{nodebrew_path}}:$PATH'
| parameter | required | default | 利用可能な値 | 説明 |
|---|---|---|---|---|
| dest | yes | 追記するファイルのパスを指定します。 | ||
| state | no | present | present, absent | コマンド実行時のあるべき状態を指定します。 |
| create | no | no | yes/no | ファイルが存在しない場合にファイルを作成するか否かを指定します。 |
| line | no | no | yes/no | ファイルに追記する文字列を指定します。 |
lineinfileでは、state: presentにすることで、複数回実行された場合にもすでに追記された行が存在する場合は自動的にこのタスクがスキップされるため、実行するごとに行が増えていくことはありません。
