こうした「Playbookの外にある情報をその場で取ってきたい」という要求に答えるのが、Lookupプラグインです。ファイルの内容・環境変数・CSVから値を検索・コマンドの出力・パスワード生成まで、多彩な外部データをPlaybook変数として動的に取り込めます。
この記事では、AnsibleのLookupプラグインの仕組みと代表的なプラグイン(file・env・csvfile・pipe・password)の使い方を、実際のPlaybookコードと出力例を交えて解説します。設計パターンまで解説するので、現場で即使えるPlaybookの「柔軟性」が身につきます。
動作確認環境:Ansible 2.16 / Rocky Linux 9.4(コントロールノード・管理対象ノード共通)
この記事のポイント
・Lookupプラグインはコントロールノードで評価され、外部データを変数に変換する仕組み
・file・env・csvfile・pipe・passwordの5種で現場の大半のユースケースを網羅できる
・query()を使うとLookupをリスト形式で返せてloopと組み合わせやすくなる
・pipeプラグインは外部入力をそのまま渡すとシェルインジェクションのリスクがある
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
LookupプラグインはPlaybookに「外側」の情報を引き込む仕組みです
Ansibleのvarsで変数を定義するとき、通常は「値を直接書く」か「vars_filesで別ファイルに記載する」のが基本です。しかし実際の現場では、こんな場面に遭遇します。・SSH公開鍵の内容をそのままauthorized_keysに登録したい
・実行環境(dev/prod)はCI/CDの環境変数で切り替えたい
・サーバーごとの設定値がCSVで管理されており、そこから読み込みたい
・初回実行時にパスワードを自動生成してファイルに保存したい
これらをvarsに手書きしようとすると「Playbookをコミットするたびに秘密情報が漏れる」「環境ごとに別のPlaybookを用意しなければならない」という問題が生じます。
Lookupプラグインはこうした問題を解決する仕組みです。Lookupはコントロールノード(Ansibleを実行するPC・サーバー)上で評価されるため、「ファイルを読む」「環境変数を取る」「コマンドを実行する」といった操作が変数展開のタイミングで自動的に行われます。
基本的な書き方は次の形です。
・変数定義でlookup関数を使う:
myvar: "{{ lookup('プラグイン名', '引数') }}"・モジュール引数の中で直接使う:
content: "{{ lookup('file', '/path/to/key.pub') }}"Lookupは通常、リストを返す場合も「最初の1要素」として扱われます。リスト全体が必要な場合は後述する
query()を使います。よく使うLookupプラグインと基本的な書き方
Ansibleには60以上のLookupプラグインが組み込まれています。現場でよく使う5種類を実際のコードと出力例で解説します。1. fileプラグイン — ローカルファイルの内容を読む
コントロールノード上のファイル内容を文字列として取得します。SSH公開鍵の登録や設定ファイルの内容をそのまま渡す用途に最も多く使われます。# playbook例 - name: authorized_keysにSSH公開鍵を登録する hosts: webservers vars: pub_key: "{{ lookup('file', '/home/ansible/.ssh/id_rsa.pub') }}" tasks: - name: deploy user の authorized_keys に公開鍵を追加 ansible.posix.authorized_key: user: deploy state: present key: "{{ pub_key }}"
# 複数ファイルを一度に取得(改行区切りの文字列として連結される) vars: multi_keys: "{{ lookup('file', '/home/ansible/.ssh/id_rsa.pub', '/home/jenkins/.ssh/id_rsa.pub') }}"
slurpモジュールやfetchモジュールを使ってください。2. envプラグイン — 環境変数を変数として取得する
コントロールノードの環境変数をPlaybook変数として取り込みます。CI/CDパイプラインからAPIキーや環境識別子を受け取るときに重宝します。# 環境変数を変数として利用する例 - name: 環境変数からデプロイ環境を取得する hosts: all vars: deploy_env: "{{ lookup('env', 'DEPLOY_ENV') | default('staging', true) }}" aws_region: "{{ lookup('env', 'AWS_DEFAULT_REGION') }}" tasks: - name: 環境名を表示 debug: msg: "デプロイ先: {{ deploy_env }}"
$ DEPLOY_ENV=production ansible-playbook deploy.yml TASK [環境名を表示] ***** ok: [web01] => { "msg": "デプロイ先: production" } ok: [web02] => { "msg": "デプロイ先: production" }
lookup('env', 'VAR')は空文字を返します。default()フィルタと組み合わせてデフォルト値を設定するのが実用的なパターンです。3. csvfileプラグイン — CSVから値を検索する
CSVファイルから特定の行・列の値を取得します。サーバーごとのポート番号やユーザーIDなど、スプレッドシートで管理されている設定値をPlaybookに取り込む用途に使えます。例として以下のCSVファイル(/etc/ansible/server_config.csv)を用意します。
# /etc/ansible/server_config.csv の内容 hostname,app_port,db_user,max_conn web01,8080,webapp,100 web02,8081,webapp,100 db01,5432,dbadmin,200
# csvfileプラグインでホスト名をキーに値を検索する - name: CSVからアプリポートを取得して確認する hosts: webservers vars: app_port: "{{ lookup('csvfile', inventory_hostname + ' file=/etc/ansible/server_config.csv col=1 delimiter=,') }}" tasks: - name: アプリケーションポートを確認 debug: msg: "{{ inventory_hostname }} のポート: {{ app_port }}" # 実行結果 TASK [アプリケーションポートを確認] ***** ok: [web01] => {"msg": "web01 のポート: 8080"} ok: [web02] => {"msg": "web02 のポート: 8081"}
col=は0始まりのカラムインデックスです。col=1はapp_port(2列目)を取得します。4. pipeプラグイン — コマンド実行結果を変数にする
コントロールノードでシェルコマンドを実行し、その標準出力を文字列変数として取得します。gitのコミットハッシュをデプロイ情報に含めたい場合などに使います。# gitのコミットハッシュとデプロイ日時を変数として取得する - name: デプロイ情報を記録する hosts: appservers vars: git_commit: "{{ lookup('pipe', 'git -C /home/ansible/myapp rev-parse --short HEAD') }}" deploy_time: "{{ lookup('pipe', 'date +%Y%m%d-%H%M%S') }}" tasks: - name: /var/www/myapp/deploy_info.txt を生成 copy: content: "commit={{ git_commit }}\ndeployed_at={{ deploy_time }}\n" dest: /var/www/myapp/deploy_info.txt # 管理対象ノード(app01)上のdeploy_info.txtの内容 commit=a3f92d1 deployed_at=20260922-113500
5. passwordプラグイン — ランダムパスワードを生成・保存する
ランダムな文字列を生成し、指定ファイルに保存します。初回実行時に生成したパスワードを以降の実行でも再利用できるのが特徴です。# DBユーザーのパスワードを自動生成して保存する - name: MariaDBの初期パスワードを設定する hosts: dbservers vars: db_root_password: "{{ lookup('password', '/etc/ansible/credentials/db_root length=20 chars=ascii_letters,digits') }}" tasks: - name: MariaDB root パスワードを設定 community.mysql.mysql_user: name: root password: "{{ db_root_password }}" login_unix_socket: /var/lib/mysql/mysql.sock update_password: on_create
/etc/ansible/credentials/db_rootというファイルが存在しない場合は新規生成して保存し、次回からはそのファイルの内容を読み返します。本番の認証情報は.gitignoreに追加してリポジトリにコミットしないこと、さらにAnsible Vaultと組み合わせてファイル自体を暗号化することを推奨します。lookupとquery・with_loopの使い分け
LookupをPlaybook内で使う方法は3種類あり、戻り値の型と使い所が異なります。lookup() — 文字列として1要素を返す
{{ lookup('file', 'a.txt', 'b.txt') }}のように複数引数を渡した場合、デフォルトでは改行区切りの文字列として返ります(リストではない)。モジュールのcontent:やkey:に単純な文字列を渡す場面で使います。query() — リストを返す
{{ query('file', 'a.txt', 'b.txt') }}は必ずリストを返します。loop:で繰り返し処理したい場合はquery()を使うとコードの意図が明確です。# query()でリストとして取得してloopで処理する例 - name: 複数の設定ファイルの内容を一覧表示 debug: msg: "{{ item }}" loop: "{{ query('file', '/etc/ansible/conf/app.conf', '/etc/ansible/conf/db.conf') }}"
with_file:やwith_items:のようなwith_プレフィックスはLookupプラグインを内部で呼び出す旧記法です。Ansible 2.5以降はloop: "{{ query(...) }}"形式が推奨されており、新規記述ではloopを使うのが現在の主流です。実践的な設計パターン3選
1. SSH公開鍵をファイルから読んでauthorized_keysに登録する
サーバー台数が増えてくると、デプロイユーザーやオペレーターのSSH公開鍵を全ホストに配布する作業が発生します。Lookupのfileプラグインとauthorized_keyモジュールを組み合わせると、鍵ファイルをPlaybookにハードコードせずに配布できます。# roles/ssh_keys/tasks/main.yml - name: チームメンバーの公開鍵を配布する ansible.posix.authorized_key: user: deploy state: present key: "{{ lookup('file', item) }}" loop: - /home/ansible/keys/alice_id_rsa.pub - /home/ansible/keys/bob_id_rsa.pub - /home/ansible/keys/charlie_id_rsa.pub # 実行結果(10台のwebserversグループに一括適用) TASK [チームメンバーの公開鍵を配布する] ***** changed: [web01] => (item=/home/ansible/keys/alice_id_rsa.pub) ok: [web01] => (item=/home/ansible/keys/bob_id_rsa.pub) changed: [web01] => (item=/home/ansible/keys/charlie_id_rsa.pub) ...(10台分繰り返し) PLAY RECAP **** web01 : ok=3 changed=2 ... web02 : ok=3 changed=2 ...
/home/ansible/keys/ディレクトリにまとめておけば、新メンバーの追加・退職者の削除も鍵ファイルの追加・削除とPlaybookの1行変更だけで完結します。2. 環境変数で本番・ステージングを切り替えるenv lookup設計
GitHub ActionsやJenkinsなどのCI/CDツールからPlaybookを呼び出す場合、デプロイ先環境の識別子(dev/staging/production)をCI側の環境変数として設定し、Playbook側はそれをlookupで受け取る設計が実践的です。# group_vars/all.yml env_name: "{{ lookup('env', 'TARGET_ENV') | default('staging', true) }}" # roles/app_config/templates/app.conf.j2 [server] environment = {{ env_name }} log_level = {% if env_name == 'production' %}warn{% else %}debug{% endif %} max_connections = {% if env_name == 'production' %}200{% else %}50{% endif %} # CI/CDからの実行(GitHub Actions の step 例) # - run: TARGET_ENV=production ansible-playbook -i inventories/production/ deploy.yml # ローカル確認時(staging) # $ TARGET_ENV=staging ansible-playbook -i inventories/staging/ deploy.yml
3. CSVからサービス設定値を取得して複数ホストに展開する
ホストごとのアプリポートやDB接続情報がExcelで管理されている現場では、CSVエクスポートしたファイルをlookup('csvfile')で直接読み込む設計が有効です。Inventoryのhost_varsにすべて書き起こす手間が省けます。# /etc/ansible/server_config.csv hostname,app_port,max_workers,db_host app01,8080,4,db-primary.internal app02,8081,4,db-primary.internal app03,8082,2,db-replica.internal # playbook(server_config.csvの値を使ってアプリ設定を構成する) - name: アプリケーションの設定ファイルを生成する hosts: appservers vars: app_port: "{{ lookup('csvfile', inventory_hostname + ' file=/etc/ansible/server_config.csv col=1 delimiter=,') }}" max_workers: "{{ lookup('csvfile', inventory_hostname + ' file=/etc/ansible/server_config.csv col=2 delimiter=,') }}" db_host: "{{ lookup('csvfile', inventory_hostname + ' file=/etc/ansible/server_config.csv col=3 delimiter=,') }}" tasks: - name: /etc/app/app.conf を生成 template: src: app.conf.j2 dest: /etc/app/app.conf notify: restart app # app01上の /etc/app/app.conf 生成後の内容確認 [root@app01 ~]# cat /etc/app/app.conf [app] port = 8080 workers = 4 database_host = db-primary.internal
AnsibleのPlaybook設計を現場で体系的に学びたい方へ
LookupプラグインはAnsibleの変数設計を理解していることで真価を発揮します。vars優先順位・インベントリ変数・Vault連携まで含めた設計を体系的に身につけたい方は、現役エンジニアによる実践ハンズオンを活用してください。
>> Ansible実践セミナーの詳細はこちら
トラブルシュート — よくあるエラーと対処法
「lookup('file')でファイルが見つからない」# エラーメッセージの例 TASK [authorized_keyに公開鍵を追加] fatal: [web01]: FAILED! => { "msg": "An unhandled exception occurred while running the lookup plugin 'file'. Error was a
, original message: could not locate file in lookup: /home/ansible/keys/alice_id_rsa.pub" }
・fileプラグインはコントロールノードのファイルを読みます。管理対象ノードのパスを指定していないか確認してください
・相対パスで指定した場合、Playbookのディレクトリからの相対パスとして解釈されます
・絶対パスか
{{ playbook_dir }}/keys/alice_id_rsa.pubのようなPlaybook変数を使うと確実です「lookup('env')が常に空文字を返す」
Lookupはコントロールノード上の環境変数を参照します。
sudoやsu -経由で実行した場合、元ユーザーの環境変数が引き継がれないケースがあります。ansible-playbookを実行するシェルでecho $TARGET_ENVを確認し、正しく設定されているかチェックしてください。「lookup('password')で毎回別のパスワードが生成される」
保存先のファイルパスに誤字がある場合、既存ファイルが読み込まれず毎回新規生成が起きます。ファイルパスの末尾にスペースや改行が混入していないか確認してください。また、複数のコントロールノードからPlaybookを実行する環境では、パスワードファイルをNFSや共有ストレージ上に置いて全ノードが同一ファイルを参照できるようにする必要があります。
「with_fileとwith_itemsを混在させて意図しない動作になる」
with_file:はリストの各要素をファイルパスとして解釈してファイル内容を返します。単純なリスト反復にはwith_items:(またはloop:)を使い、ファイル内容が欲しい場合のみwith_file:(またはloop: "{{ query('file', ...) }}")を使うよう使い分けると混乱を防げます。本記事のまとめ
| プラグイン | 用途 | 典型的な使い方 |
|---|---|---|
| file | ローカルファイル内容を取得 | lookup('file', '/path/to/key.pub') |
| env | 環境変数を取得 | lookup('env', 'TARGET_ENV') | default('staging') |
| csvfile | CSVから値を検索 | lookup('csvfile', 'host file=c.csv col=1 delimiter=,') |
| pipe | コマンド出力を取得 | lookup('pipe', 'git rev-parse --short HEAD') |
| password | ランダム文字列の生成・保存 | lookup('password', '/path/to/cred length=20') |
| query() | リスト形式でlookupを呼ぶ | loop: "{{ query('file', 'a.pub', 'b.pub') }}" |
lookup('file', ...)を取り入れるところから始めてみてください。
Ansible実践ハンズオンの詳細を見る >>
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:Ansibleのrole命名と変数プレフィックス規約|複数roleを併用しても名前が衝突しない名前空間を作る
- この記事の属するカテゴリ:Ansibleへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます