Ansibleで学ぶmountモジュール:よくあるエラーと解決策

2025-06-06

mount モジュールの主な機能と特徴

  • 主要なパラメータ:
    • path (旧 name): マウントポイントのパス(例: /mnt/data)。必須パラメータです。
    • src: マウントするデバイスのパス(例: /dev/sdb1UUID=...、NFS共有のパスなど)。statepresent または mounted の場合に必須です。
    • fstype: ファイルシステムの種類(例: ext4, xfs, nfs など)。statepresent または mounted の場合に必須です。
    • opts: マウントオプション(例: defaults, ro, noatime など)。/etc/fstab のオプションとして設定されます。
    • dump: fstabdump フィールドを設定します。
    • passno: fstabpassno フィールドを設定します。
    • fstab: デフォルトの /etc/fstab 以外のファイルを指定する場合に利用します。通常は使用しません。
    • backup: fstab を変更する際にバックアップを作成するかどうかを指定します。
  • 状態 (state) パラメータ: mount モジュールは state パラメータを通じて、マウントポイントの望ましい状態を指定します。主な state の値は以下の通りです。
    • mounted: デバイスをマウントし、必要に応じて /etc/fstab にもエントリを追加します。マウントポイントのディレクトリが存在しない場合は作成されます。
    • unmounted: デバイスをアンマウントしますが、/etc/fstab のエントリは変更しません。
    • present: /etc/fstab にエントリがあることを保証しますが、実際にマウントは行いません。
    • absent: /etc/fstab からエントリを削除し、マウントされている場合はアンマウントし、マウントポイントのディレクトリも削除します。
    • ephemeral (Ansible 1.5.0以降のansible.posix.mountモジュールで追加): デバイスをマウントしますが、/etc/fstabにはエントリを追加しません。一時的なマウントに便利です。
    • remounted (Ansible 2.9以降で追加): 既にマウントされているデバイスを再マウントします。主にマウントオプションを変更した場合などに使用します。
  • 冪等性 (Idempotency): Ansible の多くのモジュールと同様に、mount モジュールも冪等性を持っています。これは、Playbook を複数回実行しても、システムの状態が既に目的の状態であれば、余計な変更は行われないことを意味します。例えば、既にマウントされているものを再度マウントしようとしても、変更は発生しません。
  • マウントポイントの制御:
    • マウント: デバイスをディレクトリにマウントします。
    • アンマウント: マウントされているデバイスをアンマウントします。
    • /etc/fstab の管理: システム起動時に自動的にマウントされるように /etc/fstab にエントリを追加したり、既存のエントリを変更・削除したりできます。
---
- name: マウントポイントを管理する例
  hosts: your_target_servers
  become: yes # root 権限で実行する必要があるため

  tasks:
    - name: /dev/sdb1  /mnt/data  ext4 としてマウントし、fstab にも追加する
      ansible.posix.mount: # または mount: (FQCNを使用することが推奨されます)
        path: /mnt/data
        src: /dev/sdb1
        fstype: ext4
        opts: defaults
        state: mounted

    - name: /mnt/backup  fstab に存在することを保証する(マウントはしない)
      ansible.posix.mount:
        path: /mnt/backup
        src: UUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # UUID を使用することも可能
        fstype: xfs
        opts: defaults
        state: present

    - name: /mnt/old_data をアンマウントする(fstab は変更しない)
      ansible.posix.mount:
        path: /mnt/old_data
        state: unmounted

    - name: /mnt/obsolete  fstab エントリを削除し、アンマウントし、ディレクトリも削除する
      ansible.posix.mount:
        path: /mnt/obsolete
        state: absent

    - name: /mnt/temp_share を一時的にマウントする (fstabには記録しない)
      ansible.posix.mount:
        path: /mnt/temp_share
        src: 192.168.1.100:/share
        fstype: nfs
        opts: defaults
        state: ephemeral


よくあるエラーとその原因

