justin-p/ansible-role-pdc

[BUG] ansible_password does not update mid run to reflect password changes

patsevanton opened this issue · 8 comments

Hello! Thanks for role ansible-role-pdc.
I try run role for windows server 2019

Install on windows as admin https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1

sudo apt update
sudo apt install git jq python3-pip -y
sudo pip3 install ansible pywinrm
ansible-galaxy collection install ansible.windows
ansible-galaxy install justin_p.pdc

Inventory file:

[windows]
windows-server4 ansible_host=xxxx

[windows:vars]
ansible_port=5986
ansible_connection=winrm
ansible_winrm_transport=basic
ansible_user=Administrator
ansible_password=yyyyy
ansible_winrm_server_cert_validation=ignore

Run playbook

ansible-playbook -vvv -i inventory active_directory.yml

Get error

TASK [justin_p.pdc : Ensure the local user Administrator has the password specified for TEST\Administrator] ***********************************************
task path: /home/apatsev/.ansible/roles/justin_p.pdc/tasks/main.yml:36
redirecting (type: modules) ansible.builtin.win_user to ansible.windows.win_user
Using module file /home/apatsev/.ansible/collections/ansible_collections/ansible/windows/plugins/modules/win_user.ps1
Pipelining is enabled.
<178.154.208.75> ESTABLISH WINRM CONNECTION FOR USER: Administrator on PORT 5986 TO 178.154.208.75
EXEC (via pipeline wrapper)
The full traceback is:
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/winrm/transport.py", line 340, in _send_message_request
    response.raise_for_status()
  File "/usr/lib/python3/dist-packages/requests/models.py", line 935, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 401 Client Error:  for url: https://178.154.208.75:5986/wsman

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/ansible/executor/task_executor.py", line 158, in run
    res = self._execute()
  File "/usr/local/lib/python3.6/dist-packages/ansible/executor/task_executor.py", line 582, in _execute
    result = self._handler.run(task_vars=variables)
  File "/usr/local/lib/python3.6/dist-packages/ansible/plugins/action/normal.py", line 47, in run
    result = merge_hash(result, self._execute_module(task_vars=task_vars, wrap_async=wrap_async))
  File "/usr/local/lib/python3.6/dist-packages/ansible/plugins/action/__init__.py", line 1113, in _execute_module
    res = self._low_level_execute_command(cmd, sudoable=sudoable, in_data=in_data)
  File "/usr/local/lib/python3.6/dist-packages/ansible/plugins/action/__init__.py", line 1265, in _low_level_execute_command
    rc, stdout, stderr = self._connection.exec_command(cmd, in_data=in_data, sudoable=sudoable)
  File "/usr/local/lib/python3.6/dist-packages/ansible/plugins/connection/winrm.py", line 563, in exec_command
    result = self._winrm_exec(cmd_parts[0], cmd_parts[1:], from_exec=True, stdin_iterator=stdin_iterator)
  File "/usr/local/lib/python3.6/dist-packages/ansible/plugins/connection/winrm.py", line 522, in _winrm_exec
    self.protocol.cleanup_command(self.shell_id, command_id)
  File "/usr/local/lib/python3.6/dist-packages/winrm/protocol.py", line 390, in cleanup_command
    res = self.send_message(xmltodict.unparse(req))
  File "/usr/local/lib/python3.6/dist-packages/winrm/protocol.py", line 243, in send_message
    resp = self.transport.send_message(message)
  File "/usr/local/lib/python3.6/dist-packages/winrm/transport.py", line 334, in send_message
    response = self._send_message_request(prepared_request, message)
  File "/usr/local/lib/python3.6/dist-packages/winrm/transport.py", line 344, in _send_message_request
    raise InvalidCredentialsError("the specified credentials were rejected by the server")
winrm.exceptions.InvalidCredentialsError: the specified credentials were rejected by the server
fatal: [windows-server4]: FAILED! => 
  msg: Unexpected failure during module execution.
  stdout: ''

Full log
https://gist.github.com/patsevanton/a799fdcdda4bef6bb5f048a6672ee5d8

I fixed.
pdc_administrator_password need equal ansible_password

