Ansible Galaxyを使って楽々ロールの再利用
Ansibleには作成したロールをシェアするためのハブとしてAnsible Galaxyが用意されています。Ansible GalaxyによってChefのCommunity Cookbookのように他人が作成したAnsibleのロールを簡単に再利用することができます(もちろん自分で作成したロールを公開することも可能です)。
今回はこのAnsible Galaxyの仕組みを少し試してみたいと思います。Ansibleのバージョンは1.9.2を使います。
なおAnsibleの導入に関しては省略しますので、未導入の方はAnsibleとVagrantで開発環境を構築するなどを参考に導入してください。
目次
準備
例によってVagrantを利用して試してみましょう。
以下のようにディレクトリを作り、その中で作業していきます。MacもしくはLinuxなどで試してみてください。
$ mkdir try-ansible-galaxy $ cd try-ansible-galaxy
ディレクトリ内に以下の内容でVagrantfileを書きAnsibleのベストプラクティスに沿った形でインベントリファイルとトップレベルのプレイブックを作成してください。
Vagrantfile
VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "hansode/centos-6.5-x86_64" config.vm.network "private_network", ip: "192.168.33.10" end
provisioning/development
[nodejsservers] 192.168.33.10
provisioning/site.yml
--- - include: nodejsservers.yml
provisioning/nodejsservers.yml
--- - hosts: nodejsservers sudo: yes roles:
rolesは後ほど追加していきますので今は空のままにしておきます。
仮想マシンの起動
ここまでできたら
$ vagrant up
で仮想マシンを起動します。
nodejsservers.ymlが中途半端ですが、今回はVagrantのプロビジョニング機能は使わず、後ほどansible-playbookコマンドでプロビジョニングしますので気にせず起動してください。
ロールを探してインストールする
今回は試しにNode.jsをAnsible Galaxyから入れてみようと思います。
ロールを探す
まずはNode.jsをインストールするためのロールを探す必要があります。
ロールはAnsible GalaxyのサイトのBrowse Rolesのページで探すことができます。
カテゴリおよびロール名での絞り込みを行うことができ、ロール名、作者名、スコア、作成日などでのソートが可能です。
とりあえずの探し方としてはキーワードを入れてスコアで降順ソートするのがよさそうです。
ただしレーティング自体あまり使われていないようで、スコアが付いていないロールも多いです。そのため、このスコアも今のところはないよりマシ程度のものでしかありません。
ロールの互換性をチェックする
今回は node
で検索してスコアで降順ソートすると一番に表示されるJasonGiedymin.nodejsに目星をつけました。
目星をつけたらまずはJasonGiedymin.nodejsのページにあるSupported Platforms
やMinimum Ansible Version
といった項目をチェックします。
それを見るとこのロールはDebian系とRedhat系の両方に対応したロールで、Ansible 1.3以上ならば動作するようです。今回使うのはAnsible1.8.2でセットアップ対象の環境はCentOSなので問題ありませんね。
せっかくロールを見つけてもプラットフォームがサポート対象外で使えないことがままあります。ロールの検索フォームにはサポートするプラットフォームで絞り込む機能が欲しいところです。
ロールのインストール
見つけたロールは ansible-galaxy
コマンドで手元の環境にインストールすることができます。このコマンドはAnsibleをインストールしていれば使用可能です。
$ ansible-galaxy install JasonGiedymin.nodejs -p provisioning/roles
-p
オプションでインストール先をprovisioning/rolesに指定しています。この指定がない場合は/opt/local/etc/ansible/roles/
にインストールされます。
provisioning/nodejsservers.yml
nodejsservers.ymlにインストールしたロールを追加します。
--- - hosts: nodejsservers sudo: yes roles: - JasonGiedymin.nodejs
プロビジョニングの実行
これで全ての準備が整いました。ansible-playbook
で実行です。
$ ansible-playbook -i provisioning/development provisioning/site.yml -u vagrant
上のコマンドを実行すると、次のような結果が表示されます。
PLAY [nodejsservers] ************************************************************* GATHERING FACTS *************************************************************** The authenticity of host '192.168.33.10 (192.168.33.10)' can't be established. RSA key fingerprint is 10:13:56:d6:97:3e:66:25:01:c8:98:58:e0:75:63:e6. Are you sure you want to continue connecting (yes/no)? yes ok: [192.168.33.10] TASK: [JasonGiedymin.nodejs | Install Debian packages] ************************ skipping: [192.168.33.10] TASK: [JasonGiedymin.nodejs | Install RedHat packages] ************************ failed: [192.168.33.10] => (item=wget,curl,gcc-c++,gcc) => {"failed": true, "item": "wget,curl,gcc-c++,gcc"} msg: Failure talking to yum: Cannot retrieve repository metadata (repomd.xml) for repository: extras. Please verify its path and try again FATAL: all hosts have already failed -- aborting PLAY RECAP ******************************************************************** to retry, use: --limit @/Users/moongift/site.retry 192.168.33.10 : ok=1 changed=0 unreachable=0 failed=1
エラーが出ます。どうもyum周りで問題発生のようです。
yumの問題を修正するロールの作成
原因としては/etc/yum.repos.d/CentOS-Base.repo
の内容に問題があるため必要なyumのパッケージをインストールできないようです。
以下の行を
http://ftp.riken.jp/Linux/centos/6.5/updates/x86_64/repodata/repomd.xml
次のように修正すれば問題解決です。
http://ftp.riken.jp/Linux/centos/6/updates/x86_64/repodata/repomd.xml
これはfix-yum-cent-os-repoと言うアドホックなロールを作って直すことにします。
provisioning/roles/fix-yum-cent-os-repo/tasks/main.yml
--- - name: yum.repos.d/CentOS-Base.repo is fixed replace: dest=/etc/yum.repos.d/CentOS-Base.repo regexp="\$releasever" replace="6"
provisioning/nodejsservers.yml
nodejsservers.ymlに追加します。
--- - hosts: nodejsservers sudo: yes roles: - fix-yum-cent-os-repo - JasonGiedymin.nodejs
再度プロビジョニングの実行
今度こそ準備が整いました。再びansible-playbook
です。
$ ansible-playbook -i provisioning/development provisioning/site.yml -u vagrant
この実行結果は次のようになりました。
PLAY [nodejsservers] ************************************************************* GATHERING FACTS *************************************************************** ok: [192.168.33.10] TASK: [fix-yum-cent-os-repo | yum.repos.d/CentOS-Base.repo is fixed] ********** changed: [192.168.33.10] TASK: [JasonGiedymin.nodejs | Install Debian packages] ************************ skipping: [192.168.33.10] TASK: [JasonGiedymin.nodejs | Install RedHat packages] ************************ changed: [192.168.33.10] => (item=wget,curl,gcc-c++,gcc) TASK: [JasonGiedymin.nodejs | Checking installed version of nodejs] *********** failed: [192.168.33.10] => {"changed": true, "cmd": "/usr/bin/test \"$(/usr/local/bin/node -v 2> /dev/null)\" = v0.10.36", "delta": "0:00:00.003732", "end": "2015-01-17 09:34:59.096592", "rc": 1, "start": "2015-01-17 09:34:59.092860", "stdout_lines": []} ...ignoring TASK: [JasonGiedymin.nodejs | Download nodejs v0.10.36] *********************** changed: [192.168.33.10] TASK: [JasonGiedymin.nodejs | Verify SHASUM of nodejs v0.10.36] *************** changed: [192.168.33.10] TASK: [JasonGiedymin.nodejs | Unpack nodejs v0.10.36] ************************* changed: [192.168.33.10] TASK: [JasonGiedymin.nodejs | Compile and install nodejs v0.10.36] ************ changed: [192.168.33.10] TASK: [JasonGiedymin.nodejs | NPM Install global packages] ******************** failed: [192.168.33.10] => (item=nodemon) => {"failed": true, "item": "nodemon"} msg: Failed to find required executable npm failed: [192.168.33.10] => (item=debug) => {"failed": true, "item": "debug"} msg: Failed to find required executable npm failed: [192.168.33.10] => (item=foreman) => {"failed": true, "item": "foreman"} msg: Failed to find required executable npm FATAL: all hosts have already failed -- aborting PLAY RECAP ******************************************************************** to retry, use: --limit @/Users/moongift/site.retry 192.168.33.10 : ok=8 changed=7 unreachable=0 failed=1
またしてもエラーです。yumの問題はクリアしましたが、今度はsudoした際にnpmのパスが通っていないことに原因があるようです。
sudo時にパスを引き継ぐためのロールを作成
再びパッチ的なロールを作ります。
provisioning/roles/keep-user-path-in-sudo/tasks/main.yml
--- - name: keep $PATH for sudo lineinfile: dest=/etc/sudoers state=present line='Defaults env_keep += "PATH"' - name: disable secure_path for sudo lineinfile: dest=/etc/sudoers state=absent line='Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin'
provisioning/nodejsservers.yml
nodejsservers.ymlに追加します。
--- - hosts: nodejsservers sudo: yes roles: - fix-yum-cent-os-repo - keep-user-path-in-sudo - JasonGiedymin.nodejs
三度プロビジョニングの実行
今度こそ準備が整いました。三度 ansible-playbook
を実行します。
$ ansible-playbook -i provisioning/development provisioning/site.yml -u vagrant
今度の結果は次のようになります。
PLAY [nodejsservers] ************************************************************* GATHERING FACTS *************************************************************** ok: [192.168.33.10] TASK: [fix-yum-cent-os-repo | yum.repos.d/CentOS-Base.repo is fixed] ********** ok: [192.168.33.10] TASK: [keep-user-path-in-sudo | keep $PATH for sudo] ************************** changed: [192.168.33.10] TASK: [keep-user-path-in-sudo | disable secure_path for sudo] ***************** changed: [192.168.33.10] TASK: [JasonGiedymin.nodejs | Install Debian packages] ************************ skipping: [192.168.33.10] TASK: [JasonGiedymin.nodejs | Install RedHat packages] ************************ ok: [192.168.33.10] => (item=wget,curl,gcc-c++,gcc) TASK: [JasonGiedymin.nodejs | Checking installed version of nodejs] *********** ok: [192.168.33.10] TASK: [JasonGiedymin.nodejs | Download nodejs v0.10.36] *********************** skipping: [192.168.33.10] TASK: [JasonGiedymin.nodejs | Verify SHASUM of nodejs v0.10.36] *************** skipping: [192.168.33.10] TASK: [JasonGiedymin.nodejs | Unpack nodejs v0.10.36] ************************* skipping: [192.168.33.10] TASK: [JasonGiedymin.nodejs | Compile and install nodejs v0.10.36] ************ skipping: [192.168.33.10] TASK: [JasonGiedymin.nodejs | NPM Install global packages] ******************** changed: [192.168.33.10] => (item=nodemon) changed: [192.168.33.10] => (item=debug) changed: [192.168.33.10] => (item=foreman) PLAY RECAP ******************************************************************** 192.168.33.10 : ok=7 changed=3 unreachable=0 failed=0
エラーが出ずに完了しました。
変数でロールの動作を変更する
Node.jsのバージョン確認
さて一応Node.jsはセットアップできました。
しかしセットアップした仮想マシン上でNode.jsのバージョンを確認してみると・・・
$ node -v v0.10.36
少しバージョンが古いですね。
これを安定版の現時点での最新のものにバージョンアップしてみましょう。
JasonGiedymin.nodejsのvarsの確認
このロールではインストールするNode.jsのバージョンを変数で定義しているので、実はロールの内容を書き換えるなど面倒なことをしなくてもバージョンアップが可能です。
JasonGiedymin.nodejsの変数の内容を確認してみると以下のように動的に取得する仕組みになっています。
$ cat provisioning/roles/JasonGiedymin.nodejs/vars/main.yml nodejs_playbook_version: "0.1.5" nodejs_version_tag: "v{{nodejs_version}}" nodejs_file_tag: "node-{{nodejs_version_tag}}" nodejs_file_name: "{{nodejs_file_tag}}.tar.gz" nodejs_base_url: "http://nodejs.org/dist/v{{nodejs_version}}/" nodejs_tarball_url: "{{nodejs_base_url}}{{nodejs_file_name}}" nodejs_shasum_url: "{{nodejs_base_url}}SHASUMS.txt" m
これらの変数や設定はプレイブックや独自のロールで上書きすることができます。厳密には上書きではなく先に評価される場所に書いたものが有効になります。詳細は公式のドキュメントで確認してください。
なお変数は vars/main.yml
ではなくデフォルト変数として defaults/main.yml
などに定義されていることもあります。違いは簡単に言うとインベントリファイルの中で上書きできるか否かということになります。これに関しても詳細は公式のドキュメントで確認できます。
プレイブック内で変数の指定
今回はトップレベルのプレイブックで変数を指定するとしましょう。
provisioning/nodejsservers.yml
- hosts: nodejsservers sudo: yes roles: - fix-yum-cent-os-repo - keep-user-path-in-sudo - JasonGiedymin.nodejs vars: nodejs_version: "0.12.7"
または
--- - hosts: nodejsservers sudo: yes roles: - fix-yum-cent-os-repo - keep-user-path-in-sudo - { role: JasonGiedymin.nodejs, nodejs_version: "0.12.7" }
でもOKです。
実行&確認
今まで通りにansible-playbook
を実行したら仮想マシンにログインしてNode.jsのバージョンを確認してみてください。
$ node -v v0.12.7
ちゃんと指定したバージョンがインストールされているのが確認できました。
終わりに
今回は軽くAnsible Galaxyを利用してロールの再利用を試してみました。
選んだロールが意外とすんなり動かず「楽々〜」というのは少々タイトル詐欺になってしまった感がありますが、こういうことは実際に使ってみると多々あることなので、動かないものを動くように調整するところから実践してみました。
なお、こうしたトラブルはAnsibleだからではなく、Chefのクックブックでもしばしばあります。このあたりはセットアップ環境が様々なので致し方ないでしょう。ただ一からロールを作るよりは楽になるはずです。
今回は問題の解決に環境を調整するというアプローチを取りましたが、ロールの方を修正するという手もあります。Ansible Galaxyにロールを登録するためには必ずGitHubのリポジトリでロールを管理する必要がありますので、そのリポジトリをフォークして修正したり、その内容をフィードバックすることも簡単に行えます。
Ansible Galaxyを利用したロールの再利用は、本格的にAnsibleを運用していく上では不可欠といってもいい要素です。是非うまく使いこなして快適なAnsibleライフを送ってください!
Ansible Galaxy | Find, reuse, and share the best Ansible content