おふくろさまより愛をこめて

mmmpa ふとしです。誠実なプログラミングを心がけたい。

Ansible で rbenv をインストールする role を書いた

インフラ構成をできるだけ属人性を低くしつつ再現性を高くしたくて Ansible を触っています。Ansible は知識がない状態だと設定ファイルについて全くもって全景がとらえにくい === とてもとっかかりづらいという問題があります。しかし、そこを過ぎた処理設定自体はものすごく平易に書けるので素敵なツールだと感じています。

そこで、Ansible を使い慣れるのも兼ねて、rbenv がすでにある場合や ruby-version がすでにインストールされている場合はスキップ、ない場合は rbenv の update や ruby-version のインストールを行う role を書いてみました。

わたしの従来の rbenv インストール

rbenv について、従来は以下のような粗雑な shell ファイルを用意しインストールを行っていました。そしてバージョンの update が必要な場合は ssh で接続し、ruby-build のバージョンを上げ、ビルドしなおすという運用をしていました。

sudo yum -y install bzip2 gcc* openssl-devel readline-devel zlib-devel

git clone https://github.com/rbenv/rbenv.git ~/.rbenv
cd ~/.rbenv && src/configure && make -C src

echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build

~/.rbenv/bin/rbenv install 2.5.3

rbenv/tasks/main.yml

上記 shell ファイルを単純にそのまま Ansible role に書き下すのは、shell モジュールを用いて置き換えればいいだけなので非常に簡単です。しかしこれを何度も行った場合は少し問題があります。rbenv は都度ビルドされ、export PATH="$HOME/.rbenv/bin:$PATH" がどんどん書き足されていってしまいます。

そこで Check rbenv Check installed ruby version といった tasks で状態を把握して処理を切り替えます。

- name: Check rbenv
  shell: ~/.rbenv/bin/rbenv --version
  register: rbenv_exists
  changed_when: False
  ignore_errors: yes

- name: Check installed ruby version
  shell: ~/.rbenv/bin/rbenv versions | grep {{ ruby_version }}
  register: has_ruby_version
  changed_when: False
  ignore_errors: yes

- name: Check ruby version
  shell: ~/.rbenv/bin/rbenv version | grep {{ ruby_version }}
  register: is_ruby_version
  changed_when: False
  ignore_errors: yes

- name: Install ruby requiring packages
  yum:
    name:
      - bzip2
      - gcc*
      - openssl-devel
      - readline-devel
      - zlib-devel
  become: yes
  become_method: sudo
  when: has_ruby_version is failed

# install rbenv

- git:
    repo: https://github.com/rbenv/rbenv.git
    dest: ~/.rbenv
  when: rbenv_exists is failed

- git:
    repo: https://github.com/rbenv/ruby-build.git
    dest: ~/.rbenv/plugins/ruby-build
  when: rbenv_exists is failed

- name: Update rbenv
  shell: git pull
  args:
    chdir: ~/.rbenv
  when: has_ruby_version is failed

- name: Update ruby-build
  shell: git pull
  args:
    chdir: ~/.rbenv/plugins/ruby-build
  when: has_ruby_version is failed

- name: Make rbenv
  shell: src/configure && make -C src
  args:
    chdir: ~/.rbenv
  when: has_ruby_version is failed

- name: Register rbenv
  shell: echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
  when: rbenv_exists is failed

- name: Register rbenv
  shell: echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
  when: rbenv_exists is failed

# install ruby

- name: Install Ruby
  command: ~/.rbenv/bin/rbenv install {{ ruby_version }}
  when: has_ruby_version is failed

- name: Set default ruby version
  shell: ~/.rbenv/bin/rbenv global {{ ruby_version }}
  when: is_ruby_version is failed

まとめ

register changed_when ignore_errors でフラグを設定し when で切り替えるという単純な組み合わせで十分な role を書くことができました。ruby-version のダウングレードについても一瞬で終わるので便利ですね。