a. path (マウントポイント) の問題

  • 原因:
    • 指定された path (マウントポイント) が存在しない、または権限がないために作成できない。
    • マウントポイントが既に別のファイルシステムによって使用されている、またはプロセスがそのディレクトリを使用しているため、アンマウントできない(unmountedabsent の場合)。
    • state: mounted を使用しているが、マウントポイントのディレクトリが既存のファイルシステムで既に使われている。
  • エラーメッセージの例:
    • "msg": "mount point /mnt/data does not exist" (Ansibleがマウントポイントのディレクトリを作成できない場合)
    • "msg": "Error mounting /dev/sdb1 on /mnt/data: mount: /mnt/data: mount point is busy."

b. src (デバイス/ソース) の問題

  • 原因:
    • src で指定されたデバイス(例: /dev/sdb1)が存在しない、または名前が間違っている。
    • デバイスが既に別の場所にマウントされている。
    • ファイルシステムタイプ (fstype) が間違っている、またはデバイスがそのファイルシステムタイプでフォーマットされていない。
    • NFSなどのネットワークファイルシステムの場合、サーバーへの接続性がない、または共有が存在しない。
  • エラーメッセージの例:
    • "msg": "Error mounting /dev/sdb1 on /mnt/data: mount: /dev/sdb1: no such device"
    • "msg": "Error mounting /dev/sdb1 on /mnt/data: mount: /dev/sdb1 is already mounted on /another/path."
    • "msg": "Error mounting /dev/sdb1 on /mnt/data: mount: wrong fs type, bad option, bad superblock on /dev/sdb1, missing codepage or helper program, or other error."

c. fstype (ファイルシステムタイプ) の問題

  • 原因:
    • fstype パラメータに存在しない、またはサポートされていないファイルシステムタイプを指定した。
    • 指定されたデバイスが、実際にそのファイルシステムタイプでフォーマットされていない。
  • エラーメッセージの例:
    • "msg": "Error mounting /dev/sdb1 on /mnt/data: mount: unknown filesystem type 'xyzfs'"

d. opts (マウントオプション) の問題

  • 原因:
    • opts に無効なマウントオプションを指定した。
  • エラーメッセージの例:
    • "msg": "Error mounting /dev/sdb1 on /mnt/data: mount: /mnt/data: bad option 'bad_option_name'."

e. 権限の問題

  • 原因:
    • Ansible Playbook が become: yes (sudo/root 権限) なしで実行されている、またはリモートホストのユーザーにマウント操作を実行する権限がない。マウント操作は通常、root 権限が必要です。
  • エラーメッセージの例:
    • "msg": "mount: permission denied"

f. /etc/fstab の同期に関する問題

  • 原因:
    • state: mountedstate: present/etc/fstab にエントリを追加したはずが、何らかの理由で書き込みに失敗した。
    • fstab ファイルが破損している、または不正なエントリがある。
  • エラーメッセージの例:
    • Ansible の出力では直接的なエラーメッセージではなく、マウントは成功したが再起動後にマウントされない、などの挙動で現れることがあります。

a. 詳細なデバッグ出力の確認

  • Ansible の実行時に -vvv または -vvvv オプションを追加して、詳細なデバッグ情報を確認します。
    ansible-playbook your_playbook.yml -vvv
    
    これにより、mount コマンドがバックグラウンドでどのように実行され、どのようなエラーメッセージが返されているかを確認できます。

b. リモートホストでの手動実行の試行

  • Ansible を実行しているリモートホストに SSH でログインし、Playbook が実行しようとしている mount コマンドを手動で試してみます。
    • 例: sudo mount /dev/sdb1 /mnt/data
    • 例: sudo umount /mnt/old_data
    • 手動で実行することで、Ansible の問題なのか、基盤となるOSレベルの問題なのかを切り分けることができます。エラーメッセージがより明確に出力されることが多いです。

