Reputation: 3
I am making a playbook to install some software on both Linux and Windows machines (please note I am just testing with one host group containing one Windows Server, all functionality related to doing commands on different OSs is fine). The playbook is mostly split into two parts, a block that runs for the Windows machines and a block that runs for the Linux machines.
However before this the playbook should locally (on the Controller) run two shell
commands to download the relevant files from Azure. This should be done without attempting to open a SSH session to the Controller Host, and instead just using a local shell
(ASFAIK this is done via the connection: local
var rather than using delegate_to: localhost
)
When doing so using this block (indents are behaving strange when copying over to here), it still attempts to run the module on the targets causing an error:
---
- name: Install agent on selected servers
hosts: windowsbox
gather_facts: yes
vars_files:
- "group_vars/passwords.yml"
- "group_vars/windowsbox.yml"
tasks:
- name: debug print
debug:
msg: "{{ ansible_facts }}"
- name: Download agent locally
shell: |
redactedcommand
redactedcommand
connection: local
run_once: true
The error returned is:
TASK [Download agent locally] ******************************************************************************************************************************************************************
[WARNING]: No python interpreters found for host UKS-99850-WIN (tried ['/usr/bin/python', 'python3.7', 'python3.6', 'python3.5', 'python2.7', 'python2.6', '/usr/libexec/platform-python',
'/usr/bin/python3', 'python'])
fatal: [windowsbox]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "module_stderr": "Exception calling \"Create\" with \"1\" argument(s): \"At line:4 char:21\r\n+ def _ansiballz_main():\r\n+ ~\r\nAn expression was expected after '('.\r\nAt line:13 char:27\r\n+ except (AttributeError, OSError):\r\n+ ~\r\nMissing argument in parameter list.\r\nAt line:15 char:29\r\n+ excludes = set(('', '.', scriptdir))\r\n+ ~\r\nMissing expression after ','.\r\nAt line:15 char:30\r\n+ excludes = set(('', '.', scriptdir))\r\n+ ~~~~~~~~~\r\nUnexpected token 'scriptdir' in expression or statement.\r\nAt line:15 char:29\r\n+ excludes = set(('', '.', scriptdir))\r\n+ ~\r\nMissing closing ')' in expression.\r\nAt line:15 char:39\r\n+ excludes = set(('', '.', scriptdir))\r\n+ ~\r\nUnexpected token ')' in expression or statement.\r\nAt line:15 char:40\r\n+ excludes = set(('', '.', scriptdir))\r\n+ ~\r\nUnexpected token ')' in expression or statement.\r\nAt line:22 char:7\r\n+ if sys.version_info < (3,):\r\n+ ~\r\nMissing '(' after 'if' in if statement.\r\nAt line:22 char:30\r\n+ if sys.version_info < (3,):\r\n+ ~\r\nMissing expression after ','.\r\nAt line:22 char:25\r\n+ if sys.version_info < (3,):\r\n+ ~\r\nThe '<' operator is reserved for future use.\r\nNot all parse errors were reported. Correct the reported errors and try again.\"\r\nAt line:10 char:1\r\n+ $exec_wrapper = [ScriptBlock]::Create($split_parts[0])\r\n+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n + CategoryInfo : NotSpecified: (:) [], MethodInvocationException\r\n + FullyQualifiedErrorId : ParseException\r\n \r\nThe expression after '&' in a pipeline element produced an object that was not valid. It must result in a command \r\nname, a script block, or a CommandInfo object.\r\nAt line:11 char:2\r\n+ &$exec_wrapper\r\n+ ~~~~~~~~~~~~~\r\n + CategoryInfo : InvalidOperation: (:) [], RuntimeException\r\n + FullyQualifiedErrorId : BadExpression\r\n ", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}
As you can see it fails as it tries to run the shell
module on the Windows Host instead of just on the Controller.
I've tried using connection: local
, and delegate_to: localhost
in the vars for the task to no avail. I can make the Linux Targets run the shell
command remotely to download the file, but it would still not fix it breaking when running against Windows Targets.
I have some alternatives I could do like storing the file in the git repo that everything else is in but it would be preferable both for security and more so I'd prefer to keep it in the remote Azure container, and use only one playbook to install for both groups of devices.
Upvotes: 0
Views: 364
Reputation: 12145
As you can see it fails as it tries to run the
shell
module on the Windows Host instead of just on the Controller
Right, that's the behavior which is defined within the playbook and since you have used hosts: windowsbox
. Furthermore you would need to delegate_to: controlnode
instead of localhost
. The group of windowsbox
es doesn't know that there is a Remote Control Node outside and running Linux.
You may have a look into the following minimal example.
---
- name: Download relevant files from Azure
hosts: controlnode.example.com
gather_facts: false
tasks:
- name: Download agent locally
shell: |
redactedcommand
redactedcommand
- name: Install agent on selected servers
hosts: windowsbox
gather_facts: yes
vars_files:
- "group_vars/passwords.yml"
- "group_vars/windowsbox.yml"
tasks:
- name: Show Windows facts
debug:
msg: "{{ ansible_facts }}"
Further Documentation
Upvotes: 0