Inventory

---
all:
  children:
    ad_domain_test:
      vars:
        ansible_user: administrator
        ansible_password: Password01!
        ansible_connection: winrm
        ansible_port: 5986
        ansible_winrm_transport: ntlm
        ansible_winrm_server_cert_validation: ignore
      children:
        servers:
          children:
            domain_controllers:
              children:
                primary_domain_controller:
                  hosts:
                    DC01:
                      ansible_host: 10.11.12.10
                secondary_domain_controller:
                  hosts:
                    DC02:
                      ansible_host: 10.11.12.11
            file_servers:
              hosts:
                FS01:
                  ansible_host: 10.11.12.20
            exchange_servers:
              hosts:
                EXC01:
                  ansible_host: 10.11.12.30
        clients:
          children:
            windows_10:
              hosts:
                w10-01:
                  ansible_host: 10.11.12.100

Playbook

- hosts: primary_domain_controller
  roles:
    - role: justin_p.pdc
      vars:
        pdc_administrator_password: Str0ngPassw0rd01!
        pdc_domain: ad.domain.test
        pdc_domain_path: dc=ad,dc=domain,dc=test
        pdc_domain_functional_level: WinThreshold
        pdc_forest_functional_level: WinThreshold
        pdc_desired_dns_forwarders: ["10.0.0.254"]

Results in the following error

TASK [justin_p.pdc : Ensure required Windows Features are installed] ******************************************************************************************************
failed: [DC01] (item=AD-domain-services) => {"ansible_loop_var": "item", "item": "AD-domain-services", "msg": "ntlm: the specified credentials were rejected by the server", "unreachable": true}
failed: [DC01] (item=DNS) => {"ansible_loop_var": "item", "item": "DNS", "msg": "ntlm: the specified credentials were rejected by the server", "unreachable": true}
fatal: [DC01]: UNREACHABLE! => {"changed": false, "msg": "All items completed", "results": [{"ansible_loop_var": "item", "item": "AD-domain-services", "msg": "ntlm: the specified credentials were rejected by the server", "unreachable": true}, {"ansible_loop_var": "item", "item": "DNS", "msg": "ntlm: the specified credentials were rejected by the server", "unreachable": true}]}

After running Ensure the local user Administrator has the password specified for TEST\Administrator the role should update the ansible_password to match the new password of Administrator.

I am sorry. Thanks for answer. I am not use ansible-role-pdc/ansible now. I will close issue.

Hia @patsevanton, I'd like to keep the issue open so I can track it and eventually fix it :)

Fixed in latest tag.

Hello!
I think need change example playbook
With this playbook i get error "requests.exceptions.HTTPError: 401 Client Error" and "InvalidCredentialsError: the specified credentials were rejected by the server"

- hosts: primary_domain_controller
  roles:
    - role: justin_p.posh5
    - role: justin_p.wincom
    - role: justin_p.pdc

Created PR #11

Hi @patsevanton,

Since there are multiple ways a someone can set this password variable, some more secure then others, it's not include within the example playbook. Boils down to the fact that (proper) credential handling is out of scope of this role. The README Role Variables does however already explain that its advisable to change pdc_administrator_password to ensure the default administrator account does not use a weak password.

Sidenote, if you are running the example playbook you specified above the more likely culprit that caused this error is the ansible_password variable. It was most likely setup incorrectly and did not match the password that was set during a prior bootstrap. The role itself should not throw an invalid credential error (hence why i kept the issue open initially) and pdc_administrator_password is basically only used to set a password during the initial configuration of AD.

  • If there is no AD setup, and pdc_administrator_password is not changed, the default value is used (P@ssw0rd!!) to set the password of the local and domain administrator (depending on the pdc_administrator_username variable value, sane defaults apply).
  • If an AD is setup it will skip 90% of the role due a couple of checks, ex.:
    when: not ansible_windows_domain_member

    update_password: on_create

If you require an more detailed example I have a very early W.I.P. project here (https://github.com/justin-p/ansible-playbook-windows-lab) which combines most of my windows/AD focused roles and configures a AD lab environment.