0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Ansible】pipx inject したのに boto3 を見つけてくれない話【ansible-core の罠】

0
Posted at

はじめに

GitHub Actions の runner 上で Ansible を動かし、SSM 経由で EC2 を構成する——という CD を組んでいました。SSM 接続には boto3 が要るので、ちゃんと入れたつもりだったのに、最初のタスクで boto3 が無いと怒られて落ちました。

pipx inject で入れたはずなのに見つからない。原因は、runner にプリインストールされた pipx 環境と、自分で追加した venv が並存して、入れ先と実行先がズレていたことでした。

先に結論:私が動かした runner では、Ansible が ansible-core という pipx venv に入っていました。自分で pipx install ansible すると別の venv ができ、boto3 をそっちに入れても、実際に動く ansible-core 側には入っていない——これが原因でした。

環境

  • GitHub Actions(ubuntu-latest / GitHub-hosted runner)
  • Ansible(runner にプリインストール)+ amazon.aws.aws_ssm 接続プラグイン
  • pipx
  • AWS SSM 経由で EC2 を構成

(runner の中身は更新されるので、以下は私が実行した時点の runnerでの話として読んでください。)

症状

最初のタスクで、こう落ちました。

TASK [deploy_app : Install Amazon Corretto] ...
Failed to import the required Python library (boto3) on runnervm...'s Python
/opt/pipx/venvs/ansible-core/bin/python. ... If the required library is installed,
but Ansible is using the wrong Python interpreter, ...

注目したのは、boto3 を探しているのが /opt/pipx/venvs/ansible-core/bin/python だという点です。エラー文自身が「ライブラリは入っているのに、Ansible が違う Python インタプリタを使っているのでは?」とヒントをくれていました。

仕込んでいた手順(効かなかった)

導入ステップにはこう書いていました。

pipx install --include-deps ansible
pipx inject ansible boto3 botocore

「Ansible を入れて、その venv に boto3 を inject」——自分では筋が通っているつもりでした。

原因:boto3 を入れた venv と、実際に動く venv が違った

決め手は、pipx install の出力にありました。

⚠️ File exists at /opt/pipx_bin/ansible-playbook and points to
   /opt/pipx/venvs/ansible-core/bin/ansible-playbook, not
   /opt/pipx/venvs/ansible/bin/ansible-playbook. Not modifying.
...
injected package boto3 into venv ansible

整理するとこうでした。

  • 私の runner では、Ansible が ansible-core という venv に入っていて、ansible-playbook コマンドの実体(symlink)は ansible-coreを指していた。
  • 自分の pipx install ansible は、ansible という別名の venv を新たに作った。でも ansible-playbook の symlink は既に存在するので、pipx は Not modifying(書き換えない)と言って、ansible-core を指したまま。
  • pipx inject ansible boto3 は、ansible(動いていないほう)の venv に boto3 を入れた。

つまり、実際に動く ansible-core には boto3 が無く、boto3 は使われない ansible 側に入っていた。これは GitHub runner 固有というより、pipx の複数 venv と PATH / symlink の組み合わせで起きるズレです。amazon.aws.aws_ssm 接続を controller 側で動かすには、使っている Ansible の Python 環境に AWS SDK for Python(boto3 など)が必要なので、最初のタスクで import に失敗して落ちた、というわけです。「インストールしたのに ImportError」は、たいていこのインタプリタ違いでした。

解決:実際に動く venv に入れる

直し方はシンプルで、boto3 を ansible-core venv のほうに injectします。別名の venv を作る pipx install ansible は、二重 venv の原因になるだけなので外しました。

# runner は ansible を ansible-core venv でプリインストール済み。
# 実際に動くその venv へ boto3 を入れる。
pipx inject ansible-core boto3 botocore

あわせて、amazon.aws.aws_ssmansible-core 単体には含まれないため、amazon.aws collection の導入も別途必要です。

ansible-galaxy collection install amazon.aws

これで ansible-playbook が指す ansible-core の Python に boto3 が入り、SSM 接続のタスクが通るようになりました。

「どの venv に入れるか/本当に入ったか」を確かめたいときは、コマンドの指し先を見るのが確実です。

which ansible-playbook
readlink -f "$(which ansible-playbook)"   # 実体がどの venv を指すか
ansible-playbook --version

# その venv の python に boto3 が入ったか(パスは環境依存なので一般化)
"$(dirname "$(readlink -f "$(which ansible-playbook)")")/python" \
  -c "import boto3; print(boto3.__version__)"

教訓

  • 依存は「実際に Ansible が動く Python」に入れる。インストール先と実行先がズレると、入れても使われない。
  • 私の runner では Ansible は ansible-core venv。自分で pipx install ansible すると別 venv ができ、ansible-playbookansible-core を指したまま(Not modifying 警告がサイン)。runner の構成は変わりうるので、指し先は毎回確認する。
  • amazon.aws.aws_ssmansible-core 単体に含まれない。collection 導入+controller 側の Python に boto3 が要る。
  • 「入れたのに ImportError」は、まずインタプリタ/venv 違いを疑う。pipx listreadlink -f $(which ansible-playbook) で確認。

おわりに

最初はネットワークやコレクションの入れ忘れを疑ったのですが、犯人は「boto3 を入れた場所が違った」という、なんともシンプルなものでした😅 Not modifying の警告をちゃんと読んでいれば一発だったな、と反省。同じく「入れたのに見つからない」で固まった人の手がかりになれば嬉しいです🙌

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?