c. 前提条件の確認

  • マウントポイントディレクトリの確認:
    • ls -ld /mnt/data でマウントポイントのディレクトリが存在するか、権限は適切かを確認します。
    • state: mounted を使用する場合、通常はディレクトリが自動作成されますが、権限の問題などで作成できない場合はエラーになります。file モジュールで事前に作成することも検討できます。
  • ファイルシステムの確認:
    • sudo blkid /dev/sdb1 でデバイスのUUIDやファイルシステムタイプを確認し、Playbook の srcfstype と一致しているか確認します。
  • デバイスの存在確認:
    • lsblkfdisk -ldf -h コマンドを使って、指定したデバイス (src) が実際に存在し、認識されているかを確認します。
    • NFS の場合、pingshowmount -e <NFS_SERVER_IP> でサーバーへの到達性や共有の存在を確認します。

d. マウントポイントの「busy」状態の解消

  • mount point is busy エラーの場合、そのマウントポイントを使用しているプロセスを特定して終了させる必要があります。
    • lsof | grep /mnt/data または fuser -m /mnt/data を実行して、どのプロセスがマウントポイントを使用しているかを確認します。
    • 必要であれば、これらのプロセスを終了させます。
    • 強制的にアンマウントする場合は sudo umount -l /mnt/data (lazy unmount) や sudo umount -f /mnt/data (force unmount) を手動で試すこともできますが、データ破損のリスクがあるので注意が必要です。

e. /etc/fstab の整合性チェック

  • state: absent でエントリが削除されない場合、手動で /etc/fstab を確認し、該当エントリが存在しないか確認します。
  • sudo findmnt --verify コマンドで /etc/fstab の構文チェックを行うことができます。
  • /etc/fstab に手動で誤ったエントリを追加していないか確認します。

f. 冪等性の理解と利用

  • state: presentstate: mounted の違いを理解し、適切に使い分けます。
    • present: /etc/fstab にエントリがあることを保証しますが、マウントは強制しません。
    • mounted: マウントを強制し、必要に応じて /etc/fstab にもエントリを追加します。
  • mount モジュールは冪等性があるため、同じ設定で複数回実行しても問題ありません。エラーが出ている場合は、設定が間違っているか、環境に問題がある可能性が高いです。

g. block / rescue を利用したエラーハンドリング

  • Playbook で予期せぬエラーが発生した場合に備え、blockrescue を利用してエラーハンドリングを行うこともできます。
    - name: マウントを試みる
      block:
        - ansible.posix.mount:
            path: /mnt/data
            src: /dev/sdb1
            fstype: ext4
            state: mounted
      rescue:
        - name: マート失敗時に通知する
          debug:
            msg: "マウント /mnt/data が失敗しました。ログを確認してください。"
        # 必要であれば、失敗したデバイスのログ収集や、別のリカバリタスクを実行
    


mount モジュールを使う際の主要なパラメータは以下の通りです。

  • state: マウントポイントの望ましい状態。
  • fstype: ファイルシステムの種類(例: ext4, xfs, nfs)。
  • src: マウントするデバイスやソース(例: /dev/sdb1UUID=...、NFSサーバーのパス)。
  • path: マウントポイントのパス(例: /mnt/data)。

それぞれの state に応じたコード例を見ていきましょう。

state: mounted - デバイスをマウントし、必要に応じて /etc/fstab に追加する

この state は、デバイスが指定されたマウントポイントにマウントされていることを保証し、さらにシステム起動時に自動的にマウントされるよう /etc/fstab にエントリを追加します。マウントポイントのディレクトリが存在しない場合は、自動的に作成されます。

---
- name: デバイスをマウントし、fstabにも追加する例
  hosts: your_target_servers
  become: yes # マウント操作にはroot権限が必要

  tasks:
    - name: /dev/sdb1  /mnt/data  ext4 としてマウントし、fstab に永続化
      ansible.posix.mount:
        path: /mnt/data
        src: /dev/sdb1
        fstype: ext4
        opts: defaults,noatime # オプションの指定
        state: mounted

