How to know external ip address of ansible client - amazon-ec2

During deployment needed setup ufw firewall rule: enable access for hosts group servers from inventory. Target host is anazon ec2 instance, but it maybe placed at other provider.
I tried:
- name: Ufw rules
ufw: rule=allow from_ip={{ hostvars[item]['ansible_eth0']['ipv4']['address'] }}
with_items: groups['servers']
notify:
- Restart ufw
file hosts:
..
[servers]
server1.site.com
server2.site.com
server3.site.com
..
But host server1.site.com, actually have host_vars:
"ansible_eth0": {
"active": true,
"device": "eth0",
"ipv4": {
"address": "10.x.x.x",
...
Ip address 10.x.x.x, as I understand, is internal amazon network ip address.
If execute ping server1.site.com from outside ec2, I get:
64 bytes from server1.site.com (46.x.x.x): icmp_seq=1 ttl=56 time=49.5 ms
...
Executing ansible server1.site.com -m setup -i hosts | grep 46.x.x.x found nothing.
How to known external ip address of host from inventory group using ansible?
Or how setup ufw firewall using host names from inventory?

I think your best bet is to use the lookup plugin written by #dsedivec (https://github.com/dsedivec/ansible-plugins).
Create a lookup_plugins/ directory at the top directory of your playbook.
Put dns.py in it
curl https://raw.githubusercontent.com/dsedivec/ansible-plugins/master/lookup_plugins/dns.py > lookup_plugins/dns.py
And use it like so :
- name: Ufw rules
ufw: rule=allow from_ip={{ lookup('dns', item) }}
with_items: groups['servers']
notify:
- Restart ufw
Good luck !

The easiest way is to add connection: local
---
- name: get my public IP
ipify_facts: api_url=http://api.ipify.org
connection: local
- firewalld: rich_rule='rule family=ipv4 source address={{ ipify_public_ip }} accept' permanent=no state=enabled timeout=300
become: true

Related

Firewall Functional Test

I am new to Ansible, I am only using a central machine and a host node on Ubuntu server, for which I have to deploy a firewall; I was able to make the SSH connections and the execution of the playbook. What I need to know is how to verify that the port I described in the playbook was blocked or opened, either on the controller machine and on the host node. Thanks
According your question
How to verify that the port I described in the playbook was blocked or opened, either on the controller machine and on the host node?
you may are looking for an approach like
- name: "Test connection to NFS_SERVER: {{ NFS_SERVER }}"
wait_for:
host: "{{ NFS_SERVER }}"
port: "{{ item }}"
state: drained
delay: 0
timeout: 3
active_connection_states: SYN_RECV
with_items:
- 111
- 2049
and have also a look into How to use Ansible module wait_for together with loop?
Documentation
Ansible wait_for Examples
You may also interested in Manage firewall with UFW and have a look into
Ansible ufw Examples

Create vars from host inventory

I have below infrastructure (3 servers running windows 2016 server edition) where master server runs a IIS service on port 80(example) and 2 agents need to connect to them. To allow the communication, I need to add windows firewall rules to whitelist the ip addresses
one master server (mas)
and two agent servers (agt)
The task which I need to execute through ansible is, I need to add the below firewall rule only on the master server and should not run on the agent hosts. How to run the below task only on the master server so that the ip address details of agent(agt) machines are used while configuring the firewall rules.
- hosts: mas, agt
tasks:
- name: Firewall Rule Modifications
win_firewall_rule:
name: "IIS port"
localport: "80"
direction: in
action: allow
remoteip: "{{ansible_ip_addresses[0]}}"
protocol: "tcp"
description: "Allow agents"
enabled: yes
state: present
I was able to create a solution(with a vagrant test setup with centos 7) as mentioned below but I think there should be a simpler way to achieve this :-)
Inventory File:
[master]
mas
[agents]
agt1
agt2
Playbook:
- name: Configure Iptables
hosts: all
serial: 1
tasks:
- name: create a file to store inventory IP's
file:
dest: /tmp/foo
state: touch
force: yes
delegate_to: localhost
- name: Register IP address
shell: echo "{{ ansible_enp0s8.ipv4.address }}"
register: op
delegate_to: localhost
- name: write IP's to a temp file
lineinfile:
dest: /tmp/foo
line: "{{ op.stdout_lines[0] }}"
insertafter: EOF
delegate_to: localhost
- name: Add firewall rules
iptables:
chain: INPUT
source: "{{item}}"
protocol: tcp
destination_port: 80
jump: ACCEPT
with_lines: cat /tmp/foo
when: ansible_hostname == 'mas'

How to assign multiple IPs to a single host using ansible nios module

I need to assign multiple IPs to the same host using Ansible nios modules.
I tried using nios_host_record module but it doesn't work in this scenario.
- name: configure an ipv4 host record
nios_host_record:
name: host.ansible.com
ipv4:
- address: 192.168.10.1
aliases:
- cname.ansible.com
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local"
You can add multiple IPs like a list. Wish Ansible documentation for modules should have more examples like this.
ipv4:
- address: 192.168.10.1
- address: 192.168.10.2
- address: 192.168.10.3

How to use ansible to test network connection?

I am setting Zabbix agent service on many hosts, it can't confirm network is available between Zabbix server and Zabbix agent even service is up.
For example, I install Zabbix-agent on host A by ansible playbook. And there is already a Zabbix server on host B.
How can I use ansible to test, if host A can access port 10050 of host A and if host A can access port 10051 of host B?
Can you help to tell me which modules are suitable for the above network testing? In addition, how to loop inventory hosts in ansible-playbook.
Thanks.
You can take advantage of wait_for module to accomplish this.
Example:
- name: verify port 10050 is listening on hostA
wait_for:
host: hostA
port: 10050
delay: 5
state: started
delegate_to: hostB
To iterate through the hosts in the inventory file, you can use inventory_hostnames module:
with_inventory_hostnames:
- all

Ansible ufw module ERROR: Could not find a profile matching 'xxxxx'

I'm working to setup UFW rules via Ansible. I'm able to get it installed, start it and deny everything. I then attempt to allow connections from http, https, and ssh. All attempts to add the allow for those items are met with errors that look like:
failed: [lempy1] (item={u'service': u'http'}) => {"failed": true, "item": {"service": "http"}, "msg": "ERROR: Could not find a profile matching 'http'\n"}
failed: [lempy1] (item={u'service': u'https'}) => {"failed": true, "item": {"service": "https"}, "msg": "ERROR: Could not find a profile matching 'https'\n"}
failed: [lempy1] (item={u'service': u'ssh'}) => {"failed": true, "item": {"service": "ssh"}, "msg": "ERROR: Could not find a profile matching 'ssh'\n"}
The entire role looks like this:
tasks/main.yml
---
- name: Install ufw
apt: name=ufw state=present
tags:
- security
- name: Allow webservery things
ufw:
rule: allow
name: '{{item.service}}'
with_items:
- service: http
- service: https
- service: ssh
tags:
- security
- name: Start ufw
ufw: state=enabled policy=deny
tags:
- security
Any idea why I wouldn't be able to allow these services? I am able to add the services properly when ssh'ing into the server and running sudo ufw allow http, etc.
As mentioned in the ufw module docs, the name (or app) parameter uses applications that are registered in /etc/ufw/applications.d which have an INI format and look something like this:
[CUPS]
title=Common UNIX Printing System server
description=CUPS is a printing system with support for IPP, samba, lpd, and other protocols.
ports=631
Normally you can use ufw allow application-profile to allow an application defined either in /etc/ufw/applications.d or /etc/services to open up iptables for things that aren't necessarily defined in /etc/ufw/applications.d.
Unfortunately, Ansible's ufw module instead builds the ufw command in this format instead:
/usr/sbin/ufw allow from any to any app 'application-profile'
Which only uses the /etc/ufw/applications.d list and won't read /etc/services.
In your case you could simply specify the ports as these are well known, potentially using a named variable to further explain your Ansible code:
- name: Allow webservery things
ufw:
rule: allow
port: '{{ item }}'
with_items:
- '{{ http_port }}'
- '{{ https_port }}'
- '{{ ssh_port }}'
tags:
- security
And then define the variables somewhere (such as your role defaults):
http_port: 80
https_port: 443
ssh_port: 22
As an aside, you might want to notice that I simplified your list of dictionaries with a single key into a simpler straight list which tidies up your task a bit.
Alternatively you could easily template the application profiles using Ansible's template module.

Resources