Ansible Windows Become Confusion - windows

Good day,
I'm attempting to execute a PowerShell script on a Windows host to create a Windows Server Failover Cluster. Running the script on node1 works without issue when logged in as a service account with appropriate AD permissions and using a PowerShell terminal ran as Administrator.
Executing the same script via Ansible (using the service account mentioned above) results in an error stating I do not have permissions to edit the the node1's registry. Adding the "become" statements below get past this error, but then I receive an error that node2 cannot be added to the cluster as I don't have permissions to its registry.
- name: Execute configure_wsfc.ps1
win_shell: .\configure_wsfc.ps1
args:
chdir: '{{ temp_dir }}'
become: true
become_method: runas
become_user: '{{ service_account }}'
configure_wsfc.ps1:
New-Cluster -Name $WSFCClusterName -Node ("node1", "node2") -AdministrativeAccessPoint ActiveDirectoryAndDNS -StaticAddress ("192.168.0.1", "192.168.0.2" -NoStorage
What am I missing?
Thank you.

Per the below note in the Ansible documentation I needed to add become_password.
Because there are no guarantees an existing token will exist for a
user when Ansible runs, there’s a high change the become process will
only have access to local resources. Use become with a password if the
task needs to access network resources
- name: Execute configure_wsfc.ps1
ansible.windows.win_shell: .\configure_wsfc.ps1
args:
chdir: '{{ temp_dir }}'
when: service_info.start_mode == 'disabled'
vars:
ansible_become: true
ansible_become_method: runas
ansible_become_user: '{{ service_account }}'
ansible_become_password: '{{ service_account_password }}'

Related

Possibility to Run vmware_vm_shell using Powershell as Administrator

I feel frustated to find out if ansible module vmware_vm_shell is possible to run powershell as administrator? because few command that need to run with powershell has to be elevated to administrator role.
Why i didn't use win_shell, or win_psexec? Because i want to try run the command in Windows VM Guest, without WinRM, so i don't need to access the VM using IPaddr, otherwise we can utilize vmtools as a connection in this case.
- name: Initiate New Disk
vmware_vm_shell:
hostname: "{{ lookup ('env', 'VMWARE_HOST' )}}"
username: "{{ lookup ('env', 'VMWARE_USER' )}}"
password: "{{ lookup ('env', 'VMWARE_PASSWORD' )}}"
vm_id: "{{ vmname }}"
vm_username: "administrator"
vm_password: "password123"
vm_shell: 'C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe'
vm_shell_args: '-ExecutionPolicy Bypass -command "Initialize-Disk -Number {{newdisk_osnum}}"'
vm_shell_cwd: 'C:\Users\administrator\Desktop'
wait_for_process: yes
validate_certs: no
delegate_to: localhost
register: initdisk_shell
Finally, after few days full of pain, I found the way out, in ansible tower has feature to Privilege Escalation option in the job template configuration. after I enabled this option, finally vmware_vm_shell is able to run powershell command as administrator. So, I don't need to run command using winRM which have to disable few option that cause few vulnerability

"sudo: no password was provided" when running an Ansible module with `local_action`

I'm trying to use this github_key community module to add an SSH publickey to a Github account.
(I installed the community module with ansible-galaxy collection install community.general)
In my task list, I -
Read the publickey
Call github_key (with local_action) to add that key to the Github account
- name: Read SSH key for jeeves#github.com
shell: 'cat /home/jeeves/.ssh/jeeves#github.com.pub'
register: ssh_pub_key
- name: Upload SSH key for jeeves#github.com
local_action:
module: github_key
name: 'Key for jeeves#my-server.dev'
token: '{{ github_token }}'
pubkey: '{{ ssh_pub_key.stdout }}'
force: yes
When I run it get this error (in module_stderr output):
[sudo via ansible, key=<REDACTED>] password:
sudo: no password was provided
sudo: 1 incorrect password attempt
I guess it can't find my sudo password for the user.
But I am providing a sudo password, and there are 30+ other tasks before this (not shown here) where it was able to successfully execute commands. In fact in my playbook definition I use become:
- hosts: all
become: yes
become_method: sudo
become_user: root
gather_facts: yes
#...
I think the issue is caused by local_action since it's having trouble even executing the module itself.
Thanks!

Ansible: Failed to restart apache2.service: Connection timed out

I am using Ansible AWX to issue a restart command to restart an apache2 service on a host. The restart command is contained in a playbook.
---
- name: Manage Linux Services
hosts: all
tasks:
- name: Restart a linux service
command: systemctl restart '{{ service_name }}'
register: result
ignore_errors: yes
- name: Show result of task
debug:
var: result
OR
---
- name: Manage Linux Services
hosts: all
tasks:
- name: Restart a linux service
ansible.builtin.service:
name: '{{ service_name }}'
state: restarted
register: result
ignore_errors: yes
- name: Show result of task
debug:
var: result
However, when I run the command, I get the error below:
"Failed to restart apache2.service: Connection timed out",
"See system logs and 'systemctl status apache2.service' for details."
I have tried to figure out the issue, but no luck yet.
I later figured the cause of the issue.
Here's how I fixed it:
The restart command requires sudo access to run which was missing in my command.
All I have to do was to add the become: true command so that I can execute the command with root privileges.
So my playbook looked like this thereafter:
---
- name: Manage Linux Services
hosts: all
tasks:
- name: Restart a linux service
command: systemctl restart '{{ service_name }}'
become: true
register: result
ignore_errors: yes
- name: Show result of task
debug:
var: result
OR
---
- name: Manage Linux Services
hosts: all
tasks:
- name: Restart a linux service
ansible.builtin.service:
name: '{{ service_name }}'
state: restarted
become: true
register: result
ignore_errors: yes
- name: Show result of task
debug:
var: result
Another way if you want to achieve this on Ansible AWX is to tick the Privilege Escalation option in the job template.
If enabled, this runs the selected playbook in the job template as an administrator.
That's all.
I hope this helps
Restarting a service requires sudo privileges. Besides adding the 'become' directive, if you would like to prompt for the password, you can do so by passing the -K flag (note: uppercase K)
$ ansible-playbook myplay.yml -i hosts -u myname --ask-pass -K

How to make Ansible display the host name before asking for the sudo password?

I have an Ansible playbook to update my Debian based servers. For simplicity and security reasons, I don't want to use a vault for the passwords and I also don't want to store them in a publically accessible config file. So I ask for the password for every client with
become: yes
become_method: sudo
Now, when the playbook runs, it seems the first thing Ansible does is ask for the sudo password, but I don't know for which server (the passwords are different). Is there a way to get Ansible to print the current host name before it asks for the password?
The update playbook is similar to this:
---
- hosts:
all
gather_facts: no
vars:
verbose: false
log_dir: "log/dist-upgrade/{{ inventory_hostname }}"
pre_tasks:
- block:
- setup:
rescue:
- name: "Install required python-minimal package"
raw: "apt-get update && apt-get install -y --force-yes python-apt python-minimal"
- setup:
tasks:
- name: Update packages
apt:
update_cache: yes
upgrade: dist
autoremove: yes
register: output
- name: Check changes
set_fact:
updated: true
when: not output.stdout | search("0 upgraded, 0 newly installed")
- name: Display changes
debug:
msg: "{{ output.stdout_lines }}"
when: verbose or updated is defined
- block:
- name: "Create log directory"
file:
path: "{{ log_dir }}"
state: directory
changed_when: false
- name: "Write changes to logfile"
copy:
content: "{{ output.stdout }}"
dest: "{{ log_dir }}/dist-upgrade_{{ ansible_date_time.iso8601 }}.log"
changed_when: false
when: updated is defined
connection: local
(source: http://www.panticz.de/Debian-Ubuntu-mass-dist-upgrade-with-Ansible)
Your above become configuration does not make ansible ask you for a become password: it just advises it to use become with the sudo method (which will work without any password if your have the correct keys configured for example).
If you are asked for a become password, it's because (it's a guess but I'm rather confident...) you used the --ask-become-pass option when running ansible-playbook.
In this case, you are prompted only once at the beginning of the playbook operations and this default become password will be used on all servers you connect to except if you defined an other one in your inventory for a specific host/group.
If you have different become passwords depending on your machines, you don't really have an other option: you need to declare those passwords in your inventory (and it is strongly advised to use ansible-vault encryption) or use some other mechanisms to get them out of an external application (hashicorp vault, dynamic inventory, cyberark...)

Ansible login user logged in [duplicate]

A recurring theme that's in my ansible playbooks is that I often must execute a command with sudo privileges (sudo: yes) because I'd like to do it for a certain user. Ideally I'd much rather use sudo to switch to that user and execute the commands normally. Because then I won't have to do my usual post commands clean up such as chowning directories. Here's a snippet from one of my playbooks:
- name: checkout repo
git: repo=https://github.com/some/repo.git version=master dest={{ dst }}
sudo: yes
- name: change perms
file: dest={{ dst }} state=directory mode=0755 owner=some_user
sudo: yes
Ideally I could run commands or sets of commands as a different user even if it requires sudo to su to that user.
With Ansible 1.9 or later
Ansible uses the become, become_user, and become_method directives to achieve privilege escalation. You can apply them to an entire play or playbook, set them in an included playbook, or set them for a particular task.
- name: checkout repo
git: repo=https://github.com/some/repo.git version=master dest={{ dst }}
become: yes
become_user: some_user
You can use become_with to specify how the privilege escalation is achieved, the default being sudo.
The directive is in effect for the scope of the block in which it is used (examples).
See Hosts and Users for some additional examples and Become (Privilege Escalation) for more detailed documentation.
In addition to the task-scoped become and become_user directives, Ansible 1.9 added some new variables and command line options to set these values for the duration of a play in the absence of explicit directives:
Command line options for the equivalent become/become_user directives.
Connection specific variables which can be set per host or group.
As of Ansible 2.0.2.0, the older sudo/sudo_user syntax described below still works, but the deprecation notice states, "This feature will be removed in a future release."
Previous syntax, deprecated as of Ansible 1.9 and scheduled for removal:
- name: checkout repo
git: repo=https://github.com/some/repo.git version=master dest={{ dst }}
sudo: yes
sudo_user: some_user
In Ansible 2.x, you can use the block for group of tasks:
- block:
- name: checkout repo
git:
repo: https://github.com/some/repo.git
version: master
dest: "{{ dst }}"
- name: change perms
file:
dest: "{{ dst }}"
state: directory
mode: 0755
owner: some_user
become: yes
become_user: some user
In Ansible >1.4 you can actually specify a remote user at the task level which should allow you to login as that user and execute that command without resorting to sudo. If you can't login as that user then the sudo_user solution will work too.
---
- hosts: webservers
remote_user: root
tasks:
- name: test connection
ping:
remote_user: yourname
See http://docs.ansible.com/playbooks_intro.html#hosts-and-users
A solution is to use the include statement with remote_user var (describe there : http://docs.ansible.com/playbooks_roles.html) but it has to be done at playbook instead of task level.
You can specify become_method to override the default method set in ansible.cfg (if any), and which can be set to one of sudo, su, pbrun, pfexec, doas, dzdo, ksu.
- name: I am confused
command: 'whoami'
become: true
become_method: su
become_user: some_user
register: myidentity
- name: my secret identity
debug:
msg: '{{ myidentity.stdout }}'
Should display
TASK [my-task : my secret identity] ************************************************************
ok: [my_ansible_server] => {
"msg": "some_user"
}

Resources