I want to provision Windows host that is in subnet accessible only with Linux jump host.
Windows machine uses winrm connection method.
Linux jump server is available via SSH.
I have no problem accessing windows host if available directly with:
ansible_connection: winrm
If I try to delegate the task to the Linux jump server (that has direct access to Windows) by:
- name: Ping windows
hosts: windows_machines
tasks:
- name: ping
win_ping:
delegate_to: "{{ item }}"
with_items: "{{ groups['jump_servers'][0] }}"
it tries to connect to establish WINRM connection to the jump host. Not exactly what I had in mind.
Note that for windows_machines group I have group_vars defined:
ansible_port: 5986
ansible_connection: winrm
ansible_winrm_server_cert_validation: ignore
How should I provision Windows hosts via a bastion host?
My priority was to have all the configuration in one place and not distribute part of Ansible to the bastion/jump host. I went for establishing ssh tunnel for the 5986 port.
Here is the complete task:
- name: Tunneled configuration of Windows host in a subnet
hosts: windows
connection: local #This is the trick to connect to localhost not actual host
gather_facts: no
tasks:
- name: First setup a tunnel
local_action: command ssh -Nf -4 -o ControlPersist=1m -o ControlMaster=auto -o ControlPath="~/.ssh/mux2win-%r#%h:%p" -o StrictHostKeyChecking=no -o PasswordAuthentication=no -o UserKnownHostsFile="/dev/null" -i {{ hostvars[item].ansible_ssh_private_key_file }} {{ hostvars[item].ansible_ssh_user }}#{{ hostvars[item].ansible_host }} -L {{ ansible_port }}:{{ actual_host }}:{{ ansible_port }}
with_items:
- "{{ groups['jump_servers'][0] }}" #I know my topology so I know which host to use
- name: (optional) Second ensure it is up
local_action: command ssh -O check -S "~/.ssh/mux2win-%r#%h:%p" {{ hostvars[item].ansible_ssh_user }}#{{ hostvars[item].ansible_host }}
with_items:
- "{{ groups['jump_servers'][0] }}"
# ------- actual windows tasks (from ansible examples) ------------
- name: Ping
connection: local
win_ping:
- name: test raw module- run ipconfig
raw: ipconfig
register: ipconfig
- debug: var=ipconfig
- name: Test stat module- test stat module on file
win_stat: path="C:/Windows/win.ini"
register: stat_file
- debug: var=stat_file
- name: Check stat_file result
assert:
that:
- "stat_file.stat.exists"
- "not stat_file.stat.isdir"
- "stat_file.stat.size > 0"
- "stat_file.stat.md5"
# ------- end of actual windows tasks ------------
- name: Stop the tunnel. It would stop anyway after 1m.
local_action: command ssh -O stop -S "~/.ssh/mux2win-%r#%h:%p" {{ hostvars[item].ansible_ssh_user }}#{{ hostvars[item].ansible_host }}
with_items:
- "{{ groups['jump_servers'][0] }}"
For this to work I had to modify slightly the inventory file:
[windows]
windows1 ansible_host=127.0.0.1 ansible_ssh_user=Administrator actual_host=192.168.0.2 (...)
Ansible can connect by accessing 5986 port on local host, so ansible_host has to be set to 127.0.0.1 and to have the information on the actual ip of the Windows machine a custom variable actual_host is set.
That's not what the delegate_to option on a task does.
Instead, delegate_to will make sure that the task only runs against a specific node rather than the group that is listed in the role/playbook.
So for example you may have a role that sets up MySQL on a cluster of boxes that are defined generically but then want to do specific configuration/tasks on the master alone, leaving the master to then replicate these out to the slaves.
You can do SSH proxying where you forward SSH connections through a bastion/jump host but that obviously needs your connection to be SSH throughout which doesn't help you.
The only thing I can think of to help you here would be to use Ansible directly from the bastion/jump host possibly triggered by Ansible (or anything else really) from your machine outside of the protected zone.
Related
Hello to all stack overflow community.
I'm seeking you help because I've been trying to accomplish the task of getting a file from remote Windows to local linux using Ansible-AWX and I can't get it to work. Bellow I shared the playbook and most of tests I've done but none of them worked.
I'm getting latest file in a windows directory and trying to transfer that file to local AWX either inside the docker or in the linux server where AWX is running.
Test_1: Said file was copied but when I go inside the docker nothing there. I can't find an answer and couldn't find any on Google.
Test_2: Didn't work. It says can't authenticate to linux server
Test_3: Task became idle and I have to restart the docker to be able to stop it. It gets crazy. No idea why.
Test_4: It says connection unexpectedly closed.
I didn't want to provide output to reduce noise and because I can't share the information. I removed names and ips from playbook as well.
I'm connecting to Windows server using AD.
Please, I don't know what else to do. Thanks for your help in advance.
---
- name: Get file from Windows to Linux
hosts: all # remote windows server ip
gather_facts: true
become: true
vars:
local_dest_path_test1: \var\lib\awx\public\ # Inside AWX docker
local_dest_path_test2: \\<linux_ip>\home\user_name\temp\ # Outside AWX docker in the linux server
local_dest_path_test3: /var/lib/awx/public/ # Inside AWX docker
# Source file in remote windows server
src_file: C:\temp\
tasks:
# Getting file information to be copied
- name: Get files in a folder
win_find:
paths: "{{ src_file }}"
register: found_files
- name: Get latest file
set_fact:
latest_file: "{{ found_files.files | sort(attribute='creationtime',reverse=true) | first }}"
# Test 1
- name: copy files from Windows to Linux
win_copy:
src: "{{ latest_file.path }}"
dest: "{{ local_dest_path_test1 }}"
remote_src: yes
# Test 2
- name: copy files from Windows to Linux
win_copy:
src: "{{ latest_file.path }}"
dest: "{{ local_dest_path_test2 }}"
remote_src: yes
become: yes
become_method: su
become_flags: logon_type=new_credentials logon_flags=netcredentials_only
vars:
ansible_become_user: <linux_user_name>
ansible_become_pass: <linux_user_password>
ansible_remote_tmp: <linux_remote_path>
# Test 3
- name: Fetch latest file to linux
fetch:
src: "{{ latest_file.path }}"
dest: "{{ local_dest_path_test3 }}"
flat: yes
fail_on_missing: yes
delegate_to: 127.0.0.1
# Test 4
- name: Transfer file from Windows to Linux
synchronize:
src: "{{ latest_file.path }}"
dest: "{{ local_dest_path_test3 }}"
mode: pull
delegate_to: 127.0.0.1
Problem: referencing a fact about a host ( in this case, the private ip ) from another host in a playbook using a wildcard only seems to work in the "Host" part of a playbook, not inside a task. vm_ubuntu* cannot be used in a task.
In a single playbook, I have a couple of hosts, and because the inventory is dynamic, I don't have the hostname ahead of time as Azure appends an identifier after it has been created.
I am using TF to create.
And using the Azure dynamic inventory method.
I am calling my playbook like this, where myazure_rm.yml is a bog standard azure dynamic inventory method, as of the time of this writing.
ansible-playbook -i ./myazure_rm.yml ./bwaf-playbook.yaml --key-file ~/.ssh/id_rsa --u azureuser
My playbook looks like this ( abbreviated ).
- hosts: vm_ubuntu*
tasks:
- name: housekeeping
set_fact:
vm_ubuntu_private_ip="{{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] }}"
#"
- debug: var=vm_ubuntu_private_ip
- hosts: vm_bwaf*
connection: local
vars:
vm_bwaf_private_ip: "{{private_ipv4_addresses | join }}"
vm_bwaf_public_ip: "{{ public_ipv4_addresses | join }}"
vm_ubuntu_private_ip: "{{ hostvars['vm_ubuntu*']['ip'] }}"
api_url: "http://{{ vm_bwaf_public_ip }}:8000/restapi/{{ api_version }}"
#"
I am answering my own question to get rep, and to to help others of course.
I also want to thank the person ( https://stackoverflow.com/users/4281353/mon ) who came up with this first, which appears in here: How do I set register a variable to persist between plays in ansible?
- name: "Save private ip to dummy host"
add_host:
name: "dummy_host"
ip: "{{ vm_ubuntu_private_ip }}"
And then this can be referenced in the other host in the playbook like this:
- hosts: vm_bwaf*
connection: local
vars:
vm_bwaf_private_ip: "{{private_ipv4_addresses | join }}"
vm_bwaf_public_ip: "{{ public_ipv4_addresses | join }}"
vm_ubuntu_private_ip: "{{ hostvars['dummy_host']['ip'] }}"
I would like to monitor multiple logs on the universal forwarder. How can i do this? Also when I set forward-server am running out in error. with Enable boot-start somehow i have to accept license manually to finish up the installation. Any suggestions, please?
- name: connect forward server to Splunk server
command: "{{ splunkbin }} add forward-server {{ item }} -auth {{ splunkcreds }}"
with_items: "{{ splunkserver }}"
when: splunkserver is defined
notify: restart_splunk
- name: Enable Boot Start
command: "{{ splunkbin }} enable boot-start"
- name: add temporary monitor to create directory
command: "{{ splunkbin }} add monitor /etc/hosts -auth {{ splunkcreds }}"
notify: restart_splunk
Use the following to accept the license without prompting
- name: Enable Boot Start
command: "{{ splunkbin }} enable boot-start --accept-license"
I am new to ansible.I am trying to fetch a setup file from a remote server and trying to copy it on my mac and then run it if necessary.Here is my playbook.I tried get_url because i am running in a virtual box on mac..So I have ansible on my mac and linux on a virtual box on mac.So I can give commands in linux and not have to worry about mac os x syntax.So the issue i am facing is this.This is the error ansible is showing me.So please help in resolving this.Am i using the right command ,if not what can i do.
- name: download file
hosts: linux
user: root
vars_prompt:
- name: smb_username
prompt: "Enter smb share username"
- name: smb_password
prompt: "Enter smb share password"
private: yes
tasks:
- name: download file
command: smbclient "Actual url" {{ smb_password }} -U {{ smb_username }} -c "recurse;lcd /local/path;get archive.zip" creates=/local/path/archive.zip*
This isn't a playbook, playbooks start with
---
- hosts:
- hostA
tasks:
- name: ...
get_url: ...
Ansible has example playbooks, and one for get_url in particular: https://github.com/ansible/ansible-examples/blob/master/language_features/get_url.yml
Background
I am deploying to a system containing multiple hosts along with a monitoring host. The monitoring host needs to use information about the other hosts to configure its monitoring checks. However, variables defined as Jinja templates in host_vars/group_vars do not work when accessed through hostvars on the monitoring host.
Example
inventory.ini
my_host ansible_connection=local
monitoring_host ansible_connection=local
host_vars/my_host
---
my_var: "{{ inventory_hostname }}"
playbook.yml
---
- hosts: my_host
tasks:
- debug: var=my_var
- hosts: monitoring_host
tasks:
- debug: var="hostvars['my_host']['my_var']"
The expectation is that the two debug task will output the same value, "my_host". In Ansible 1.7, the second debug task outputs "{{ inventory_hostname }}" (i.e. the template is not expanded). In Ansible 1.8, the second debug task outputs "monitoring_host" (i.e. the template is expanded in the wrong context).
Is this a known bug? Is there a good workaround?
I'm pretty sure this is buggy behaviour. Possible workaround:
---
- hosts: my_host
tasks:
- debug: var=my_var
- set_fact: my_var="{{ my_var }}" # Expanded in my_host context
- hosts: monitoring_host
tasks:
- debug: var="hostvars['my_host']['my_var']"