解説

  • state: mounted: これにより、/dev/sdb1/mnt/data にマウントされ、かつ /etc/fstab に永続的なエントリが追加されます。
  • opts: defaults,noatime: マウントオプションとして defaults (デフォルトのオプション) と noatime (ファイルのアクセス時刻の更新を無効化) を指定しています。
  • fstype: ext4: ファイルシステムの種類は ext4 です。
  • src: /dev/sdb1: マウントするデバイスは /dev/sdb1 です。
  • path: /mnt/data: /mnt/data がマウントポイントになります。もしこのディレクトリがなければ、Ansibleが自動的に作成します。

state: present - /etc/fstab にエントリがあることを保証する(マウントはしない)

この state は、指定されたエントリが /etc/fstab ファイル内に存在することを保証しますが、Playbook 実行時に実際にマウント操作は行いません。システム起動時にマウントされるように設定だけしておきたい場合に便利です。

---
- name: fstabにエントリを追加するが、マウントはしない例
  hosts: your_target_servers
  become: yes

  tasks:
    - name: UUID を使用して /mnt/backup  fstab エントリが存在することを確認
      ansible.posix.mount:
        path: /mnt/backup
        src: UUID="a1b2c3d4-e5f6-7890-1234-567890abcdef" # デバイスのUUIDを指定
        fstype: xfs
        opts: defaults
        state: present

解説

  • state: present: これにより、/etc/fstab にエントリが追加または更新されますが、Ansible Playbook の実行中にマウントはされません。マウントは次回のシステム起動時に行われるか、手動で mount /mnt/backup と実行する必要があります。
  • src: UUID="...": デバイスのパスの代わりに UUID (Universally Unique Identifier) を使うと、デバイス名(例: /dev/sdb1)が変わっても確実に識別できるため、より堅牢な設定が可能です。sudo blkid コマンドでデバイスの UUID を確認できます。

state: unmounted - マウントされたデバイスをアンマウントする

この state は、指定されたマウントポイントがアンマウントされていることを保証します。/etc/fstab のエントリは変更されません。

---
- name: デバイスをアンマウントする例
  hosts: your_target_servers
  become: yes

  tasks:
    - name: /mnt/old_data をアンマウントする (fstab は変更しない)
      ansible.posix.mount:
        path: /mnt/old_data
        state: unmounted

解説

  • state: unmounted: これにより、/mnt/old_data がマウントされていればアンマウントされます。もし /etc/fstab にこのマウントポイントのエントリがあっても、それはそのまま残ります。
  • path: /mnt/old_data: アンマウントするマウントポイントを指定します。

state: absent - /etc/fstab からエントリを削除し、アンマウントし、ディレクトリも削除する

この state は、指定されたマウントポイントに関連する /etc/fstab のエントリを削除し、もしマウントされていればアンマウントし、さらにマウントポイントのディレクトリも削除します。完全にクリーンアップしたい場合に便利です。

---
- name: マウントポイントとfstabエントリを完全に削除する例
  hosts: your_target_servers
  become: yes

  tasks:
    - name: /mnt/obsolete  fstab から削除し、アンマウントし、ディレクトリも削除
      ansible.posix.mount:
        path: /mnt/obsolete
        state: absent

解説

  • state: absent: この設定により、/mnt/obsolete に関連する /etc/fstab のエントリが削除され、もしマウントされていればアンマウントされ、そして /mnt/obsolete ディレクトリ自体も削除されます。

state: ephemeral - 一時的にマウントする(/etc/fstab に追加しない)

この state は、デバイスをマウントしますが、/etc/fstab にエントリを追加しません。一時的なマウントや、Ansible 実行時のみ必要なマウントポイントを設定するのに適しています。Playbook の実行が完了すると、通常はマウントされたままですが、再起動すると消えます。

