AnsibleホストとしてNetBSDを扱う

2021年3月7日 初稿

  1. Ansibleとは
  2. NetBSDをAnsible実行機として扱う
  3. NetBSDをAnsibleホストとして扱う
    1. ディレクトリ構造
    2. ブートストラップ
    3. pkginをセットアップする例
  4. より便利に使うために

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以上ならpipvenvどちらも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_factsnoを指定することで、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-toolscloud-initのようなソフトウェアを使うことで指定されたIPアドレスやホスト名の設定を自動的におこなえます。

仮想マシンそのものの構成管理化

Ansibleはソフトウェアの構成管理ツールにすぎません。これも仮想化基盤に依存しますが、Terraformのように仮想マシンそのものをコードとして表現しデプロイできるツールもあります。

CI/CD

書いたタスクをバージョン管理システムで管理し、そのリポジトリをGtiLab RunnerJenkinsなどと連携させれば、リポジトリに変更が加わるたびにansible-lintによるコードの検査やansible-playbookの実行などを自動化できます。

高機能なAnsibleインタフェース

AWXやその商用版のRed Hat Ansible TowerはWebベースのAnsible用ユーザインタフェースです。もっとも、これらアプリケーションは必須というわけでもありません。普通に使う分にはCLIでansible-playbookを動かせばいいでしょう。