ファイルを安全に転送する:Ansibleのcopyおよびfetchモジュールの使用
Ansibleのcopyおよびfetchアドホックコマンドを使用して、管理ノードにファイルをプッシュし、ログや設定をコントロールノードに取得します。
ファイルの安全な転送:Ansible CopyモジュールとFetchモジュールの使用
ファイルの移動は、Ansibleで最初に実践するタスクの1つです。サーバーに設定をプッシュしたり、ログファイルを収集したり、変更前にリモートファイルをバックアップしたりします。copyモジュールとfetchモジュールは、これら2つの方向の処理を明確に行います。
このガイドではアドホックコマンドを使用するため、完全なプレイブックを作成しなくても、1回限りの転送を実行できます。同じモジュール引数は、タスクを繰り返し可能にしたい場合にプレイブックでも使用できます。
前提条件
以下の例を実行する前に、次のものが揃っていることを確認してください。
- Ansibleコントロールノード: Ansibleがインストールされたマシン。
- インベントリファイル: 管理ノードを定義する動作可能なインベントリファイル(例:
/etc/ansible/hosts)。 - 接続性: リモートホストに設定されたSSHキーアクセス。
すべての例では、インベントリ内のターゲットグループがwebserversという名前であることを前提としています。
ファイル転送のためのアドホックコマンドについて
アドホックコマンドは、ターミナルから直接実行される1行のコマンドで、恒久的なプレイブックを必要としない簡単なタスクに最適です。基本的な構造は次のとおりです。
ansible <host-group> -m <module-name> -a "key=value key2=value2 ..."
ファイル転送には、-m copyまたは-m fetchモジュール名を使用し、-aフラグを使用して必須の引数を渡します。
copyモジュール:リモートノードへのファイルのプッシュ
copyモジュールは、Ansibleコントロールマシン上にあるファイルを1つ以上の管理ノードに転送するために使用されます。これは、設定ファイル、スクリプト、または小さなアセットをデプロイするための標準的な方法です。
copyの主要な引数
copyモジュールには2つの必須引数が必要であり、構成管理のためにいくつかのオプション引数を受け入れます。
| 引数 | 説明 | 必須? | 値の例 |
|---|---|---|---|
src |
Ansibleコントロールマシン上のローカルファイルパス。アドホックコマンドでは絶対パスが最も明確です。 | はい | /tmp/config.conf |
dest |
リモート管理ノード上にファイルが配置されるパス。 | はい | /etc/app/config.conf |
owner |
リモートノード上でファイルを所有するユーザーの名前。 | いいえ | nginx |
group |
リモートノード上でファイルを所有するグループの名前。 | いいえ | www-data |
mode |
宛先ファイルに設定するパーミッション(8進数)。 | いいえ | 0644 |
backup |
yesの場合、元のファイルを上書きする前にバックアップファイルを作成します。 |
いいえ | yes |
例1:シンプルなファイルのデプロイ
カスタムのMessage of the Day(motd)ファイルがローカルにあり、それをすべてのウェブサーバーにプッシュするとします。
# ローカルファイルパス:/home/user/ansible/motd_banner
# リモートの宛先:/etc/motd
ansible webservers -m copy -a "src=/home/user/ansible/motd_banner dest=/etc/motd"
例2:パーミッションと所有権の設定
安全な設定ファイルをデプロイする場合は、所有者、グループ、および制限されたパーミッション(例:所有者のみが読み取り/書き込み可能)を指定する必要があります。
# アプリケーション設定ファイルをデプロイ。所有者は'app_user'、グループは'devops'、
# 所有者のみ読み取り/書き込みパーミッション(0600)。
ansible webservers -m copy -b -a "src=/tmp/app_settings.yaml dest=/etc/app/settings.yaml owner=app_user group=devops mode=0600"
-bに関する注意:-b(または--become)フラグは、リモートの宛先に昇格されたパーミッションが必要な場合(/etcへの書き込みなど)に必要です。
fetchモジュール:リモートノードからのファイルの取得
fetchモジュールはcopyの逆の操作を実行します。管理ノードからAnsibleコントロールマシンにファイルを取得します。これは、設定ファイルのバックアップ、ログの取得、診断情報の収集に役立ちます。
fetchの主要な引数
fetchモジュールには、リモートノード上のソースファイルと、コントロールマシン上の宛先ディレクトリが必要です。
| 引数 | 説明 | 必須? | 値の例 |
|---|---|---|---|
src |
リモート管理ノード上のファイルの絶対パス。 | はい | /var/log/nginx/error.log |
dest |
コントロールマシン上でファイルが保存されるディレクトリの絶対パス。 | はい | /tmp/backups/logs |
flat |
yesの場合、結果のファイル名にホスト名構造が含まれません(複数のホストから取得する場合は推奨されません)。 |
いいえ | no(デフォルト) |
重要な違い:宛先の構造
copyモジュールとは異なり、fetchモジュールは、複数のサーバーからファイルを取得する際にファイル名の衝突を防ぐために、リモートホスト名に基づいた構造化されたサブディレクトリパスを自動的に作成します。
コントロールマシン上の結果のパスは次のようになります。
<dest>/<hostname>/<src>
たとえば、host1から/etc/nginx/nginx.confを/tmp/backupsに取得すると、次のようになります。
/tmp/backups/host1/etc/nginx/nginx.conf
例3:リモート設定のバックアップの取得
すべてのウェブサーバーから実行中の設定ファイルをローカルのバックアップディレクトリに取得するには、次のようにします。
# すべてのウェブサーバーからnginx.confをローカルディレクトリ/tmp/config_backupsに取得
ansible webservers -m fetch -a "src=/etc/nginx/nginx.conf dest=/tmp/config_backups"
このコマンドを実行した後、webserver1とwebserver2をターゲットにした場合、ローカルディレクトリ構造は次のようになります。
/tmp/config_backups/
├── webserver1
│ └── etc
│ └── nginx
│ └── nginx.conf
└── webserver2
└── etc
└── nginx
└── nginx.conf
例4:ホスト構造なしで単一ファイルを取得する(flat=yes)
単一のホストからのみファイルを取得することが絶対に確実な場合、またはファイルの内容のみが必要な場合(元の構造は不要な場合)は、flat=yesを使用できます。これにより、ファイルは元のリモートファイル名で宛先フォルダに直接配置されます。
# 単一のホストからローカルのヘルスステータスレポートを取得し、直接保存します。
ansible webserver1 -m fetch -a "src=/tmp/health_status.txt dest=/tmp/reports flat=yes"
# 結果のパス:/tmp/reports/health_status.txt
警告:
flat=yesは、単一のホストをターゲットにしている場合、または後続の実行でファイルを上書きするつもりがある場合にのみ使用してください。Ansibleは競合を防ぎません。
ベストプラクティスとセキュリティに関する考慮事項
小さなファイル転送のミスが本番環境のインシデントにつながる可能性があります。特に、ファイルが/etcに配置されたり、機密情報が含まれている場合です。
copyで常にパーミッションを設定する
modeとownerを明示的に定義せずに設定ファイルをプッシュしないでください。リモートシステムのデフォルトのumaskに依存すると、機密ファイル(SSHキーやデータベース認証情報など)のアクセス権限が過度に緩くなる可能性があります。
# 悪い例(モードがumaskから派生)
- name: 安全でないキーをデプロイ
ansible.builtin.copy:
src: private.key
dest: /etc/app/private.key
# 良い例(アクセスを明示的に制限)
- name: 安全なキーをデプロイ
ansible.builtin.copy:
src: private.key
dest: /etc/app/private.key
mode: '0600'
owner: root
重要な変更にはbackup=yesを使用する
copyを使用して既存の重要なファイル(例:/etc/sudoers)を上書きする場合は、backup=yesを含めてください。Ansibleは、ファイルを上書きする前にリモートノードにタイムスタンプ付きのバックアップコピーを作成し、簡単にロールバックできるようにします。
大規模な転送にはsynchronizeを検討する
copyとfetchは迅速な操作と小さなファイルに適していますが、大規模なディレクトリツリーや効率的な差分転送にはansible.posix.synchronizeを使用してください。これはrsyncをラップしているため、コントロールノードとターゲット環境に適切なrsyncとSSHアクセスが必要です。
まとめ
ソースがコントロールノード上にあり、宛先が管理ノード上にある場合はcopyを使用します。ソースが管理ノード上にあり、ファイルをローカルに保存したい場合はfetchを使用します。
| モジュール | 方向 | アドホックコマンドの例 |
|---|---|---|
copy |
コントロールノード -> 管理ノード | ansible all -m copy -a "src=/local/file dest=/remote/path mode=0644" |
fetch |
管理ノード -> コントロールノード | ansible all -m fetch -a "src=/remote/file dest=/local/dir" |
1台のサーバーの場合、flat=yesを使用すると、取得したファイルが読みやすくなります。サーバーのグループの場合は、デフォルトのホストベースのディレクトリ構造を維持して、あるホストのログが別のホストのログを上書きしないようにします。