てくなべ (tekunabe)

ansible / network automation / 学習メモ

[Ansible] エラー「SyntaxError: future feature annotations is not defined」発生時は Python インタプリターを要チェック

はじめに

ansible-core 2.17.0 で Linux サーバーをマネージドノード(自動化対象)に実行したとき、以下のエラーに出くわしたことがありました。

SyntaxError: future feature annotations is not defined

調べてみると、マネージドノード側の Python が 3.6 しか入っていないことによるものでした。

このエラーが必ずこの原因かはわからないですが、私が出くわした時のことをまとめます。

  • 検証環境
    • コントロールノード
      • ansible-core 2.17.0
    • マネージドノード
      • RHEL 8.5
      • Python 3.6.8 のみ (パスは /usr/bin/python3)

実行

ansible コマンドで ping モジュールを実行するだけで発生しました。

%  ansible -i inventory.yml all -m ping
[WARNING]: Unhandled error in Python interpreter discovery for host vm-sakana: Expecting value:
line 1 column 1 (char 0)
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: SyntaxError: future feature annotations is not defined
[WARNING]: Platform linux on host vm-sakana is using the discovered Python interpreter at
/usr/bin/python3, but future installation of another Python interpreter could change the meaning
of that path. See https://docs.ansible.com/ansible-
core/2.17/reference_appendices/interpreter_discovery.html for more information.
vm-sakana | FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "module_stderr": "Shared connection to 192.168.1.228 closed.\r\n",
    "module_stdout": "Traceback (most recent call last):\r\n  File \"/home/adminuser/.ansible/tmp/ansible-tmp-1719059368.2095401-62904-248254909367870/AnsiballZ_ping.py\", line 107, in <module>\r\n    _ansiballz_main()\r\n  File \"/home/adminuser/.ansible/tmp/ansible-tmp-1719059368.2095401-62904-248254909367870/AnsiballZ_ping.py\", line 99, in _ansiballz_main\r\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\r\n  File \"/home/adminuser/.ansible/tmp/ansible-tmp-1719059368.2095401-62904-248254909367870/AnsiballZ_ping.py\", line 44, in invoke_module\r\n    from ansible.module_utils import basic\r\n  File \"<frozen importlib._bootstrap>\", line 971, in _find_and_load\r\n  File \"<frozen importlib._bootstrap>\", line 951, in _find_and_load_unlocked\r\n  File \"<frozen importlib._bootstrap>\", line 894, in _find_spec\r\n  File \"<frozen importlib._bootstrap_external>\", line 1157, in find_spec\r\n  File \"<frozen importlib._bootstrap_external>\", line 1131, in _get_spec\r\n  File \"<frozen importlib._bootstrap_external>\", line 1112, in _legacy_get_spec\r\n  File \"<frozen importlib._bootstrap>\", line 441, in spec_from_loader\r\n  File \"<frozen importlib._bootstrap_external>\", line 544, in spec_from_file_location\r\n  File \"/tmp/ansible_ping_payload_4phdfb99/ansible_ping_payload.zip/ansible/module_utils/basic.py\", line 5\r\nSyntaxError: future feature annotations is not defined\r\n",
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
    "rc": 1
}

いちばん重要なメッセージは最後の方の以下の箇所です。

SyntaxError: future feature annotations is not defined

他にちょっと気にするべきポイントは、"discovered_interpreter_python": "/usr/bin/python3" です。明示的に Python インタープリターを指定しなかったため、Interpreter Discovery 機能によって検出された結果が、/usr/bin/python3 だったということを示しています。

今回のマネージドノードでは、/usr/bin/python3Python 3.6.8 でした。そして、ansible-core 2.17.0 からは、マネージドノードは Python 3.7 以上である必要があるため、Python レベルのエラーが発生していたということのようです。

なお、話はそれますが ansible-core 2.17.0 からは INTERPRETER_PYTHON_DISTRO_MAPディストリビューション/バージョンと Python インタープリタの対応マップ)がなくなったため、RHEL 8 系ですが /usr/libexec/platform-python ではなく /usr/bin/python3 が検出されました。

対策

マネージドノード側の Python のバージョンを上げることにします。

今回はひとまず Python 3.9 にバージョンアップしたことで、エラーはなくなりました。

$ sudo dnf install python3.9 -y
...()...
$ /usr/bin/python3 --version
Python 3.6.8
$ /usr/bin/python3.9 --version
Python 3.9.19
[WARNING]: Platform linux on host vm-sakana is using the discovered Python interpreter
at /usr/bin/python3.9, but future installation of another Python interpreter could change
the meaning of that path. See https://docs.ansible.com/ansible-
core/2.17/reference_appendices/interpreter_discovery.html for more information.
vm-sakana | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3.9"
    },
    "changed": false,
    "ping": "pong"
}

ひっそり、検出された Python インタープリタのパスが /usr/bin/python3.9 になっていることにも注目です。

ansible-core 2.17 では、Python インタープリタを検出する順番

  • python3.12
  • python3.11
  • python3.10
  • python3.9
  • python3.8
  • python3.7
  • /usr/bin/python3
  • python3

となっています。

残った WARNING は、Python インタープリターの検出に任せずに ansible_python_interpreter 変数などで明示指定すれば消えます。明示しておくほうがいいかなと思います。

関連事例

Python 3.9 を指定しているはずなので、同様のエラーが発生することもあるようです。少し特殊で、別の古い Python 環境で respawn した結果、ということのようです。

forum.ansible.com

おわりに

今回に限らないのですが、ansible-core 2.17 では、Python インタープリターの指定周りでときどきつまずくことがあります。