Windows Server 2012 R2 and AWS S3 Download from Ansible - windows

I'm trying to download some files from AWS S3 with IAM Role for EC2 but Ansible is getting an error. Other Ansible win_* modules works great.
Windows Server has Python2 and Python3, and also boto and boto3 modules. Cmd is responding to python command. It opens Python3 when it is executed. I also tested the 'import boto' command when the Python3 is opened to be sure that module is installed.
Ansible Playbook is configured like:
- name: test s3 module
hosts: windows
tasks:
- name: get s3 file
aws_s3:
bucket: drktests3
object: /test
dest: C:\tests3.txt
mode: get
When i run this configuration, the output is like that:
root#ip-172-31-22-4:/etc/ansible/playbooks# ansible-playbook s3test
PLAY [test s3 module] *******************************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************************************
ok: [38.210.201.10]
TASK [get s3 file] **********************************************************************************************************************************************
[WARNING]: FATAL ERROR DURING FILE TRANSFER:
fatal: [38.210.201.10]: FAILED! => {"msg": "winrm send_input failed; \nstdout: Unable to initialize device PRN\r\nUnable to initialize device PRN\r\nUnable to initialize device PRN\r\n\nstderr ANSIBALLZ_WRAPPER : The term 'ANSIBALLZ_WRAPPER' is not recognized as the name \r\nof a cmdlet, function, script file, or operable program. Check the spelling of \r\nthe name, or if a path was included, verify that the path is correct and try \r\nagain.\r\nAt line:1 char:1\r\n+ ANSIBALLZ_WRAPPER = True # For test-module script to tell this is a \r\nANSIBALLZ_WR ...\r\n+ ~~~~~~~~~~~~~~~~~\r\n + CategoryInfo : ObjectNotFound: (ANSIBALLZ_WRAPPER:String) [], C \r\n ommandNotFoundException\r\n + FullyQualifiedErrorId :
The same script works on the Master server(Linux Ubuntu) if i change the hosts value to localhost. Why Ansible cannot execute the python code on the Windows server?

I found that there is a section about the problem in Ansible Docs.
Can I run Python modules?
No, the WinRM connection protocol is set to use PowerShell modules, so Python modules will not work. A way to bypass this issue to use delegate_to: localhost to run a Python module on the Ansible controller. This is useful if during a playbook, an external service needs to be contacted and there is no equivalent Windows module available.
So if you want to do such a process, you have to workaround the problem.
I solved it with suggestion that Ansible Documentation gives.
- name: test s3 module
hosts: windows
tasks:
- name: get s3 file
aws_s3:
bucket: bucketname
object: /filename.jpg
dest: /etc/ansible/playbooks/test.jpg
mode: get
delegate_to: localhost
- name: copy to win server
win_copy:
src: /etc/ansible/playbooks/test.jpg
dest: C:/test.jpg
When you use these sample codes, firstly you are downloading the files to Master Ansible server with delegate_to. And after then that you are copying the files to Windows host.

Related

What is error "Get-AnsibleWindowsWebRequestSpec"?

I am trying a test to upload a .txt file from a FTP server to a Windows client with Ansible using ansible.windows.win_get_url module like this:
Playbook:
hosts: win
gather_facts: no
tasks:
- name: Download file through FTP
ansible.windows.win_get_url:
url: ftp://10.30.103.3/FLAG.txt
dest: '%TEMP%/FLAG.txt'
url_username: test
url_password: azerty
In the output, at the end when trying:
ansible-playbook test_ftp.yml > error.txt
I get the error:
"msg": "Unhandled exception while executing module: The term 'Get-AnsibleWindowsWebRequestSpec' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again."
I installed the modules using
ansible-galaxy collection install ansible.windows
I'm using Ansible 2.9.
The error was the Windows task in the playbook, changed from ansible.windows.win_get_url to win_get_url.

Copy & fetch files in Ansible/Cygwin

Question - - how do you navigate the cygwin path structure for file transfers, copies and fetches?
I've installed ansible on a windows 10 machine using cygwin. Everthing works except for the ansible.builtin.copy task. Here is the setup
Relevant Directory Structure
C:.
├───.github
│ └───workflows
├───files
└───payload
├───communication
├───monitoring
The playbook sits in the documents directory of the user, so . is C:/Users/user/Documents/
Ansible Task
- name: Download YAML payloads
ansible.builtin.copy:
src: payload
dest: /some/directory/
The ansible cygwin command line actually runs from /cygdrive/c/Users... path. I can navigate to the payload directory from either windows cli or the cygwin cli using their native paths. [Must be a symlink?] In any event - when I run the above task, the src directory is not found.
What I've tried - both absolute and relative path variables in the src line, for both the cywgin and the windows paths. I've also tried using the inventory environment variables ({{ playbook_dir }}). fileglob: didn't work either.
What I haven't tried - {{ role_path }}. I'd like to keep the source YAMLs all together in the top directory. But not sure if this would work by putting the files directory under a role.
added details
Path to playbook from windows
C:\Users\billr\Documents\GitHub\home-k3s
Path to playbook from cygwin
/cygdrive/c/Users/billr/Documents/GitHub/home-k3
files & directories
home-k3s
files // these are the files/dirs I'm looking to copy
payload
communication
first.yaml
second.yaml
monitoring
first.yaml
second.yaml
hosts.ini //contains playbook hosts.
test.yml //this is the playbook I'm running
playbook cat
---
- hosts: master
gather_facts: yes
become: yes
tasks:
- name: Download YAML payloads
ansible.builtin.copy:
src: payload
dest: /home/bill/
Run #1
src: payload <-- this is the method per docs (for linux).
result: FAILED! => {"changed": false, "msg": "Source payload not found"}
Run #2
src: "{{ playbook_dir }}/files/payload"
result: FAILED! => {"changed": false, "msg": "Source /cygdrive/c/Users/billr/Documents/GitHub/home-k3s/files/payload not found"}
Run #3
src: "/cygdrive/c/Users/billr/Documents/GitHub/home-k3s/files/payload"
result: FAILED! => {"changed": false, "msg": "Source /cygdrive/c/Users/billr/Documents/GitHub/home-k3s/files/payload not found"}
Run #4
src: "c:/Users/billr/Documents/GitHub/home-k3s/files/payload"
FAILED! => {"changed": false, "msg": "Source c:/Users/billr/Documents/GitHub/home-k3s/files/payload not found"}
Note that I can see the files from the cygwin terminal with ls and I can see the files from the windows cli with dir.
Final Notes
Cygwin Github Issue Link

Run local command with Ansible and share variable in the remote context

I have the following logic that I would like to implement with Ansible:
Before to update some operating system packages, I want to check some other remote dependencies, which involve querying some endpoints and decide if the next version is good or not.
The script new_version_available returns 0 if there is something new and 1 if there isn't something new.
To avoid install unnecessary packages in production, or open unnecessary ports in my firewall in the DMZ, I would like to run this script locally in my host and if it succeeds, then we run the next task remotely.
tasks:
- name: Check if there is new version available
command: "{{playbook_dir}}/new_version_available"
delegate_to: 127.0.0.1
register: new_version_available
ignore_errors: False
- name: Install our package
command:
cmd: '/usr/bin/our_installer update'
warn: False
when: new_version_available is succeeded
Which gives me the following error:
fatal: [localhost -> 127.0.0.1]: FAILED! => {"changed": false, "cmd": "/home/foo/ansible-deploy-bar/new_version_available", "msg": "[Errno 2] No such file or directory", "rc": 2}
That means that my command cannot be found, however my script exists and i have permission to access it.
My Development environment where I'm testing the playbook, is running in a virtual machine, via NAT, where forward the Guest port 22 to my host 2222, so if i want to login in my VM I do ssh root#localhost -p 2222. My inventory looks like:
foo:
hosts:
localhost:2222
My Question is:
What would be the Ansible way to achieve what I want, i.e run some command locally and pass the results to a register and use it as condition in a task? Run the command and pass the result as environment variable to Ansible?
I'm using this documentation as support https://docs.ansible.com/ansible/latest/user_guide/playbooks_delegation.html

How to fix "Could not match supplied host pattern, ignoring: bigip" errors, works in Ansible, NOT Tower

I am running Ansible Tower v3.4.1 with Ansible v2.7.6 on an ubuntu 16.04 VM running on VirtualBox. I run a playbook that works when I run it from the command line using "ansible-playbook" but fails when I try to run it from Ansible Tower. I know I must have something misconfigured in ansible tower but I can't find it.
I get this warning no matter what changes I make to the inventory (hosts) file.
$ ansible-playbook 2.7.6
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/var/lib/awx/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/dist-packages/ansible
executable location = /usr/bin/ansible-playbook
python version = 2.7.12 (default, Nov 12 2018, 14:36:49) [GCC 5.4.0 20160609]
Using /etc/ansible/ansible.cfg as config file
SSH password:
**/tmp/awx_74_z6yJB4/tmpVlXGCX did not meet host_list requirements**, check plugin documentation if this is unexpected
Parsed /tmp/awx_74_z6yJB4/tmpVlXGCX inventory source with script plugin
PLAYBOOK: addpool.yaml *********************************************************
1 plays in addpool.yaml
[WARNING]: **Could not match supplied host pattern, ignoring: bigip**
PLAY [Sample pool playbook] ****************************************************
17:05:43
skipping: no hosts matched
I have enabled inventory plugins for YAML, and made my hosts file into a hosts.yml file.
Here's my hosts file:
192.168.68.253
192.168.68.254
192.168.1.165
[centos]
dad2 ansible_ssh_host=192.168.1.165
[bigip]
bigip1 ansible_host=192.168.68.254
bigip2 ansible_host=192.168.68.253
Here's my playbook:
---
- name: Sample pool playbook
hosts: bigip
connection: local
tasks:
- name: create web servers pool
bigip_pool:
name: web-servers2
lb_method: ratio-member
password: admin
user: admin
server: '{{inventory_hostname}}'
validate_certs: no
I replaced hosts: bigip with hosts: all and specified the inventory in Tower as bigip which contains only the two hosts I want to change. This seems to provide the output I am looking for.
For the ansible-playbook command line, I added --limit bigip and this seems to provide the output I am looking for.
So things appear to be working, I just don't know whether this is best practice use.
If you get the error below while running a playbook with the command
ansible-playbook -i test-project/inventory.txt playbook.yml
{"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 172.31.24.10 port 22: Connection timed out", "unreachable": true}
The solution is to add, in the file ansible.cfg:
[defaults]
inventory=/etc/ansible/hosts
I think you need to remove the connection: local.
You have specified in hosts: bigip that you want these tasks to only run on hosts in the bigip group. You then specify connection: local which causes the task to run on the controller node (i.e. localhost), rather than the nodes in the bigip group. Localhost is not a member of the bigip group, and so none of the tasks in the play will trigger.
Check for special characters in absolute path of hosts file or playbook. Incase if you directly copied the path from putty, try copy and paste it from notepad or any editor
For me the issue was the format of the /etc/ansible/hosts file. You should use the :children suffix in order to use groups of groups like this:
[dev1]
dev_1 ansible_ssh_host=192.168.1.55 ansible_connection=ssh ansible_ssh_user={{username}} ansible_ssh_pass={{password}}
[dev2]
dev_2 ansible_ssh_host=192.168.1.68 ansible_connection=ssh ansible_ssh_user={{username}} ansible_ssh_pass={{password}}
[devs:children]
dev1
dev2
Reference: here

Ansible node not able to access a file in my host System

I am trying to copy a file from my Host Mac System to CentOS on a VM through Ansible Roles.
I have a folder created called Ansible Roles and under that I have used ansible-galaxy command and have created a role called tomcatdoccfg. helloworld.war is present in the root Ansible Roles folder.
The folder structure is as below :
Ansible tasks\main.yml playbook on Mac is as below:
- name: Copy war file to tmp
copy:
src: ⁨helloworld.war
dest: /tmp/helloworld.war
The helloworld.war file should be accessible for user abhilashdk(My Default MAC username). The CentOS VM also has a user called abhilashdk. I have configured ssh keys. Meaning I have generated ssh-keys -t rsa and moved the keys to the CentOS VM using ssh-copy-id and I am able to ping to VM using ansible -i hosts node1 -m ping command. I am able to install docker also on my node1 machine using ansible.
I have a main.yml file in the root Ansible Roles folder the contents of which is as below:
---
- hosts: node1
vars:
webapp:
app1:
PORT: 8090
NAME: webapp1
app2:
PORT: 8091
NAME: webapp2
become: true
roles:
- docinstall
- tomcatdoccfg
Now when I run the command ansible-playbook -i hosts main.yml I get the below error for Copy war file to tmp:
TASK [tomcatdoccfg : Copy war file to tmp] ************************************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: /Files/DevOps/Ansible/Ansible_roles/⁨helloworld.war
fatal: [node1]: FAILED! => {"changed": false, "msg": "Could not find or access '⁨helloworld.war'\nSearched in:\n\t/Files/DevOps/Ansible/Ansible_roles/tomcatdoccfg/files/⁨helloworld.war\n\t/Files/DevOps/Ansible/Ansible_roles/tomcatdoccfg/⁨helloworld.war\n\t/Files/DevOps/Ansible/Ansible_roles/tomcatdoccfg/tasks/files/⁨helloworld.war\n\t/Files/DevOps/Ansible/Ansible_roles/tomcatdoccfg/tasks/⁨helloworld.war\n\t/Files/DevOps/Ansible/Ansible_roles/files/⁨helloworld.war\n\t/Files/DevOps/Ansible/Ansible_roles/⁨helloworld.war"}
I am not understanding what permissions should I give to hellowrold.war file so that my centos on vm will be able to access it through ansible playbook/roles.
Could anybody help me out how to solve this issue.
Thanks in Advance
adding as answer, so i can show the non-latin characters that the log you attached in the question includes:
note right before the helloworld.war.
Could be the reason why Ansible cant find the file on the FS.
To be on the safe side, i would delete the whole main.yml and rewrite it.
ansible-playbook -i hosts main.yml --ask-sudo-pass or ansible-playbook -i hosts main.yml --ask-pass
This params will ask you for sudo password for playbook operations

Resources