【CentOS × Ansible × serverspec】ansible-playbookからserverspecをインストールできない
はじめに
書籍『DevOps導入指南』に沿ってローカル環境でDevOpsっぽいツールのエコシステムを構築しようと思い立ち、2019年のお盆休みに作業を開始したものの、全367ページ中82ページにして早くも「Ansibleのplaybookからserverspecをインストールできない」というハプニングが発生。疑問に思った私は、この書籍の発行日を確認したところ、「2016年10月13日 初版 第1刷発行」と書かれていたのであった。。。
問題
書籍『DevOps導入指南』のp.82のコマンド
$ ansible-playbook -i development site.yml --diff
を実行すると、以下のエラーが発生。(実際には--diffオプションは使っていない結果ですが。。)
[DEPRECATION WARNING]: The TRANSFORM_INVALID_GROUP_CHARS settings is set to allow bad characters in group names by default, this will change, but still be user configurable on deprecation. This feature will be removed in version 2.10. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. [WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details PLAY [webservers] ************************************************************************************************** TASK [Gathering Facts] ********************************************************************************************* ok: [localhost] TASK [common : install epel] *************************************************************************************** ok: [localhost] TASK [nginx : install nginx] *************************************************************************************** changed: [localhost] TASK [nginx : replace index.html] ********************************************************************************** changed: [localhost] TASK [nginx : nginx start] ***************************************************************************************** changed: [localhost] TASK [serverspec : install ruby] *********************************************************************************** changed: [localhost] TASK [serverspec : install serverspec] ***************************************************************************** changed: [localhost] => (item=rake) failed: [localhost] (item=serverspec) => {"ansible_loop_var": "item", "changed": false, "cmd": "/bin/gem install --no-user-install --no-document serverspec", "item": "serverspec", "msg": "ERROR: Error installing serverspec:\n\tnet-ssh requires Ruby version >= 2.2.6.", "rc": 1, "stderr": "ERROR: Error installing serverspec:\n\tnet-ssh requires Ruby version >= 2.2.6.\n", "stderr_lines": ["ERROR: Error installing serverspec:", "\tnet-ssh requires Ruby version >= 2.2.6."], "stdout": "Successfully installed rspec-support-3.8.2\nSuccessfully installed rspec-core-3.8.2\nSuccessfully installed diff-lcs-1.3\nSuccessfully installed rspec-expectations-3.8.4\nSuccessfully installed rspec-mocks-3.8.1\nSuccessfully installed rspec-3.8.0\nSuccessfully installed rspec-its-1.3.0\nSuccessfully installed multi_json-1.13.1\n", "stdout_lines": ["Successfully installed rspec-support-3.8.2", "Successfully installed rspec-core-3.8.2", "Successfully installed diff-lcs-1.3", "Successfully installed rspec-expectations-3.8.4", "Successfully installed rspec-mocks-3.8.1", "Successfully installed rspec-3.8.0", "Successfully installed rspec-its-1.3.0", "Successfully installed multi_json-1.13.1"]} PLAY RECAP ********************************************************************************************************* localhost : ok=6 changed=4 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
原因
エラーメッセージに注目。
"msg": "ERROR: Error installing serverspec:\n\tnet-ssh requires Ruby version >= 2.2.6."
この本に沿って環境構築を進めると、rubyのバージョンが古すぎてserverspecが入らないようです。
$ ruby --version ruby 2.0.0p648 (2015-12-16) [x86_64-linux]
あと、冒頭に出てくるWarningも気になるので対応したい。
現在のAnsibleではgroup名の書き方が厳格になっているらしく、そのあたりでWarningが出ている模様。
結論
~/ansible-playbook-sample/roles/serverspec/tasks/main.ymlを下記のように変更する。
--- # tasks file for serverspec - name: exist ruby shell: bash -lc 'which ruby' register: ruby_install failed_when: ruby_install.rc not in [0,1] - name: install rbenv git: repo: https://github.com/sstephenson/rbenv.git dest: /usr/local/rbenv update: no - name: install ruby-build git: repo: https://github.com/sstephenson/ruby-build.git dest: /usr/local/rbenv/plugins/ruby-build update: no - name: add rbenv path blockinfile: path: /etc/profile.d/rbenv.sh block: | export RBENV_ROOT="/usr/local/rbenv" export PATH="/usr/local/rbenv/bin:$PATH" eval "$(rbenv init -)" create: yes - name: reflesh login shell shell: bash -lc 'source /etc/profile.d/rbenv.sh' - name: run install.sh shell: bash -l '/usr/local/rbenv/plugins/ruby-build/install.sh' become: true - name: install package-related-ruby yum: name: - bzip2 - gcc - openssl-devel - readline-devel - zlib-devel state: installed - name: install ruby 2.6.3 shell: bash -lc "rbenv install 2.6.3 && rbenv rehash && rbenv global 2.6.3" when: ruby_install.rc == 1 - name: provisioning gem shell: bash -lc 'rbenv shell 2.6.3' when: ruby_install.rc == 1 - name: install rake gem: name: rake state: present executable: /usr/local/rbenv/shims/gem - name: install serverspec gem: name: serverspec state: present user_install: no executable: /usr/local/rbenv/shims/gem
その他、~/ansible-playbook-sample/developmentと~/ansible-playbook-sample/productionの中のgroup名にある記述を下記のように変更。
- development-servers --> development_servers
- production-serveres --> production_servers
さらに、~/ansible-playbook-sample/group_varsのファイル名を変更。
- development-servers.yml --> development_servers.yml
- production-servers.yml --> production_servers.yml
これでOK。
あ、ひとつ注意。
このplaybookを回したあと、手動でserverspec-initを立ち上げるときは一度仮想環境からexitして再ログインが必要です。
これね↓
[vagrant@**** ~]$ exit
$ vagrant ssh
対策の概要
エラー対策
Warning対策
- group名の"-"(ハイフン)を"_"(アンダースコア)に置換
ポイント
- pathの管理
これが混乱の元凶。Ansibleはroot権限で実行するようだが、rbenvはそれ自身がRBENV_ROOTなるpathを持っているようで、思ったように動作してくれず大いに悩んだ。
- インストール先の設定
root権限だけであれば機能するplaybookを作れたのだが「全ユーザで手動でもserverspecをいじれるようにしたい!」と欲張ったために更に時間がかかった。。
rbenvのインストール
- name: install rbenv git: repo: https://github.com/sstephenson/rbenv.git dest: /usr/local/rbenv update: no
全ユーザに適用するために、インストール先を/usr/local/rbenvに指定。
[ruby][rbenv][System Wide Install]全ユーザーrubyを使えるようにする – ADACHIN SERVER LABO
CentOS7 全体でユーザ共通に使える rbenv をインストールする - らくがきちょう
システムワイドにrbenvを入れる - 私事ですが……
ruby-buildのインストール
- name: install ruby-build git: repo: https://github.com/sstephenson/ruby-build.git dest: /usr/local/rbenv/plugins/ruby-build update: no
こちらは/<rbenvのインストール先>/plugins/ruby-buildにインストールしないと、あとでrbenvに「installなんて知らない!」と怒られる。
rbenvとruby-buildインストール時に no such command `install' が出た原因と対処法 - Javaエンジニア、React+Redux+Firebaseでアプリを作る
- name: add rbenv path blockinfile: path: /etc/profile.d/rbenv.sh block: | export RBENV_ROOT="/usr/local/rbenv" export PATH="/usr/local/rbenv/bin:$PATH" eval "$(rbenv init -)" create: yes - name: reflesh login shell shell: bash -lc 'source /etc/profile.d/rbenv.sh' - name: run install.sh shell: bash -l '/usr/local/rbenv/plugins/ruby-build/install.sh' become: true
この設定にかなり手間取った。
まだ混乱や冗長な部分もあると思うけど、一番のポイントはたぶん、/etc/profile.d/rbenv.shを作り、そこでRBENV_ROOTを指定すること。
これを設定しないばっかりに、「rbenvなんてない!」と怒られまくりました。。
rubyの依存パッケージのインストール
- name: install package-related-ruby yum: name: - bzip2 - gcc - openssl-devel - readline-devel - zlib-devel state: installed
rubyをインストールする前に依存パッケージをインストールしないと怒られる。
これは調べればすぐに出てきたし、そこまで難しくなかったかな。
指定バージョンのrubyをインストール
- name: install ruby 2.6.3 shell: bash -lc "rbenv install 2.6.3 && rbenv rehash && rbenv global 2.6.3" when: ruby_install.rc == 1 - name: provisioning gem shell: bash -lc 'rbenv shell 2.6.3' when: ruby_install.rc == 1
この記述自体はすぐに分かったんだけど、その前のpath設定が難しすぎていつもここでansibleが止まったので色々といじりまわした部分。
結果、ここが原因ではなかったという。。
rake & serverspecをインストール
- name: install rake gem: name: rake state: present executable: /usr/local/rbenv/shims/gem - name: install serverspec gem: name: serverspec state: present user_install: no executable: /usr/local/rbenv/shims/gem
途中、rakeのインストールはどのユーザでも使えるのにserverspecはうまくいかない謎の現象が発生し混乱した部分。
調べると、serverspecはデフォルトインストールだと/rootの中に入っちゃうらしく、user_installをnoに設定して解決。
これにも意外と時間を使ってしまった。。
まとめ
この記事もまだ整理しきれておらず、記述に混乱があると思われます。
また、結論に記載したタスクも冗長な部分が残っていると思います。
というのも、1つの問題に対する対策が新たな問題を引き起こし、二重三重の対策を施すうちにどの対策がどの問題を解決したか、あるいは、どの問題が未然に防がれたかがもはや把握できていなくなったからです。笑
まぁ、でも、ひとまずこれでまた本に沿って次に進めるようになりました。
DevOpsへの道は険しいなぁ。。
DevOps導入指南 Infrastructure as Codeでチーム開発・サービス運用を効率化する (DEV Engineer’s Books)
- 作者: 河村聖悟,北野太郎,中山貴尋,日下部貴章,株式会社リクルートテクノロジーズ
- 出版社/メーカー: 翔泳社
- 発売日: 2016/10/14
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る