エラーの内容
ERROR! this task 'copy' has extra params, which is only allowed in the following modules: raw, meta, include, include_tasks, import_tasks
ansible-playbook を実行すると即座に終了します — 接続の試み、ホスト出力、何もありません。問題はリモートホストではなく、タスク定義自体にあります。
原因
Ansible のモジュールは引数を2つの方法で受け取ります:
- フリーフォーム(インライン文字列):
command、shell、raw、scriptのみ有効。モジュールキーと同じ行に1つの文字列を記述します。 - キー=値 または YAML ディクト:それ以外のすべて —
copy、file、apt、templateなど。
このエラーは、これらのスタイルを混在させた場合に発生します。多くの場合、モジュールの下にネストされるべきパラメータがタスクレベルに配置されているか、インライン文字列と YAML キーが同じタスクブロック内で混在しています。引数が1つでも誤った位置にあれば発生します。
よくある原因パターン
パターン1:タスクレベルに余分なキーを置いてしまった場合
# 誤り
- name: Copy config file
copy: src=files/app.conf dest=/etc/app/app.conf
mode: '0644' # <-- copy: の下ではなくタスクレベルに記述されている
owner: root
mode と owner がモジュール内ではなくタスクディクトに配置されています。Ansible はこれらを未知のタスクレベルキーとして扱い、エラーをスローします。
パターン2:フリーフォーム文字列と YAML ディクトキーの混在
# 誤り
- name: Copy config file
copy: src=files/app.conf dest=/etc/app/app.conf
mode: '0644'
インライン キー=値 文字列と同じモジュールキー下のインデントされた YAML を混在させると、パーサーが壊れます。どちらか一方のスタイルに統一してください。
パターン3:タスクブロックに2つ目のモジュールキーが残っている場合
# 誤り
- name: Restart nginx
service:
name: nginx
state: restarted
copy: # <-- カット&ペーストの残骸
src: files/nginx.conf
dest: /etc/nginx/nginx.conf
タスクに含められるモジュールは1つだけです。2つ目のモジュールキー(ここでは copy:)は未認識の余分なパラメータになります — コピー&ペーストによるよくあるミスです。
修正方法
YAML ディクト構文でモジュール下にすべての引数をネストする
# 正しい
- name: Copy config file
copy:
src: files/app.conf
dest: /etc/app/app.conf
mode: '0644'
owner: root
すべての引数をインデントされたキーとして copy: の下に記述します。copy: と同じインデントレベルには、標準のタスクキーワードのみ記述します:name、when、notify、tags、become などです。
インライン キー=値 も使用可能 — ただし1行にまとめること
# 正しい — すべての引数をインラインで記述
- name: Copy config file
copy: src=files/app.conf dest=/etc/app/app.conf mode='0644' owner=root
引数が3〜4個を超えると、テキストの塊になってしまいます。YAML ディクト形式の方が読みやすく、プルリクエストでのレビューもしやすいです。
フリーフォームモジュール(command、shell)は動作が異なります
# 正しい — shell/command はフリーフォームを使用
- name: Check disk usage
shell: df -h /
# 正しい — 構造化オプションはインラインに混在させず args: の下に記述
- name: Run script with timeout
command: /opt/scripts/deploy.sh
args:
chdir: /opt/scripts
フリーフォームモジュールでも、chdir や stdin などの構造化オプションは args: の下に記述します。コマンド文字列と一緒にインラインで記述してはいけません。
素早い診断方法
Ansible はエラーメッセージに問題のあるタスク名を表示します。プレイブック内でそのタスクを見つけ、以下を確認してください:
- タスクのトップレベルに、標準の Ansible キーワード以外のキーがないか(
name、when、register、loop、notify、tags、become、ignore_errorsなど) - モジュール引数のインデントが1段高すぎる箇所
- 同じタスクブロックに2つのモジュールキーがないか
リモートホストに触れる前に、構文チェックを実行してください:
ansible-playbook site.yml --syntax-check
SSH 接続なし、リスクなし — YAML の高速パースだけです。
修正の確認
# 構文チェック — エラーなしで返るはず
ansible-playbook site.yml --syntax-check
# 期待される出力
playbook: site.yml
# タスクが正しく実行されるか確認するドライラン
ansible-playbook site.yml --check --diff
--syntax-check がクリーンに終了すれば、余分なパラメータエラーは解消されています。続けて --check --diff を実行すると、リモートホストに触れることなく、タスクが実際に何を変更するかを確認できます。
今後のために — 予防のコツ
- フリーフォーム以外のモジュールには YAML ディクト構文を基本とする。 インデントのミスが一目でわかりやすくなります。
- CI パイプラインに
--syntax-checkを追加する。 PR がマージされる前に、この種のエラーを1秒以内に検出できます。 - ローカルで
ansible-lintを実行する。pip install ansible-lintでインストールし、ansible-lint site.ymlを実行します。混在した構文やその他多数のスタイル問題を検出します。 - VS Code の Ansible 拡張機能(Red Hat 製)をインストールする。 入力中に構造上のエラーが赤い波線で表示されます — 何かを実行する必要はありません。