---
- name: 一時的なマウントの例 (NFS共有)
  hosts: your_target_servers
  become: yes

  tasks:
    - name: NFS共有を /mnt/temp_share に一時的にマウント
      ansible.posix.mount:
        path: /mnt/temp_share
        src: 192.168.1.100:/exports/data # NFSサーバーのIPと共有パス
        fstype: nfs
        opts: defaults
        state: ephemeral
  • state: ephemeral: これにより、NFS共有が /mnt/temp_share にマウントされますが、/etc/fstab には何も書き込まれません。システムを再起動すると、このマウントは失われます。


ansible.builtin.command または ansible.builtin.shell モジュール

最も直接的な代替手段は、command または shell モジュールを使って、OS ネイティブのマウント関連コマンドを直接実行することです。これは、mount モジュールでは対応できない特殊なケースや、非常に細かい制御が必要な場合に利用されます。

利点

  • トラブルシューティング時に、Ansible から実行される実際のコマンドを確認しやすい。
  • mount モジュールが提供しない特定のオプションや機能を利用できる。
  • 非常に柔軟性が高く、任意のコマンドを実行できる。

欠点

  • 状態のチェックや変更の判断をスクリプト内でロジックとして書く必要がある。
  • エラーハンドリングが手動になる。
  • 冪等性 (Idempotency) の管理が複雑: ほとんどの commandshell コマンドは冪等性を持たないため、タスクがシステムに不必要な変更を加えないように、自身で条件分岐 (when) や changed_when を使用して冪等性を実装する必要があります。

コード例

a. mount コマンドを直接実行する

- name: commandモジュールでディスクをマウントする (非推奨)
  hosts: your_target_servers
  become: yes

  tasks:
    - name: /dev/sdb1  /mnt/data にマウント(冪等性なし)
      ansible.builtin.command: mount /dev/sdb1 /mnt/data
      args:
        creates: /mnt/data/.mounted_sdb1 # 既にマウントされている場合はスキップする簡単な冪等性対策
      # 注意: fstabへの永続化は行われません

b. fstab を編集するために shell と grep/sed を使う (非推奨)

- name: shellモジュールでfstabを編集する (非推奨)
  hosts: your_target_servers
  become: yes

  tasks:
    - name: /etc/fstab にエントリを追加(冪等性なし)
      ansible.builtin.shell: |
        grep -q '/mnt/data' /etc/fstab || echo '/dev/sdb1 /mnt/data ext4 defaults 0 0' >> /etc/fstab
      args:
        warn: no # このような複雑なコマンドには警告を出さない
      # 注意: 既存のエントリの変更や削除はさらに複雑になります

c. 冪等性を考慮した mount コマンドの実行例

- name: mountコマンドと条件分岐で冪等性を確保する
  hosts: your_target_servers
  become: yes

  tasks:
    - name: マウントポイントが既にマウントされているか確認
      ansible.builtin.shell: mountpoint -q /mnt/data
      register: mount_check
      failed_when: mount_check.rc not in [0, 1] # 0はマウント済み、1は未マウント
      changed_when: false # このタスクは変更を行わない

    - name: /dev/sdb1  /mnt/data にマウント (未マウントの場合のみ)
      ansible.builtin.command: mount /dev/sdb1 /mnt/data
      when: mount_check.rc == 1 # mountpoint が未マウントを返した場合のみ実行

考察
commandshell を使う場合、冪等性の確保が最も重要です。changed_whenfailed_whenwhen などの条件分岐や、creates/removes などの args を駆使して、Playbook が繰り返し実行されても安全であることを確認する必要があります。これは複雑になりがちで、推奨される方法ではありません。

ansible.builtin.lineinfile または ansible.builtin.blockinfile モジュール

これらのモジュールは、/etc/fstab のようなテキストファイルを管理するのに適しています。ファイル内の特定の行を追加、削除、または変更するために使用できます。

