How to create ansible galaxy roles in windows? - windows

I am learning ansible from ansible-beginner to pro by micheal heap. It seems that ansible is not supported on windows. The book suggests running ansible from a virtual machine instead. I started a VMbox using vagrant, which has ubuntu/trusty64 on it. I am successfully able to run my playbooks on it. However, I ran into an issue when creating ansible-galaxy roles.
I could not find a way to create/ initialize a role on windows. I vaguely borrowed ideas from this question How to automatically install Ansible Galaxy roles? and added the following command to my playbook create roles on windows
local_action: command ansible-galaxy init sush.util --init-path roles
---
- hosts: all
gather_facts: false
become: true
tasks:
- name: make sure we can connect
ping:
#ansible-galaxy
- name: Init sush.util
local_action: command ansible-galaxy init sush.util --init-path roles
ignore_errors: true
I also added ignore_errors=true to ignore the errors if the role has already been created.
Is this the correct approach or is there another/better to do this in windows ?

If your aim is to create a role locally on Windows, you don't actually need to use Ansible Galaxy to do that. An Ansible role is just a set of folders. To create a sush.util role, create a folder named sush.util and then create the following folders inside that:
tasks
handlers
templates
files
vars
meta
Finally, inside each of these folders create a file named main.yml that contains --- at the top.
You now have an Ansible role that you can run. Any tasks you add to tasks/main.yml will be executed.

This is what I usually do : Just create those folders and main.yml file
*$path = "c:\git\install-sqlserver"
$main = "main.yml"
$dir = "defaults","files","handlers","meta","tasks","templates","tests","vars"
foreach ($d in $Dir){
New-Item -Path $path -Name $d -ItemType "directory"
New-Item -Path "$path\$d" -Name $main -ItemType "file" -Value "---"
if ((Test-path $path )){
New-Item -Path $path -Name $main -ItemType "file" -Value "---" -ErrorAction SilentlyContinue }
}*

Related

How do I inject more than one environment variable into a Playbook task?

I have an Ansible playbook that I did not write myself. In it, I've identified the relevant task to my issue. This task runs as a another user, and within the docker container it appears this user doesn't have the correct environment variables for the task to run successfully.
- name: Run enmasse -> /opt (02)
become: true
become_user: "zato"
environment:
SOME_TEST_VAR: some-value
shell: |
/usr/bin/find /opt/hot-deploy/enmasse -type f \( -name "*.yml" ! -name "default.yml" \) -exec ~/current/bin/zato enmasse {{ zato_env_path }}/server1 --import --input '{}' --replace-odb-objects --verbose \;
I've experimented by adding the environment directive to the task and setting arbitrary environment variables. These values seem to pass through and be available to the task correctly. However, for the actual work, I have a long list of environment variables I wish to pass through to the task, a list that will probably constantly grow.
If all of my environment variables are given some prefix, is there a simple one-liner that might suffice to pull all of those in? I've found some tutorials and documents that show how environment variables can be read from within Ansible, like so:
"{{ lookup('env','HOME') }}"
But if there is a more sophisticated way other than listing each var in that list, I can't figure out how to search for it.
Question:
I have a long list of environment variables I wish to pass through to the task, a list that will probably constantly grow.
According the documentation setting the remote environment in a task
You can store environment settings for re-use in multiple playbooks by defining them in a group_vars file.
as well
re-use environment settings by defining them as variables in your play and accessing them in a task as you would access any stored Ansible variable.
environment: "{{ env_variables }}"

Pre VM Deployment checks in ansible

I have been trying for the past days to make a playbook to check for some things before ansible starts creating a new windows VM, I'm a junior engineer and just starting on the path of Ansible
I figured out the ping part but what I really want to know is if there's some way to check if the computer name is already registered in Active Directory and if it is the workflow should stop.
I am not sure if win_domain_computer can also just check.
Thanks
I think a powershell request is a way to do that.
In my playbook, we don't check name in Active Directory, but we check dns record
with a task, something similar with get-adcomputer should be ok.
Task dns example :
- block:
- name: Check dns record
win_shell: Get-DnsServerResourceRecord -ComputerName DNSSERVER -Name "{{ SERVERNAME }}" -ZoneName DNSZONE -RRType "A" -ErrorAction Ignore | select -ExpandProperty RecordData | select -ExpandProperty IPv4Address | select -Property IPAddressToString -ExpandProperty IPAddressToString
register: reg_dnscheck
changed_when: reg_dnscheck.rc == 1
failed_when: reg_dnscheck.rc > 1

