はじめに
この実験では、Ansible を使用して Red Hat Enterprise Linux (RHEL) システムにファイルをデプロイおよび管理するための基本的なスキルを習得します。基本的なファイルのデプロイから、より高度なコンテンツの操作や状態管理まで、ファイル操作のために設計された最も一般的で強力な Ansible モジュールを実際に体験します。
まず、ansible.builtin.copy モジュールを使用して静的ファイルを転送し、その属性を設定します。次に、lineinfile および blockinfile でファイルの内容を変更し、ansible.builtin.template モジュールを使用してカスタム MOTD を生成します。この実験では、シンボリックリンクの作成、stat を使用したファイル状態の検証、fetch を使用したログの取得、および管理対象ファイルのクリーンアップについても説明し、Ansible のファイル管理機能の包括的な概要を提供します。
ansible.builtin.copy モジュールを使用した静的ファイルのコピーと属性の設定
このステップでは、最も基本的な Ansible モジュールの一つである ansible.builtin.copy の使用方法を学びます。このモジュールは、コントロールノード(LabEx VM)から管理対象ホストの指定された場所にファイルを転送するために使用されます。今回のケースでは、管理対象ホストは localhost 自体です。単なるコピーだけでなく、copy モジュールを使用すると、ファイルの所有者、グループ、パーミッションモードなどの属性を正確に制御でき、これは適切なシステム構成に不可欠です。
まず、プロジェクト環境をセットアップしましょう。すべての作業は ~/project ディレクトリ内で行います。
プロジェクトディレクトリに移動し、ソースファイル用のサブディレクトリを作成します。 これはプロジェクトを整理するための一般的なプラクティスです。
ansible-coreパッケージをインストールします。sudo dnf install -y ansible-core次に、プロジェクトディレクトリに移動し、ソースファイル用のサブディレクトリを作成します。
cd ~/project mkdir files次に、コピーする簡単なテキストファイルを作成します。
catコマンドと「ヒアドキュメント」を使用して、filesディレクトリ内にinfo.txtファイルを作成します。cat << EOF > ~/project/files/info.txt This file was deployed by Ansible. It contains important system information. EOF次に、Ansible インベントリファイルを作成します。 インベントリは、Ansible がどのホストを管理するかを指示します。この実験では、ローカルマシンを管理します。
inventory.iniという名前のファイルを作成します。cat << EOF > ~/project/inventory.ini localhost ansible_connection=local EOFこのインベントリでは、
localhostがターゲットとするホストです。変数ansible_connection=localは、Ansible に SSH を使用せずに、コントロールノードで直接タスクを実行するように指示します。最初の Ansible プレイブックを作成します。 このプレイブックには、ファイルをコピーするための指示が含まれます。
nanoまたはcatを使用して、copy_file.ymlという名前のファイルを作成します。nano ~/project/copy_file.ymlファイルに以下のコンテンツを追加します。このプレイブックは 1 つのタスクを定義しています。それは、
info.txtを/tmp/ディレクトリにコピーし、その属性を設定することです。--- - name: Deploy a static file to localhost hosts: localhost tasks: - name: Copy info.txt and set attributes ansible.builtin.copy: src: files/info.txt dest: /tmp/info.txt owner: labex group: labex mode: "0640"copyタスクのパラメータの内訳を見てみましょう。src: files/info.txt: コントロールノード上のソースファイルへのパス。プレイブックの場所からの相対パスです。dest: /tmp/info.txt: 管理対象ホスト上のファイルが配置される絶対パスです。owner: labex: ファイルの所有者をlabexユーザーに設定します。group: labex: ファイルのグループをlabexグループに設定します。mode: '0640': ファイルのパーミッションを設定します。0640は、所有者が読み取り/書き込み可能、グループが読み取り可能、その他は権限なしを意味します。
ansible-playbookコマンドを使用してプレイブックを実行します。-iフラグは、インベントリファイルを指定します。ansible-playbook -i inventory.ini copy_file.yml以下のような、プレイブックの正常な実行を示す出力が表示されるはずです。
PLAY [Deploy a static file to localhost] *************************************** TASK [Gathering Facts] ********************************************************* ok: [localhost] TASK [Copy info.txt and set attributes] **************************************** changed: [localhost] PLAY RECAP ********************************************************************* localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0最後に、ファイルが正しくコピーされ、正しい属性を持っていることを確認します。
ls -lコマンドを使用して、パーミッション、所有者、グループを確認します。ls -l /tmp/info.txt出力は、
labexが所有者およびグループであり、パーミッションが-rw-r-----であることを示すはずです。-rw-r----- 1 labex labex 72 Jul 10 14:30 /tmp/info.txtファイルのコンテンツを表示して、完全にコピーされたことを確認することもできます。
cat /tmp/info.txtThis file was deployed by Ansible. It contains important system information.
これで、ansible.builtin.copy モジュールを使用して、ローカルシステムにファイルをデプロイし、その属性を構成することに成功しました。
lineinfile および blockinfile を使用したファイルコンテンツの変更
このステップでは、管理対象ホスト上の既存のファイルを、ファイル全体を置き換えることなく変更する方法を学びます。Ansible はこの目的のために強力なモジュールを提供しています。単一行を管理するための ansible.builtin.lineinfile と、複数行のテキストブロックを管理するための ansible.builtin.blockinfile です。これらは、設定の変更やログファイルへのエントリの追加などのタスクに非常に役立ちます。
前のステップで作成した info.txt ファイル(/tmp/info.txt にあります)を引き続き使用します。
まず、プロジェクトディレクトリにいることを確認します。
cd ~/projectmodify_file.ymlという名前の新しいプレイブックを作成します。 このプレイブックには 2 つのタスクが含まれます。1 つは単一行を追加するタスク、もう 1 つは既存のファイルにテキストブロックを追加するタスクです。nano ~/project/modify_file.ymlmodify_file.ymlプレイブックに以下のコンテンツを追加します。 このプレイブックはlocalhostをターゲットとし、lineinfileとblockinfileの両方を使用して/tmp/info.txtにコンテンツを追記します。--- - name: Modify an existing file hosts: localhost tasks: - name: Add a single line of text to a file ansible.builtin.lineinfile: path: /tmp/info.txt line: This line was added by the lineinfile module. state: present - name: Add a block of text to an existing file ansible.builtin.blockinfile: path: /tmp/info.txt block: | ## BEGIN ANSIBLE MANAGED BLOCK This block of text consists of two lines. They have been added by the blockinfile module. ## END ANSIBLE MANAGED BLOCK state: present使用されているモジュールを見てみましょう。
ansible.builtin.lineinfile: このモジュールは、特定の行がファイルに存在することを保証します。行が既に存在する場合、Ansible は何も行わないため、タスクは冪等性(idempotent)を持ちます。path: 変更するファイル。line: ファイルに存在することを保証するテキスト行。state: present: これにより行が存在することが保証されます。削除するにはstate: absentを使用できます。
ansible.builtin.blockinfile: このモジュールは、マーカー行(例:## BEGIN ANSIBLE MANAGED BLOCK)で囲まれたテキストブロックを管理します。これは設定セクションの管理に理想的です。path: 変更するファイル。block: 挿入する複数行の文字列。|はリテラルブロックの YAML 構文で、改行を保持します。state: present: ブロックが存在することを保証します。
ansible-playbookコマンドとinventory.iniファイルを使用してプレイブックを実行します。ansible-playbook -i inventory.ini modify_file.yml出力は、両方のタスクがファイルに変更を加えたことを示します。
PLAY [Modify an existing file] ************************************************* TASK [Gathering Facts] ********************************************************* ok: [localhost] TASK [Add a single line of text to a file] ************************************* changed: [localhost] TASK [Add a block of text to an existing file] ********************************* changed: [localhost] PLAY RECAP ********************************************************************* localhost : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0最後に、
/tmp/info.txtのコンテンツを表示して変更を確認します。cat /tmp/info.txt元のコンテンツに続いて、新しい行と新しいテキストブロックが表示されるはずです。
This file was deployed by Ansible. It contains important system information. This line was added by the lineinfile module. ## BEGIN ANSIBLE MANAGED BLOCK This block of text consists of two lines. They have been added by the blockinfile module. ## END ANSIBLE MANAGED BLOCKプレイブックを再度実行すると、コンテンツは既に存在するため、Ansible は
ok=3およびchanged=0と報告します。これは、これらのモジュールの冪等性を示しています。
ansible.builtin.template モジュールを使用したカスタム MOTD の生成
このステップでは、静的ファイルのコピーから、ansible.builtin.template モジュールを使用した動的ファイルの生成へと進みます。このモジュールは Jinja2 テンプレートエンジンを活用して、Ansible が管理対象ホストから収集した変数やシステム情報(「ファクト」として知られる)でカスタマイズされたファイルを作成します。ここでは、システム固有の情報を表示する動的な Message of the Day (MOTD) を作成します。
まず、
~/projectディレクトリにいることを確認し、テンプレート専用のサブディレクトリを作成します。 Jinja2 テンプレートをtemplatesディレクトリに保存するのは、Ansible の標準的なベストプラクティスです。cd ~/project mkdir templates次に、Jinja2 テンプレートファイルを作成します。 このファイル
motd.j2は、動的データのプレースホルダーを含む MOTD の構造を保持します。.j2拡張子は Jinja2 テンプレートの一般的な規約です。nano ~/project/templates/motd.j2ファイルに以下のコンテンツを追加します。
{{ ... }}の構文に注意してください。これは変数またはファクトのプレースホルダーを示します。################################################################# ## Welcome to {{ ansible_facts['fqdn'] }} # ## This is a {{ ansible_facts['distribution'] }} system. ## System managed by Ansible. # ## For support, contact: {{ admin_email }} #################################################################このテンプレートでは:
{{ ansible_facts['fqdn'] }}は、ホストの完全修飾ドメイン名(Fully Qualified Domain Name)に置き換えられます。{{ ansible_facts['distribution'] }}は、Linux ディストリビューション名(例:RedHat)に置き換えられます。{{ admin_email }}は、プレイブックで定義するカスタム変数です。
次に、
template_motd.ymlという名前の新しいプレイブックを作成します。 このプレイブックはテンプレートを使用して/etc/motdを生成します。nano ~/project/template_motd.yml以下のコンテンツを追加します。このプレイブックは
/etcディレクトリへの書き込みに必要なため、昇格された権限(become: true)が必要です。また、カスタム変数admin_emailも定義します。--- - name: Deploy a custom MOTD from a template hosts: localhost become: true vars: admin_email: admin@labex.io tasks: - name: Generate /etc/motd from template ansible.builtin.template: src: templates/motd.j2 dest: /etc/motd owner: root group: root mode: "0644"このプレイブックの主要なパラメータ:
become: true: これは Ansible にsudoを使用してタスクを実行するように指示します。これは/etc/motdへの書き込みに必要です。vars: このセクションは、admin_emailのようなカスタム変数を定義する場所です。ansible.builtin.template: Jinja2 テンプレートを処理するモジュールです。srcは.j2ファイルを指し、destは管理対象ホスト上のターゲットファイルです。
プレイブックを実行します。
ansible-playbook -i inventory.ini template_motd.yml出力はタスクが成功したことを確認するはずです。
PLAY [Deploy a custom MOTD from a template] ************************************ TASK [Gathering Facts] ********************************************************* ok: [localhost] TASK [Generate /etc/motd from template] **************************************** changed: [localhost] PLAY RECAP ********************************************************************* localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0結果を確認します。 新しく生成された
/etc/motdファイルのコンテンツを確認します。cat /etc/motdJinja2 のプレースホルダーが実際のシステムファクトと定義したカスタム変数に置き換えられたレンダリングされた出力が表示されます。
fqdnはラボ環境のホスト名と一致します。################################################################# ## Welcome to host.labex.io # ## This is a RedHat system. ## System managed by Ansible. # ## For support, contact: admin@labex.io #################################################################
これで、テンプレートを使用してカスタマイズされたファイルを作成することに成功しました。これはインフラストラクチャ自動化におけるコアスキルです。
copy および file を使用してサポートファイルをデプロイし、シンボリックリンクを作成する
このステップでは、copy モジュールの知識を、新しく汎用的なモジュールである ansible.builtin.file と組み合わせます。copy はコンテンツの転送に使用されますが、file は管理対象ホスト上のファイル、ディレクトリ、およびシンボリックリンクの状態を管理するために使用されます。これを使用してディレクトリを作成したり、パーミッションを設定したり、そしてこの演習で最も重要なシンボリックリンクを作成したりします。
シナリオは、システムによって表示されるログイン前のメッセージを構成することです。多くの Linux システムでは、/etc/issue はローカル端末ユーザーに表示され、/etc/issue.net はリモートユーザー(SSH など)に表示されます。ここでは単一の issue ファイルをデプロイし、その後シンボリックリンクを作成して /etc/issue.net が /etc/issue を指すようにし、常に同じメッセージが表示されるようにします。
まず、
~/projectディレクトリにいることを確認し、問題メッセージのソースファイルを作成します。 このファイルは、以前に作成したfilesサブディレクトリに配置します。cd ~/project cat << EOF > ~/project/files/issue Authorized access only. All connections are logged and monitored. EOFdeploy_issue.ymlという名前の新しいプレイブックを作成します。 このプレイブックには 2 つのタスクが含まれます。1 つはissueファイルをコピーするタスク、もう 1 つはシンボリックリンクを作成するタスクです。nano ~/project/deploy_issue.ymldeploy_issue.ymlプレイブックに以下のコンテンツを追加します。 このプレイブックは/etc/ディレクトリ内のファイルを管理するために昇格された権限(become: true)が必要です。--- - name: Configure system issue files hosts: localhost become: true tasks: - name: Copy custom /etc/issue file ansible.builtin.copy: src: files/issue dest: /etc/issue owner: root group: root mode: "0644" - name: Ensure /etc/issue.net is a symlink to /etc/issue ansible.builtin.file: src: /etc/issue dest: /etc/issue.net state: link force: yes新しい
ansible.builtin.fileタスクを分析しましょう。src: /etc/issue:stateがlinkの場合、srcはシンボリックリンクが指すべきファイルを指定します。dest: /etc/issue.net: これはシンボリックリンク自体が作成されるパスです。state: link: この重要なパラメータは、fileモジュールに通常のファイルやディレクトリではなく、シンボリックリンクを作成するように指示します。force: yes: これは冪等性を確保する便利なオプションです。/etc/issue.netが既に通常のファイルとして存在する場合、Ansible はそれを削除してリンクを作成します。force: yesがない場合、その状況ではプレイブックは失敗します。
プレイブックを実行します。
ansible-playbook -i inventory.ini deploy_issue.yml出力は両方のタスクが正常に変更を行ったことを示すはずです。
PLAY [Configure system issue files] ******************************************** TASK [Gathering Facts] ********************************************************* ok: [localhost] TASK [Copy custom /etc/issue file] ********************************************* changed: [localhost] TASK [Ensure /etc/issue.net is a symlink to /etc/issue] ************************ changed: [localhost] PLAY RECAP ********************************************************************* localhost : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0ls -lコマンドを使用して結果を確認します。 このコマンドは、シンボリックリンクを明確に示す詳細なリストを提供します。ls -l /etc/issue /etc/issue.net出力は、
/etc/issueが通常のファイルであり、/etc/issue.netがそれに指すシンボリックリンクであることを示すはずです。/etc/issue.netのパーミッションの先頭にあるlは、それがリンクであることを示します。-rw-r--r--. 1 root root 65 Jul 10 15:00 /etc/issue lrwxrwxrwx. 1 root root 10 Jul 10 15:00 /etc/issue.net -> /etc/issue
これで、設定ファイルを正常にデプロイし、ansible.builtin.file モジュールを使用してシンボリックリンクを作成することに成功しました。これはシステム構成を管理するための一般的で強力なパターンです。
stat でファイルの状態を確認し、fetch でログを取得する
このステップでは、2 つの重要なデータ収集モジュールである ansible.builtin.stat と ansible.builtin.fetch について学びます。stat モジュールは、管理対象ホスト上のファイルまたはディレクトリの状態を確認するために使用されます。例えば、ファイルが存在するかどうか、そのパーミッションは何か、または最後にいつ変更されたかなどを確認できます。これは何も変更しないため、チェックや条件付きロジックに最適です。fetch モジュールは copy の逆を行います。管理対象ホストからファイルを 取得 し、コントロールノードに保存します。これは、構成のバックアップや分析のためのログファイルの収集に理想的です。
ここでは、以前に作成した /etc/motd ファイルの存在を確認し、次に DNF パッケージマネージャーのログファイル (/var/log/dnf.log) を LabEx VM 上のローカルディレクトリに取得するプレイブックを作成します。
まず、
~/projectディレクトリにいることを確認し、取得するファイルを保存するための新しいサブディレクトリを作成します。cd ~/project mkdir fetched_logscheck_and_fetch.ymlという名前の新しいプレイブックを作成します。 このプレイブックには、ファイルのチェックとログの取得を行うタスクが含まれます。nano ~/project/check_and_fetch.ymlcheck_and_fetch.ymlプレイブックに以下のコンテンツを追加します。 このプレイブックは、statを使用してファイルの詳細を取得し、registerを使用してそれらの詳細を変数に格納し、debugを使用して変数を表示し、fetchを使用してログファイルを取得します。--- - name: Check file status and fetch logs hosts: localhost become: true tasks: - name: Check if /etc/motd exists ansible.builtin.stat: path: /etc/motd register: motd_status - name: Display stat results ansible.builtin.debug: var: motd_status.stat - name: Fetch the dnf log file from managed host ansible.builtin.fetch: src: /var/log/dnf.log dest: fetched_logs/ flat: yes主要な概念を分解しましょう。
register: motd_status: これは重要な Ansible の機能です。タスクの出力全体を取得し、motd_statusという名前の新しい変数に保存します。ansible.builtin.debug: このモジュールは、プレイブックの実行中に値を表示するために使用されます。ここでは、登録された変数内のstatオブジェクト (motd_status.stat) を表示して、ファイルのプロパティを確認します。ansible.builtin.fetch: このモジュールは、管理対象ホストからファイルを取得します。src: 管理対象ホストから取得するファイルのパスです。dest: ファイルが保存されるコントロールノード(LabEx VM)上のディレクトリです。flat: yes: デフォルトでは、fetchはホストとソースパスに一致するサブディレクトリ構造を作成します。flat: yesは、余分なサブディレクトリなしでファイルをdestディレクトリに直接コピーすることで、これを簡略化します。
プレイブックを実行します。 システムログファイルを読み取るため、必要な権限を取得するために
become: trueが使用されます。ansible-playbook -i inventory.ini check_and_fetch.yml出力は、デバッグタスクでの
statチェックの結果、それに続くfetchタスクを示します。PLAY [Check file status and fetch logs] **************************************** TASK [Gathering Facts] ********************************************************* ok: [localhost] TASK [Check if /etc/motd exists] *********************************************** ok: [localhost] TASK [Display stat results] **************************************************** ok: [localhost] => { "motd_status.stat": { "exists": true, "gid": 0, "isreg": true, "mode": "0644", "path": "/etc/motd", ... } } TASK [Fetch the dnf log file from managed host] ******************************** changed: [localhost] PLAY RECAP ********************************************************************* localhost : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0ログファイルが正常に取得されたことを確認します。
fetched_logsディレクトリの内容を一覧表示します。ls -l ~/project/fetched_logs/dnf.logファイルが表示され、現在はコントロールノードにローカルに保存されているはずです。total 4 -rw-r--r--. 1 labex labex 1234 Jul 10 15:30 dnf.log
これで、変更を行わずにファイルプロパティを検査する方法と、管理対象システムからコントロールノードに重要なファイルを取得する方法を学びました。
file モジュールで管理対象ホストのファイルをクリーンアップする
この最後のステップでは、ansible.builtin.file モジュールを使用して、システム上にファイルやディレクトリが 存在しない ことを保証する方法を学びます。構成管理の重要な部分は、リソースを作成および変更するだけでなく、それらをクリーンアップすることでもあります。state パラメータを absent に設定することで、Ansible にファイル、シンボリックリンク、またはディレクトリ全体を削除するように指示できます。
この実験を締めくくるために、前のステップで作成したすべての成果物(/tmp/info.txt、/etc/motd、/etc/issue、および /etc/issue.net のシンボリックリンク)を削除する単一の「クリーンアップ」プレイブックを作成します。
まず、
~/projectディレクトリにいることを確認します。cd ~/projectcleanup.ymlという名前の新しいプレイブックを作成します。 このプレイブックには、変更を元に戻すために必要なすべてのタスクが含まれます。nano ~/project/cleanup.ymlcleanup.ymlプレイブックに以下のコンテンツを追加します。 このプレイブックはタスクのリストを使用し、各タスクは作成したファイルのうちの 1 つを対象とします。become: trueはプレイレベルで設定されているため、すべてのタスクは昇格された権限で実行されます。--- - name: Clean up managed files from the system hosts: localhost become: true tasks: - name: Remove the temporary info file ansible.builtin.file: path: /tmp/info.txt state: absent - name: Remove the custom MOTD file ansible.builtin.file: path: /etc/motd state: absent - name: Remove the custom issue file ansible.builtin.file: path: /etc/issue state: absent - name: Remove the issue.net symbolic link ansible.builtin.file: path: /etc/issue.net state: absentこのプレイブックの鍵は、各タスクの
state: absentパラメータです。これは、指定されたpathにある項目が存在しないことを保証するようにfileモジュールに指示します。ファイルが見つかった場合は削除します。ファイルが既に存在しない場合は何も行わず、冪等性を維持します。クリーンアッププレイブックを実行します。
ansible-playbook -i inventory.ini cleanup.yml出力は、各タスクがファイルを削除することによって正常に変更を行ったことを示します。
PLAY [Clean up managed files from the system] ********************************** TASK [Gathering Facts] ********************************************************* ok: [localhost] TASK [Remove the temporary info file] ****************************************** changed: [localhost] TASK [Remove the custom MOTD file] ********************************************* changed: [localhost] TASK [Remove the custom issue file] ******************************************** changed: [localhost] TASK [Remove the issue.net symbolic link] ************************************** changed: [localhost] PLAY RECAP ********************************************************************* localhost : ok=5 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0ファイルが削除されたことを確認します。
lsコマンドを使用して、それらの存在を確認できます。コマンドは、ファイルが存在しないためアクセスできないことを報告します。ls /tmp/info.txt /etc/motd /etc/issue /etc/issue.net期待される出力は一連のエラーであり、クリーンアップが成功したことを確認します。
ls: cannot access '/tmp/info.txt': No such file or directory ls: cannot access '/etc/motd': No such file or directory ls: cannot access '/etc/issue': No such file or directory ls: cannot access '/etc/issue.net': No such file or directory
これで、Ansible を使用してファイルを削除し、システムをクリーンアップする方法を学び、作成から削除までのファイル管理の完全なライフサイクルを完了しました。
まとめ
この実験では、Ansible を使用して RHEL システム上のファイル管理の基本を学びました。まず、ansible.builtin.copy モジュールを使用して、特定の所有権と権限を設定しながら、静的ファイルを管理対象ホストに転送しました。次に、lineinfile を使用して特定の行が存在することを保証し、blockinfile を使用して複数行のテキストブロックを管理することで、既存のファイルを変更する方法を検討しました。カバーされた重要なスキルは、ansible.builtin.template モジュールと Jinja2 構文を使用して動的なファイルコンテンツを生成し、システムファクトで満たされたカスタマイズされたメッセージ・オブ・ザ・デイ (MOTD) を作成することでした。
さらに、ansible.builtin.file モジュールを使用してサポートファイルをデプロイし、シンボリックリンクを作成する練習をしました。デプロイメントが成功したことを確認するために、stat モジュールを使用してファイルのステータスと属性を検証し、fetch モジュールを使用してログなどのファイルを管理対象ホストからコントロールノードに取得しました。最後に、実験全体で作成したファイルとディレクトリを削除するために state: absent を持つ file モジュールを使用してクリーンアップ操作を実行する方法を学び、管理対象ホストのクリーンな状態を確保しました。


