AnsibleでRHELを実際に変える
このラボは本物のRHEL系で動きます
VMの中にAlmaLinux 9が起動しています。systemdがPID 1として動き、SELinuxがEnforcingで、firewalldが動いています。プレイブックがシステムを本当に変更し、採点ツールはその結果をシステムから直接読み取ります。
既存のAnsibleコースはPodで動いていたため、文法の確認までがすべてでした。ここでは、設定しないと実際に遮断されます。
最初の起動には2分ほどかかります。
目標
RHCE試験が実際に問うことを一通り巡ります。ユーザー、サービス、SELinux、ファイアウォール、テンプレート、そして冪等性です。
なぜ重要なのか
RHCE(EX294)は、「Ansibleの文法を知っているか」を問いません。システムを望む状態にできるかを問います。そのため、減点の大部分は、文法ではなく次のようなところから出ます。
state: startedだけを書いてenabled: trueを書き漏らし、再起動後にサービスが起動しない- firewalldを
permanentだけで開けて、今は開かない、またはimmediateだけで開けて、再起動後に消える - SELinuxのブーリアンを有効にしたが
persistentがなく、再起動のときに元に戻る command/shellを条件なしで使い、毎回changedになる
最後のものが特に重要です。冪等でないプレイブックとは、実行するたびに何かを変えるプレイブックです。そうすると、「今回の実行が何を変えたか」がわからず、ハンドラーが毎回サービスを再起動して、不要な中断が発生します。
ステップ
/root/rhce/inventory.iniに[webservers]グループとしてこのホストを入れ、/root/rhce/ansible.cfgも作成してください。ansible webservers -m pingが成功する必要があります。/root/rhce/users.ymlで、webadminグループと、alice・bobユーザー(シェル/bin/bash、補助グループwebadmin)を作成してください。ループ(loop)を使ってください。/root/rhce/service.ymlでhttpdをインストールし、startedとenabledの両方を満たしてください。curl http://127.0.0.1/が200である必要があります。/root/rhce/selinux.ymlでhttpd_can_network_connectブーリアンを永続的に有効にし、/srv/webにhttpd_sys_content_tコンテキストを付けてください。/root/rhce/firewall.ymlで、httpサービスをファイアウォールで開けてください。runtimeとpermanentの両方を満たす必要があります。/root/rhce/templates/index.html.j2でホスト名が入ったページを作成し、/root/rhce/template.ymlで配置してください。変更されたときだけhttpdを再起動するハンドラーを使ってください。- 上記のすべてを呼び出す
/root/rhce/site.ymlを作成してください。そして、状態をわざと崩したあと(サービス停止・ファイル削除・アカウント削除)、2回実行して、changedの数を/root/rhce/idempotent.txtにchanged_first=・changed_second=で書いてください。 1回目は0より大きく、2回目は0である必要があります。崩さずに測ると、1回目から0になり、「直したので0になった」と「もともと何もしていなかった」を区別できません。 /root/rhce/report.mdに、selinux=Enforcing、idempotent=yes、playbooks=<개수>の3行と、説明を書いてください(プレースホルダーは個数です)。
参考
- SELinuxのモジュールは、
ansible.posix.sebooleanとcommunity.general.sefcontextです。2つのコレクションが両方とも必要で、ansible-coreのバージョンに合った版である必要があります。合わないと、警告だけを出してcouldn't resolve module/actionで失敗しますが、その文言は、タイプミスを疑わせます。コンテキストを定義したあとは、ansible.builtin.command: restorecon -R /srv/webを、changed_whenと一緒に使わないと、冪等が壊れます。 - firewalldモジュールには、
permanentとimmediateが別々にあります。両方が真であって初めて、「今も開いていて、再起動後も開いている」状態になります。 - ファクトは
ansible_facts['hostname']または{{ ansible_hostname }}で書きます。 changedの数は、ansible-playbook site.yml | grep -oE 'changed=[0-9]+'で数えます。- よくある間違い1:
command/shellを条件なしで使うことです。そのタスクはいつもchangedです。creates:・changed_when:で条件を付けてください。 - よくある間違い2:
state: startedだけを書いて、enabled: trueを書き漏らすことです。今は動いていますが、再起動すると起動しません。 - よくある間違い3: SELinuxブーリアンに
persistent: trueを書き漏らすことです。今は有効になりますが、再起動のときに元に戻ります。 - よくある間違い4: 2つのタスクが、同じファイルを異なる内容で管理することです。互いを元に戻し合って、どちらも永遠にchangedになり、各タスクは単独で見ると問題がないので、最も見つけにくいです。ファイル1つには持ち主が1つであるべきで、ブートストラップ用なら、
force: falseで「ないときだけ」を明示してください。
インベントリと設定ファイル
/root/rhce/inventory.ini に[webservers]グループとしてこのホストを入れ、/root/rhce/ansible.cfg も作成してください。ansible webservers -m pingが成功する必要があります。
このVM自身を対象にします。ansible_connection=localを使うと、SSHなしですぐに動きます。ansible.cfgにインベントリのパスを書いておくと、毎回-iを指定しなくて済みます。
ユーザーとグループを作成する
/root/rhce/users.yml で、webadminグループと、alice・bobユーザー(シェル/bin/bash、補助グループwebadmin)を作成してください。ループ(loop)を使ってください。
まずansible.builtin.groupを、その次にansible.builtin.userをloopで回します。グループがない状態でユーザーを作成すると、失敗します。
サービスは2つを満たす必要がある
/root/rhce/service.yml でhttpdをインストールし、startedとenabledの両方を満たしてください。curl http://127.0.0.1/が200である必要があります。
state: startedは今、enabled: trueは再起動後です。2つは別の話で、試験で最もよく書き漏らすものです。
SELinuxは有効で、実際に遮断する
/root/rhce/selinux.yml でhttpd_can_network_connectブーリアンを永続的に有効にし、/srv/webにhttpd_sys_content_tコンテキストを付けてください。
ブーリアンはansible.posix.sebooleanにpersistent: trueを付け、ファイルコンテキストはcommunity.general.sefcontextのあとにrestoreconを使います。
runtimeとpermanentは別
/root/rhce/firewall.yml で、httpサービスをファイアウォールで開けてください。runtimeとpermanentの両方を満たす必要があります。
permanent: trueは設定ファイルに、immediate: trueは今動いているファイアウォールに適用します。両方を指定して初めて完成です。
変更されたときだけ再起動する
/root/rhce/templates/index.html.j2 でホスト名が入ったページを作成し、/root/rhce/template.yml で配置してください。変更されたときだけhttpdを再起動するハンドラーを使ってください。
templateタスクにnotifyを付け、handlersの節に再起動を置きます。ハンドラーは、そのタスクがchangedのときだけ動きます。
2回目の実行は静かであるべき
上記のすべてを呼び出す /root/rhce/site.yml を作成してください。そして、状態をわざと崩したあと(サービス停止・ファイル削除・アカウント削除)、2回実行して、changedの数を /root/rhce/idempotent.txt にchanged_first=・changed_second=で書いてください。
1回目は0より大きく、2回目は0である必要があります。崩さずに測ると、1回目から0になり、「直したので0になった」と「もともと何もしていなかった」を区別できません。
site.ymlで、前のプレイブックをimport_playbookで呼び出し、2回実行します。2回目のchangedが0でなければ、そのタスクを探してください。
学んだこと
/root/rhce/report.md に、selinux=Enforcing、idempotent=yes、playbooks=<개수>の3行と、説明を書いてください(プレースホルダーは個数です)。
selinux=、idempotent=、playbooks=の3行と一緒に、試験で減点が出る箇所を整理してください。