Ansible
Seems the Ansible users must belong to the local administrators of the machines it tries to manipulate (on Windows 10 at least, the Remote Management group is not even enough to gather facts).
Tasks
Do not stop when a task fails
- name: do something
win_shell: something
failed_when: False
changed_when: False
https://medium.com/@sbarnea/why-ansible-ignore-errors-is-evil-500fb6e81229
Run a role
---
- hosts: all
gather_facts: False
tasks:
- include_role:
name: rolename
Retry an intermittent error
- name: Test failure
command: "bash -c 'exit $(( $RANDOM % 4 ))'"
register: result
retries: 5
delay: 10
until: result is not failed
ignore_errors: True
- debug: var=result
https://curiousdba.netlify.app/post/ansibleretries/
Loops
https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html
Simple loop
- name: Create a temporary directory
ansible.builtin.tempfile:
path: /my/path
state: directory
register: tempdir
- name: Download files
get_url:
url: "ftp://my.anonymous.server/files/{{ item }}"
dest: "{{ tempdir.path }}/{{ item }}"
mode: +x
loop:
- "file01.txt"
- "file02.txt"
- "file03.txt"
The mode: +x
is only needed there’s an executable that is supposed to be run afterwards.
Advanced loop
- name: DaVinci resolve - Set Firewall rule
vars:
applications:
- name: DaVinci Resolve
path: C:\program files\blackmagic design\davinci resolve\resolve.exe
- name: FusionScript services for Fusion
path: C:\program files\blackmagic design\davinci resolve\fuscript.exe
- name: dpdecoder
path: C:\program files\blackmagic design\davinci resolve\dpdecoder.exe
community.windows.win_firewall_rule:
name: '{{ item[0].name }} ({{ item[1] }})'
group: DaVinci Resolve
description: '{{ item[0].name }}'
program: '{{ item[0].path }}'
profiles: domain
localport: any
protocol: '{{ item[1] }}'
loop: "{{ applications |product(['udp', 'tcp'])|list }}"
https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#combining-lists
Conditional execution
With when
- name: Remove previous splashtop versions
ansible.windows.win_package:
product_id: '{C8BC0F03-D53F-4f19-B42F-06CB733C09E4}'
state: absent
become: yes
when: software_version.win_file_version.file_version != "3.46.9.7769"
With block – when
- name: fetch Splashtop Streamer version
ansible.builtin.command: defaults read "/Applications/Splashtop Streamer.app/Contents/Info.plist" CFBundleShortVersionString
register: app_version
- block:
- name: Create a temporary directory
ansible.builtin.tempfile:
path: /my/path
state: directory
register: tempdir
- name: Use the registered var and the file module to remove the temporary folder
ansible.builtin.file:
path: "{{ tempdir.path }}"
state: absent
when: tempdir.path is defined
when: app_version.stdout != "3.4.6.1"
Collections
Install an ansible galaxy collection
ansible-galaxy collection install ansible.windows
ansible.builtin
ansible.builtin.command – Execute commands on targets
- name: fetch Splashtop Streamer version
ansible.builtin.command: defaults read "/Applications/Splashtop Streamer.app/Contents/Info.plist" CFBundleShortVersionString
register: app_version
ansible.builtin.debug – Print statements during execution
Debug message
# Example that prints return information from the previous task
- shell: /usr/bin/uptime
register: result
- debug:
var: result
verbosity: 2
Conditional debug message
- name: fetch Cinema4D R21 version
community.windows.win_file_version:
path: 'C:\Program Files\Maxon Cinema 4D R21\CINEMA 4D.exe'
register: C4DR21_version
failed_when: False
- debug:
msg: "C4DR21 version: {% if C4DR21_version.win_file_version.file_version is defined %}{{ C4DR21_version.win_file_version.file_version }}{% else %}Not installed{% endif %}"
ansible.builtin.setup – Gathers facts about remote hosts
- name: Collect facts
ansible.builtin.setup:
gather_subset:
- min
gather_subset: Possible values: all
, min
, hardware
, network
, virtual
, ohai
, and facter
.
ansible.builtin.slurp – Slurps a file from remote nodes
- name: get content of remote file
slurp:
src: "{{remote_path}}"
register: remote_content_encoded
- name: decode remote content
set_fact:
remote_content: "{{remote_content_encoded.content | b64decode}}"
- debug:
msg: "content of remote file {{remote_path}}: {{remote_content}}"
https://fabianlee.org/2021/05/25/ansible-creating-a-variable-from-a-remote-or-local-file-content/
ansible.windows
ansible.windows.win_shell – Execute shell commands on target hosts
- name: Uninstall AWS Thinkbox Deadline Client
ansible.windows.win_shell: '& "$Env:ProgramFiles\Thinkbox\Deadline10\uninstall.exe" --mode unattended'
become: yes
So the path to the exe must be in double quotes, the entire command in single quotes and $Env:ProgramFiles is used (instead of %programfiles% which only works with cmd.exe).
ansible.windows.win_package – Installs/uninstalls an installable package
- name: Install Maxon Cinema4D_S26_26.014
ansible.windows.win_package:
path: '{{ deployment_folder }}\Maxon\C4Dr26\Cinema4D_S26_26.014_Win.exe'
arguments: --mode unattended --unattendedmodeui none
creates_path: 'C:\Program Files\Maxon Cinema 4D R26\Cinema 4D.exe'
creates_version: 26.0.1.4
product_id: "Maxon Cinema 4D R26"
state: present
become: yes
Uninstall registry path
HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall
HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall
HKCU:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
community.windows
community.windows.win_robocopy – Synchronizes the contents of two directories using Robocopy
If flags is set, purge
and recurse
will be ignored.
- name: Ensure the Redshift Core folder is copied to C:\ProgramData
become: yes
community.windows.win_robocopy:
src: '{{ library_folder }}\PLUGINS\C4D_v002\redshift\redshift_v2.6.52_flt\Redshift\'
dest: C:\ProgramData\Redshift\
recurse: yes
purge: yes
#flags: /v
register: result
- debug:
var: result.output
https://docs.ansible.com/ansible/latest/collections/community/windows/win_robocopy_module.html
community.windows.psexec – Runs commands on a remote Windows host based on the PsExec model
- name: Test the PsExec connection to the local system (target node) with your user
win_psexec:
command: 'Powershell Add-WindowsCapability -Online -Name "SNMP.Client~~~~0.0.1.0"'
community.windows.win_file_version – Get DLL or EXE file build version
- name: fetch software version
community.windows.win_file_version:
path: 'C:\Program Files\Maxon Cinema 4D R24\Cinema 4D.exe'
register: software_version
Utilities
ansible-playbook – run an ansible playbook
--ask-vault-password, --ask-vault-pass | ask for vault password |
--vault-password-file, --vault-pass-file | vault password file |
-e, --extra-vars | set additional variables as key=value or YAML/JSON, if filename prepend with @ |
-i, --inventory, --inventory-file | specify inventory host path or comma separated host list. –inventory-file is deprecated |
-l <SUBSET>, --limit <SUBSET> | further limit selected hosts to an additional pattern |
-v, --verbose | verbose mode (-vvv for more, -vvvv to enable connection debugging) |
https://docs.ansible.com/ansible/latest/cli/ansible-playbook.html
Add variables in command line
ansible-playbook -i production.yml --vault-password-file ~/vault_password add_new_project.yml --extra-vars "new_project=XXXX_Testpermissions"
ansible-playbook -i production.yml --vault-password-file ~/vault_password add_new_project.yml --extra-vars "client=myclient new_project=myproject"
ansible-playbook -i production.yml play_test.yml --limit rendernodes
ansible-playbook --ask-vault-pass -i production.yml play_test.yml --limit test
https://linux.die.net/man/1/ansible-playbook
Installation
Kerberos python plugin needed on Turnkey Ansible:
apt install python3-kerberos krb5-user
edit /etc/krb5.conf (change only realms and domain_realm):
[logging]
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log
[libdefaults]
default_realm = EXAMPLE.COM
[realms]
EXAMPLE.COM = {
kdc = domain-controller1.example.com
kdc = domain-controller2.example.com
default_domain = example.com
}
[domain_realm]
.example.com = EXAMPLE.COM
example.com = EXAMPLE.COM
[login]
test (case is important !):
klist
kinit myuser@EXAMPLE.COM
GPO to allow WinRM for Ansible
TODO
Archived
Run an arbitrary powershell one liner (the double quotes must be escaped inside)
this seems wrong, there’s a powershell module: “ansible.windows.win_shell”
---
- name: Uninstall Office ProPlus
hosts: all
gather_facts: no
tasks:
- name: removes old shortcuts
win_command: powershell -command "Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList' | ForEach-Object { $profilePath = $_.GetValue('ProfileImagePath') ; Remove-Item -Path \"$profilePath\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\*2010*\" }"
Check C4D version
the right way to go is to use ‘community.windows.win_file_version’
---
- name: fetch Cinema4D r19 version
hosts: all
gather_facts: no
tasks:
- win_shell: '& "C:\Program Files\MAXON\Cinema 4D R19\Commandline.exe" | Select-String -Pattern "Version / Build"'
register: C4Dr19_version
- debug:
var: C4Dr19_version.stdout_lines[1]