前回の続き。

VPS上で生活しよう!ということなので、開発用の各種パッケージをインストールしたり設定ファイルをセットアップしたりするPlaybookを作成しました。

今回は量が多く何度もやり直しをしたのと、今後もちょこちょこメンテして再実行をしたいので、冪等性を保つような作りにしています。

軽い解説

Roleについて

今回は Role の機能を使ってみました。 Roleを使ってセットアップ内容を以下のように分割しました。

  • common - 共通で使うパッケージのインストール
  • dotfiles - dotfilesのインストール
  • vim - Vimプラグインマネージャ(Dein)のインストール
  • linuxbrew - linuxbrewのインストールと、brewを使ったソフトウェアのインストール
  • nodejs - nodebrewのインストール
  • rbenv - rbenvのインストール
  • python - venvをPythonの環境設定

……なんというか、ほぼ docker-desktop でやっている内容の移植です。

処理の共通化

また、セットアップ処理には同じような作業が多いため、処理を共通化しました。 lib ディレクトリ以下にタスクをまとめたモジュールを作成し、include して使うようにしてみました。

これらのモジュールを使うことで、 tasks には処理の順番を、 vars には処理の中身やパッケージのリストを宣言するという作りで Playbook を作成できるようになりした。 ControllerとModelに分割したようなイメージです。

  • apt-install.yml - 変数 packages に宣言されているパッケージをaptでインストールする
  • execute-commands.yml - 変数 commands に宣言されているコマンドを、ログインシェルで実行する
  • get-url.yml - 変数 `remote_urls に宣言されている url からファイルをダウンロードする
  • git-clone.yml - 変数 remote_repos に宣言されているリポジトリを git clone する
  • make-directories.yml - 変数 dirs に宣言されているディレクトリを作成する
  • set-environments.yml - 変数 envs に宣言されている環境変数を ~/.bash_profile に追記する

ちなみにこのやり方はAnsible Galaxyをちょっと真似したような感じです。

例えばわかりやすい例だと、 rbenv の場合、

  • vars - roles/rbenv/vars/main.yml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
dir: "{{ cache }}/rbenv"

remote_repos:
  - repo: https://github.com/sstephenson/rbenv.git
    dest: "{{ dir }}"
  - repo: https://github.com/sstephenson/ruby-build.git
    dest: "{{ dir }}/plugins/ruby-build"
packages:
  - libssl-dev
  - libreadline-dev
  - zlib1g-dev
commands:
  - "eval '$(rbenv init -)'"
  - rbenv install -v 2.4.1
  - rbenv rehash
  - rbenv global 2.4.1
envs:
  - "# RBENV"
  - "export RBENV_ROOT={{ dir }}"
  - export PATH=$RBENV_ROOT/bin:$PATH
  - 'eval "$(rbenv init -)"'

  • tasks - roles/rbenv/tasks/
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
- name: check rbenv
  shell: "bash -lc 'which rbenv'"
  register: exists
  failed_when: false

- block:
  - include: lib/apt-install.yml
  - include: lib/git-clone.yml
  - include: lib/set-environments.yml
  - include: lib/execute-commands.yml
  when: exists.rc != 0

と書けます。

軽いまとめ

こんな感じで環境を用意できたので、しばらくはブラウザの上で生きていきます。