はじめに
前回のansible構築から結構時間が経ってしまいましたが、前回とりあえず動くplaybookを作成したところから、今後の検証環境を構築する上で、必要となる構成管理を簡単にするために、Rolesを使って再利用がしやすく変更に強いPlaybookに分割していきます。
そして私が今回ansibleを使っているのはslurmの検証環境構築用ですが、実際の本番環境に適用するためのplaybookとしても利用出来るように記述することも可能です。実際この考えでplaybookを作っていないとあとから本番環境に適用するときに、検証環境と本番環境の違いでシステムが動かないなんて事が発生します。
Rolesとは
通常playbookファイルのtasksに以下のようにタスクを羅列して書いていくと、どんどん可読性が落ち、変更に強くするために、変数なんかをこの段階で使ってしまうと何がなんだか分からなくなってしまいます。
Ansbile Rolesを使う事で、playbookの中から、さらにplaybookを呼び出す事が出来ます。この仕組みのお陰で複数のタスクを一つのRole(グループ)としてまとめてplaybookに書く事が可能です。
ただし何でもかんでもRolesで分割したら良いモノでも無いです。一応RHEL系Debian系の違いを吸収出来るようなplabookも記述可能ですが、ansible以前のシステムコンセプトと役割がしっかりしていないと、メンテナンスが難しいplaybookになってしまいます。
Rolesはlaravel,strusts,django,flaskなど開発系フレームワークと同様に、ルールが規定されています。このルールを知らないと想定と違う挙動で悩まされるので、最低限のルールは理解して置きましょう。
ここ最近RHEL系のcentos9から有償版と無償版の完全互換性が失われた事で、有償ソフトウェアの対応OSからcentos及びrocky linuxが外れるような事が発生しています。 実際は動くのですがサポートを受けられなくなるので、新しくubuntu Suse LinuxにOSを変更する動きがあります。このときに、複数OSに対応出来るansibleを作るのも一つの手ですし、今後使わなくなるOS用に対応するplaybookを書く意味は無いため、新しくplaybookを書くのもありです。ただRolesを適切に記述していたら、どちらにせよ変更が少なく再利用出来ます。
今回の検証環境ではOSはRHEL系のrocky linux8.8で統一しているのでOSの違いを吸収する書き方はしません。
Rolesの最低限のルール
ansibleはRolesでは、以下のディレクトリ名及びファイル名を前提としています。
詳細は、ansibleの公式ドキュメントを参照してください。私の方で最低限のルールはここにピックアップします。
Rolesでは以下のディレクトリ名であることが前提です(使わないディレクトリがなくても問題無い)
- tasks ・・・ これは説明するまでもなくtaskに関する記述を記載します
- handlers ・・・ taskの実行がされた事をトリガーとして動作する処理(主に再起動など)を記述する
- defaults ・・・ 基本的な変数を設定する
- vars ・・・ 条件によって変数の値を定義しているファイルを配置する
- files ・・・ taskで配布するファイルを配置
- templates ・・・ 変数によってファイル内容を置換するファイルを配置
- meta ・・・ 今回の対象外
そしてRolesでは各ディレクトリの直下にあるmain.yml
ファイルが読み込まれます。
最後に変数の定義は至る所で出来るため、どこが一番優先されるかは確認して置いてください。
意図通りに動かなかった原因の一つに、この変数の優先順位を考えずに設定している事が挙げられます。
まずは分割とその準備
まずは大まかに
- セキュリティの無効化
- NISクライアントの設定
- NFSクライアントの設定
で分割してみます。slurmのインストール部分は省きます。
まずはansible-playbookを実行する際に指定するplaybookファイル:site.ymlを作成します。
ここではインストール対象をslurm01
にしました。
---
- hosts: slurm
roles:
- disable_security
etc/hostsファイルの中は以下の通りです。(nnn.nnn.nnn.nnnはIPアドレス)
[slurm]
nnn.nnn.nnn.nnn ansible_ssh_user=root ansible_ssh_private_key_file=/root/.ssh/id_ed25519
site.ymlが保存されているディレクトリ直下でディレクトリの作成を実施
セキュリティの無効化では以下のディレクトリのみ作成します。
mkdir -p roles/disable_security
mkdir -p roles/disable_security/tasks
mkdir -p roles/disable_security/handlers
ここではファイアウォールとselinuxを無効化にしています。
私自身の考えでは検証環境以外でも不特定多数にサービスを提供していない限りはselinuxは無効化で問題無いと考えています。今は色んな箇所でセキュリティの仕組みを入れられるが故に、似たようなセキュリティを多数設定しすぎてメンテナンス性が極端に落ちてしまいます。ここら辺は境界線モデルにするのかEDRにするのかなどコンセプト次第ですが端末系はEDR・サーバー系は境界線モデルでも十分なのでは?と思っています(パブリックサービスなどは別)
---
- name: Disable and stop firewalld
systemd:
name: firewalld
enabled: false
state: stopped
- name: Disable SELinux
selinux:
state: disabled
notify: Reboot the system
---
- name: Reboot the system
reboot:
msg: "Rebooting after disabling SELinux"
reboot_timeout: 300 # タイムアウトは必要に応じて調整
ちゃんとハンドラーが動作して、rebootも掛かりました。
nis_clientロールの追加
では同じ要領でnisクライアントの方もやっています。
---
- hosts: slurm
roles:
- disable_security
- nis_client
nis_clientロール用のディレクトリも作成します。
mkdir -p roles/nis_client
mkdir -p roles/nis_client/tasks
mkdir -p roles/nis_client/handlers
NISクライアントの設定を行う際には、NISのドメイン名とNISサーバーを指定します。
これは検証環境と本番環境で異なるので、変数化して置いた方が便利です。
教科書的に言えばroles/nis_client/defaults/main.yml
に変数の定義をしておくのですが、
こういう奥まった所に記載していると正直忘れます。私としてお勧めなのが、hostsファイルに追記して置いた方が、検証用と本番用の設定を切替えが簡単です(この段階では)。
---
- name: Install NIS and related packages
dnf:
name:
- ypbind
- rpcbind
- oddjob-mkhomedir
state: present
- name: Set NIS domain name
command: ypdomainname '{{ NISDOMAIN }}'
- name: Add NISDOMAIN to /etc/sysconfig/network
lineinfile:
path: /etc/sysconfig/network
line: "NISDOMAIN={{ NISDOMAIN }}"
create: yes
- name: Add NIS server to /etc/yp.conf
lineinfile:
path: /etc/yp.conf
line: "domain {{ NISDOMAIN }} server {{ NISSERVER }}"
create: yes
- name: Select NIS profile with authselect
command: authselect select nis --force
- name: Enable mkhomedir with authselect
command: authselect enable-feature with-mkhomedir
notify: Enable and restart NIS-related services
追加部分だけ抜粋しました。
[slurm:vars]
NISDOMAIN=<nisドメイン名>
NISSERVER=<nisサーバー名 or IP>
NIS関連のパッケージをインストールし、設定も終わった段階でハンドラーを呼び出しています。
- name: Enable and restart NIS-related services
systemd:
name: "{{ item }}"
enabled: true
state: restarted
loop:
- rpcbind
- ypbind
- nis-domainname
- oddjobd
再度実行
ansible-playbook -i etc/hosts site.yml
### 検証環境と本番環境の違いをansibleで吸収
最後に検証系と本番系の違いをansibleで表現するために、検証系はhostsファイルを/etc/hostsに配布し、本番系ではhostsを配布しない挙動を入れてみます。
[slurm:vars]
NISDOMAIN=<nisドメイン名>
NISSERVER=<nisサーバー名 or IP>
HOST_ENVIRONMENT=TEST
hosts.testはfilesに配置しておく。
- name: Overwrite /etc/hosts if HOST_ENVIRONMENT is TEST
copy:
src: hosts.test
dest: /etc/hosts
backup: yes
when: HOST_ENVIRONMENT == "TEST"
この状態で一度動く事を確認してください。
この状態のままでもいいですが、一応varディレクトリを使ったやり方も記載します。
まずはhostsの変数はHOST_ENVIRONMENTのみにします。
[slurm:vars]
HOST_ENVIRONMENT=TEST
site.ymlの設定に、変数ファイルの読み込みを指定します。vars_files
---
- name: Manage slurm nodes
hosts: slurm
vars_files:
- "vars/{{ HOST_ENVIRONMENT }}/main.yml"
become: true
roles:
- disable_security
- nis_client
検証(TEST)環境に関係する変数は以下の場所に設定します。
mkdir -p roles/nis_client/vars/TEST
ここではイコール(=)からコロン(:)に変更になっている事に注意してください
NISDOMAIN:<nisドメイン名>
NISSERVER:<nisサーバー名 or IP>
これで実行しても挙動は変わらないハズです。
このように環境毎に違う変数をあらかじめ変数ファイルとして定義しておき、読み込むやり方も出来ます。
ただ多数の変数や環境がない場合は、素直にhostsファイルに記述することをお勧めします
残りのNFSや他のも同じ感じなので、記述はスキップします。