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を動かせばいいでしょう。