I have a playbook with a mix of connection: local
tasks and remote tasks that use an AWS dynamic inventory. The Python interpreter has different paths on local and remote systems.
Through another question python3 venv - how to sync ansible_python_interpreter for playbooks that mix connection:local and target system, I have determined I should use ansible_python_interpreter_fallback
to configure two Python interpreter paths to try. But I cannot get them working.
I have tried:
Defining it in my playbook:
---
- hosts: tag_group_web_servers
vars_files:
- group_vars/au
roles:
- autodeploy
vars:
ansible_python_interpreter_fallback:
- /Users/jd/projects/mgr2/ansible/bin/python3
- /usr/bin/python3
, which is ignored
And defining it in the dynamic inventory:
plugin: aws_ec2
regions:
- ap-southeast-2
- us-east-1
hostnames:
- ip-address
keyed_groups:
- prefix: "tag"
key: tags
- prefix: "group"
key: tags
- prefix: "security_groups"
key: 'security_groups|json_query("[].group_name")'
all:
hosts:
127.0.0.1:
ansible_connection: local
ansible_python_interpreter: "/Users/jd/projects/mgr2/ansible/bin/python3"
remote:
ansible_host: remote.host.ip
ansible_python_interpreter: /usr/bin/python3
ansible_python_interpreter_fallback:
- /Users/jd/projects/mgr2/ansible/bin/python3
- /usr/bin/python3
, which is also ignored.
I'm confused where else this can go or why it doesn't work.
Here is my Ansible version:
ansible [core 2.17.4]
config file = /Users/jd/projects/mgr2/ansible/ansible.cfg
configured module search path = ['/Users/jd/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /opt/homebrew/lib/python3.11/site-packages/ansible
ansible collection location = /Users/jd/.ansible/collections:/usr/share/ansible/collections
executable location = /opt/homebrew/bin/ansible
python version = 3.11.10 (main, Sep 7 2024, 01:03:31) [Clang 15.0.0 (clang-1500.3.9.4)] (/opt/homebrew/opt/python@3.11/bin/python3.11)
jinja version = 3.1.4
libyaml = True
You cannot mix and match a dynamic inventory and a "regular" (YAML) inventory in the same file like that, you will have to create two different inventory files.
The reason being the inventory is inferred by Ansible when it loads the inventory files.
You can actually realise this if you run Ansible in verbose mode (using the option -vvv
)
$ ansible-playbook play.yml -vvv
(... some lines not relevant for the issue at hand)
Using inventory plugin
'ansible_collections.amazon.aws.plugins.inventory.aws_ec2'
to process inventory source
'/usr/local/ansible/inventories/inventory.aws_ec2.yml'
Parsed /usr/local/ansible/inventories/inventory.yml
inventory source with yaml plugin
(...)
The good thing is that you can configure Ansible inventory(ies) either as a list of files or as a folder of inventories in your configuration file.
For example, my ansible.cfg
reads
inventory =
/usr/local/ansible/inventories/
But you could also do something like
inventory =
/usr/local/ansible/inventories/inventory.yml, # YAML inventory
/usr/local/ansible/inventories/inventory.aws_ec2.yml # AWS inventory
But, in your case, I would probably use a default on all hosts and redefine it only for the local machine, all of this happening in the YAML inventory (i.e.: in /usr/local/ansible/inventories/inventory.yml, in the example above):
all:
vars:
ansible_python_interpreter: /usr/bin/python3
hosts:
127.0.0.1:
ansible_connection: local
ansible_python_interpreter: >-
/Users/jd/projects/mgr2/ansible/bin/python3
Another solution would be to use the compose
parameter to set the variable in the dynamic inventory:
plugin: aws_ec2
regions:
- ap-southeast-2
- us-east-1
hostnames:
- ip-address
# You can define variable(s) for the dynamic hosts here,
# and it can even be applied with Jinja templating, making those dynamic
# Mind that the usage of both double and single quote here **is** important
# as it will indicate to the Jinja templating that it is a literal string
compose:
ansible_python_interpreter: "'/usr/bin/python3'"
keyed_groups:
- prefix: "tag"
key: tags
- prefix: "group"
key: tags
- prefix: "security_groups"
key: 'security_groups|json_query("[].group_name")'
Then in the YAML inventory:
all:
hosts:
127.0.0.1:
ansible_connection: local
ansible_python_interpreter: >-
/Users/jd/projects/mgr2/ansible/bin/python3