AnsibleホストとしてNetBSDを扱う
2021年3月7日 初稿
Ansibleとは
Ansibleはサーバを構成管理するためのツールです。ユーザはYAML形式でタスク(task)を記述し、Ansibleはそのタスクを自動的に実行します。ここで、Ansibleは——ほとんどの場合において——冪等性(べきとうせい)を保証します。つまりAnsibleが同じタスクを何回実行しても、タスクが実行されたサーバは常に同じ状態・結果を保ちます。
タスクはある役割(role)単位で分割して記述されます。ひとつ以上の役割をホスト(host)として対応付け、最終的にはどのサーバがどのホストに含まれるのかをインベントリ(inventory)とプレイブック(playbook)で表現します。
NetBSDをAnsible実行機として扱う
AnsibleはPythonで実装されています。したがってPythonがインストールできればあとは簡単です。
pkgsrcではsysutils/ansible
パッケージが提供されていますが、Pythonパッケージはなるべくpip
を使ってインストールしたほうがいいでしょう。venv
のようなPython仮想環境と併せて利用することで、システムへの影響を最小限にしたうえで最新のパッケージをroot権限なしに利用できます。
したがって、NetBSDでAnsibleを動かすにはpkgsrcからlang/python
パッケージだけをインストールすればいいです。Python 3.4以上ならpip
とvenv
どちらもPythonのモジュールとして標準で利用できるからです。Pythonインストール後は次のようにPython仮想環境を作り、その中にAnsibleをインストールします。
python3.8 -m venv ~/.venv/ansible
source ~/.venv/ansible/bin/activate
pip install ansible
NetBSDをAnsibleホストとして扱う
反対に、NetBSDがインストールされたマシンをAnsibleで構成管理したいときを考えます。
Ansibleはホスト側にもPythonがインストールされていないと機能のほとんどが制限されます。RHELやUbuntuといったGNU/Linuxディストリビューションの多くは標準でPythonがインストールされていますが、NetBSDのベースシステムにPythonは含まれていません。ホスト側にPythonがインストールされていない場合、ホストの情報を集めたり、高機能なモジュールを利用したりできません。YAML形式のファイルの中でシェルスクリプトを書くのも同然です。
そのため、NetBSDをAnsibleホストとして扱う場合、(1)PythonなしでPythonをインストールするタスクを動かしてから、(2)NetBSDもサポートされているモジュールを使って構成管理を進めることになります。
ディレクトリ構造
Ansible Playbookを使って構成管理するにあたり、ディレクトリ構造を提示します。
workdir_root/
├── hosts
├── roles/
│ ├── bootstrap
│ │ └── tasks
│ │ └── main.yml
│ ├── pkgin
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ └── repositories.conf
└── site.yml
workdir_root
はディレクトリ構造のルートを表します。名前はなんでもいいです。このディレクトリにはhosts
というインベントリファイルと、site.yml
というマスタープレイブック(master playbook)があります。roles
ディレクトリに各役割ごとのロールが格納されており、ここでは初期化用のbootstrap
ロールと、pkgin
をセットアップするためのpkgin
ロールがあります。
ブートストラップ
bootstrap
ロールを含むbootstrap
ホストで、PythonとNetBSD用の高機能なパッケージ管理マネージャpkginをインストールします。roles/bootstrap/tasks/main.yml
へ次のように書きます。
---
- name: Install Packages for Ansible
raw: "/usr/sbin/pkg_add https://cdn.netbsd.org/pub/pkgsrc/packages/$(uname)/$(uname -m)/$(uname -r)/All/{{ item }}"
with_items:
- python38-3.8.6nb1.tgz
- pkgin-20.12.1.tgz
https://cdn.netbsd.orgからバイナリパッケージをインストールするようにタスクを書いています。パッケージの名前やバージョンは適宜確認し変更してください。このタスクをPythonを使わないraw
モジュールを使い、with_items
で列挙された各パッケージをpkg_add
コマンドでインストールしています。
次にマスタープレイブックsite.yml
を書き、bootstrap
ロールに対応するホストnetbsd_bootstrap
を定義します。
---
- name: Bootstrap NetBSD host for Ansible
gather_facts: no
hosts: netbsd_bootstrap
roles:
- bootstrap
ここのポイントは、gather_facts
にno
を指定することで、Ansibleによるホスト情報の収集をさせないことです。この機能はPythonが必要なので、このように指定しないとAnsibleの実行が失敗します。
インベントリhosts
を編集し、netbsd_bootstrap
ホストに属するマシンのIPアドレスかドメインを列挙します。ここではIPアドレス192.0.2.1
がAnsibleで構成管理するNetBSDマシンとします。
[netbsd_bootstrap]
192.0.2.1
最後にansible-playbook
を動かして、このタスクを192.0.2.1
に対し実行します。-i
でインベントリへのパスを、-u
でSSHログインするときのユーザ名を指定します。--ask-pass
オプションをつけると、コマンド実行直後に、SSHログインのためのパスフレーズを尋ねられます。公開鍵認証の設定が済んでいる場合は、このオプションは不要です。
ansible-playbook -i hosts -u root site.yml --ask-pass
このansible-playbook
が正常に終了すれば、再度実行する必要はありません。仮想マシンで動かしているなら、このブートストラップのタスクが走った仮想マシンをテンプレートとして保存しておくといいでしょう。
pkginをセットアップする例
pkgin
モジュールを使い、パッケージのインストールができます。このモジュールを使うためには、ホストOSにpkgin
がインストールされており、repositories.conf
が適切に設定されていなければなりません。
各ホストごとにpkgin
の設定が同一とします。Ansibleのtemplate
モジュールで設定ファイルをデプロイし、リポジトリのキャッシュを更新するpkgin
ロールを定義します。
roles/pkgin/templates/repositories.conf
の内容は以下のとおりです。{{ ansible_distribution }}
では変数を展開しています。この変数はAnsibleがOSの情報を収集したときに定義される特別な変数のひとつです。ホストがNetBSDの場合はNetBSD
と展開されます。
https://cdn.netbsd.org/pub/pkgsrc/packages/{{ ansible_distribution }}/$arch/9.1/All
roles/pkgin/tasks/main.yml
を次のように書きます。
---
- name: Deploy repositories.conf
template:
src: repositories.conf
dest: /usr/pkg/etc/pkgin/repositories.conf
owner: root
group: wheel
mode: '0644'
- name: Update repository cache
pkgin:
update_cache: yes
マスタープレイブックsite.yml
はこのようになります。前節で書いたブートストラップ用の定義はそのまま残して構いません。
- name: Setup NetBSD host
hosts: netbsd
roles:
- pkgin
インベントリhosts
を編集します。ここで、netbsd
ホスト用に変数ansible_python_interpreter
を定義しています。Pythonインタプリタが/usr/bin/python
など一般的なパスではない場合はこのようにユーザがパスを指定します。
[netbsd]
192.0.2.1
[netbsd:vars]
ansible_python_interpreter=/usr/pkg/bin/python3.8
前節でインベントリに書いたグループの定義ですが、netbsd_bootstrap
からIPアドレス・ドメインを削除しておけばいいです。そのようにすることでそのホストに紐付いたタスクは実行されなくなります。
ansible-playbook
を実行しタスクを動かします。前述したように、公開鍵認証が設定されているなら--ask-pass
オプションは不要です。
ansible-playbook -i hosts -u root site.yml --ask-pass
これで準備は完了です。あとは以下のようにpkgin
モジュールが使えます。
- name: Install git
pkgin:
name:
- git
- mozilla-rootcerts
state: present
より便利に使うために
以上、NetBSDマシンをAnsibleホストとして扱うための手順を紹介しました。はじめにraw
モジュールを使ってPythonなしにPythonをインストールすることで、Ansibleを——シェルスクリプトではなく——Ansibleとして使えるようにしました。次に、pkgin
モジュールを使うための準備として、repositories.conf
をデプロイしキャッシュを更新するタスクを書きました。これはほんの手始めです。自動化のためにはもっとやれることがあります。
- 仮想マシンテンプレートの作成と保守
仮想マシンなら、ブートストラップ済みのマシンは一旦テンプレートとして保存することで、新しくマシンを作る時にブートストラップ部分を省略できます。SSHの設定と公開鍵の登録も済ませておくといいでしょう。
- IPアドレスとホスト名の自動登録
本稿ではIPアドレスやホスト名がすでにマシンに設定されていることが前提となっていました。仮想化基盤やOS次第ですがopen-vm-toolsやcloud-initのようなソフトウェアを使うことで指定されたIPアドレスやホスト名の設定を自動的におこなえます。
- 仮想マシンそのものの構成管理化
Ansibleはソフトウェアの構成管理ツールにすぎません。これも仮想化基盤に依存しますが、Terraformのように仮想マシンそのものをコードとして表現しデプロイできるツールもあります。
- CI/CD
書いたタスクをバージョン管理システムで管理し、そのリポジトリをGtiLab RunnerやJenkinsなどと連携させれば、リポジトリに変更が加わるたびにansible-lintによるコードの検査や
ansible-playbook
の実行などを自動化できます。- 高機能なAnsibleインタフェース
AWXやその商用版のRed Hat Ansible TowerはWebベースのAnsible用ユーザインタフェースです。もっとも、これらアプリケーションは必須というわけでもありません。普通に使う分にはCLIで
ansible-playbook
を動かせばいいでしょう。