How can I run a playbook for each user on the machine

On our Linux workstations we have an AD user setup, so that when a user access a machine it will generate a /home/{username} folder, with all of the items defined in our skel. So each machine in our pool have different and multiple user folders.
I need to modify some files that are located in each of these user folders. How can I make ansible loop through each folder in the /home/* folder, so that the playbook is being applied to all of the users?
It should be noted that the playbook is being run as root, so I don't need to run the playbook itself as the user.
IMHO, this is the wrong way to approach this - hopefully your company has a record of who should have access to each system, and a provision to get those accounts setup automatically on each system. Given that, this is a good example of "we need to fix this today while we get the better solution setup."
The example that #mdaniel provided should work. You can implement this in a playbook like this:
---
- hosts: all
gather_facts: false
tasks:
- name: "Get home directories"
shell: /bin/ls -d /home/*
register: home_dirs
- name: "Touch files"
debug:
msg: "Working on {{ item }}"
loop: "{{ home_dirs.stdout_lines }}"
Of course replace the "debug:" module with your tasks to automate.

multiple commands in an ansible playbook for an if statement?

I want to disable Windows defender on a windows client unless the status is already disabled.
At the moment I've divided it in 2 tasks using the register command in ansible
---
-hosts: all
become_method: runas
tasks:
- name: Check if WinDefend is running
win_shell: (Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender").DisableAntiSpyware
register: WinDefendStatus
become: yes
become_user: Administrator
- name: Turn off WinDefend
win_shell: New-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender" -Name DisableAntiSpyware -Value 1 -PropertyType DWORD -Force
become: yes
become_user: Administrator
when: WinDefendStatus.stdout == "0" or ""
Technically this works but I'd like to have this in 1 task. The guides only show local variables or local stored facts but none about remotely gotten values.
Any idea how to do this?

Run a script – with spaces in its path, a parameter, and a variable for the parameter value – with the script module?

My task in my playbook:
- name: Run a script
script: '"./files/name of a script.ps1" -Param1 {{ variable_name }}'
The above is only the latest attempting at quoting/escaping I've tried. Regardless, I get an error like this when I run the playbook containing the above task:
TASK [Run a script] *****************************
task path: /etc/ansible/playbook.yml:38
<192.168.200.245> ESTABLISH WINRM CONNECTION FOR USER: SOME-HOST\Administrator on PORT 5986 TO 192.168.200.245
<192.168.200.245> EXEC Set-StrictMode -Version Latest
(New-Item -Type Directory -Path $env:temp -Name "ansible-tmp-1466538051.8-95578181041077").FullName | Write-Host -Separator '';
<192.168.200.245> PUT "/etc/ansible/"./files/name\" TO "C:\Users\Administrator\AppData\Local\Temp\ansible-tmp-1466537998.0-243829631467080\name"
fatal: [some-host]: FAILED! => {"failed": true, "msg": "file or module does not exist: \"/etc/ansible/\"./files/name\\\""}
This also doesn't work, and fails with the same error as above:
script: ./files/name\ of\ a\ script.ps1 -Param1 {{ variable_name }}
I'm running Ansible version 2.1.0.0 (according to ansible --version on my control machine).
Any ideas?
This is either a 'bug':
Please file a bug on this under the ansible/ansible project – it looks like it's not a Windows-specific issue, given where it's failing. No guarantees we'll be able to thread the needle correctly for separating the script name from the args in the free_form script arg, but others have asked for a more explicit separation between script name and args in our script action, and this would be an excellent case for it.
or a 'missing feature'.

Resources