利点

  • 設定ファイルのコメントや特定セクションの管理に役立つ。
  • state: present/absentregexp (lineinfile)、block (blockinfile) を使って冪等性を実現できる。
  • テキストファイルの特定の行を確実に管理できる。

欠点

  • マウントポイントの存在確認や作成は別途行う必要がある。
  • マウントオプションやデバイスのUUIDの自動検出などの高度な機能はない。
  • 実際にデバイスをマウント/アンマウントする機能はない。ファイルの内容(/etc/fstab)を編集するのみ。

コード例

- name: lineinfileでfstabを管理する例
  hosts: your_target_servers
  become: yes

  tasks:
    - name: /etc/fstab  /mnt/data のエントリを追加または更新
      ansible.builtin.lineinfile:
        path: /etc/fstab
        regexp: '^/dev/sdb1\s+/mnt/data' # /dev/sdb1 /mnt/data で始まる行を検索
        line: '/dev/sdb1 /mnt/data ext4 defaults,noatime 0 0'
        state: present
        backup: yes # 変更前に元のファイルをバックアップ

    - name: /etc/fstab から /mnt/old_data のエントリを削除
      ansible.builtin.lineinfile:
        path: /etc/fstab
        regexp: '^UUID="a1b2c3d4-e5f6-7890-1234-567890abcdef"\s+/mnt/old_data'
        state: absent

考察
lineinfile/etc/fstab のような構造化されていない設定ファイルに特定のエントリを追加・削除するのに便利ですが、マウント操作自体は行いません。したがって、この方法を使う場合は、ファイル編集後に別途 mount -a コマンドを実行して、設定を反映させる必要があるかもしれません。

ansible.builtin.filesystem モジュール (パーティションのフォーマット)

これは直接マウントを制御するモジュールではありませんが、マウントする前の前提条件として、デバイスをフォーマットするために使用されます。

利点

  • 冪等性があるため、既にフォーマットされていれば何も変更しない。
  • 特定のデバイスを目的のファイルシステムで確実にフォーマットできる。

欠点

  • ディスクの初期化やパーティション作成のステップは別途必要。
  • マウント操作自体は行わない。

コード例 (mount モジュールと組み合わせて使う)

- name: 新しいディスクのフォーマットとマウントの例
  hosts: your_target_servers
  become: yes

  tasks:
    - name: マウントポイントディレクトリを作成
      ansible.builtin.file:
        path: /mnt/new_data
        state: directory
        mode: '0755'

    - name: /dev/sdc  ext4 でフォーマット(すでにフォーマット済みならスキップ)
      ansible.posix.filesystem: # filesystemモジュールは ansible.posix コレクションに属します
        fstype: ext4
        dev: /dev/sdc
        force: yes # 必要であれば強制的にフォーマット

    - name: /dev/sdc  /mnt/new_data にマウントし、fstab に追加
      ansible.posix.mount:
        path: /mnt/new_data
        src: /dev/sdc
        fstype: ext4
        opts: defaults
        state: mounted

より複雑なロジックや、Ansible が提供するモジュールでは対応が難しい特定のベンダー固有のストレージ管理ツールなどを利用する必要がある場合は、カスタムのシェルスクリプトや Python スクリプトを書き、それを ansible.builtin.script または ansible.builtin.command/ansible.builtin.shell モジュールで実行する方法もあります。

利点

  • 特定のツールや API と連携できる。
  • 任意の複雑なロジックを実装できる。

欠点

  • デバッグやメンテナンスが難しくなる可能性がある。
  • Ansible の抽象化の恩恵を受けられない。
  • 冪等性の管理が完全に自己責任: スクリプト内で冪等性を考慮したロジックを実装する必要がある。

Ansible でマウントポイントを制御する際には、**公式の mount モジュールを使用することが最も推奨されます。**これは、冪等性が組み込まれており、エラーハンドリングが適切に処理され、コードの可読性と保守性が高いためです。