Is it possible to write an ansible playbook that can tell me if my ec2 instance has a security group that opens a port? - amazon-ec2

I would like to write an ansible playbook that will tell me if my ec2 instances have a security group that contains a rule that allows ingress on a specified port. I have seen answers like Test if a server is reachable from host and has port open with Ansible where one would have this in the playbook:
- hosts: target.host
tasks:
- wait_for: host=remote.host port=8080 timeout=1
- debug: msg=ok
But that tells me if something is listening on port 8080 on the remote host. In my circumstance there will be no process listening because the service has not yet been installed.

You could try using the aws ec2 module to get Netword ACLs and apply a filter to get the one's you're after. Using tags could also be an easy method to filter the resources for your playbook. This code is untested, and you'd need to parse the response into your playbook get the information you're after. It's basically a starting point. Check this link for further info.
# Retrieve Port 8080 Network ACLs
- name: Get Port 8080 NACLs
community.aws.ec2_vpc_nacl_info:
region: us-west-2
filters:
'entry.port-range.from': 8080,
'entry.port-range.to': 8080
register: port_8080_nacls

Related

What's the "best" way to add an ip route using ansible?

I am unable to find an ansible module that adds ip routes.
Basically the command I'm looking for should allow something like:
sudo ip route add 12.3.4.0/24 via 123.456.78.90
I found net_static_route_module which seems related, but is deprecated since 2022-06-01.
A simple solution would be:
- name: Add a route
ansible.builtin.shell:
cmd: sudo ip route add 12.3.4.0/24 via 123.456.78.90
of course, but inbuilt modules are usually better.
Additional information
This task will be executed on a subset of all nodes (ubuntu 22.04 machines that are all part of a cloud cluster using openstack) (specified by groups). Concrete subnets and IPs will be defined using variables.
An example hostfile could look like this:
master:
hosts:
localhost:
ansible_connection: local
ansible_python_interpreter: /usr/bin/python3
ansible_user: ubuntu
ip: localhost
workers:
children:
ephemeral:
hosts: {}
hosts:
someworker:
ansible_connection: ssh
ansible_python_interpreter: /usr/bin/python3
ansible_user: ubuntu
This playbook will be used to setup wireguard. Every vpn-node (those nodes will be connected with each other via wireguard) is connected in its own subnet with multiple worker nodes. Those workers need to add the ip route to get back to the master node which is in a different subnet, but in the same virtual subnet created by wireguard and the vpn nodes). I do not think that this is related to my question, but I might overlook how this can affect the right answer.
From your description I understand that you like to configure the network route settings on a Linux based operating system (Debian/GNU Linux, Ubuntu 22.04) and not on a dedicated router or switch.
Whereby the mentioned module net_static_route was for providing
... declarative management of static IP routes on network appliances (routers, switches et. al.).
and became deprecated
Removed in: major release after 2022-06-01
Why: Updated modules released with more functionality
Alternative: Use platform-specific [netos]_static_route module
it further recommends to use the vendor and platform specific modules instead.
Certain Linux Distributions tend to integrate and use NetworkManager for creating and managing network connections.
Documentation
RHEL7 - Getting Started with NetworkManager
ArchLinux - NetworkManager
Ubuntu - NetworkManager
...
So the respective Ansible module for this is nmcli module – Manage Networking. You may have a look into the Parameters and Examples, especially into the parameters for route*.
Further Readings
For more examples have a look at
How to configure network settings with Ansible system roles
Linux System Roles

Can we create a playbook to install a package in our own system?

I'm using Ubuntu Linux
I have created an inventory file and I have put my own system IP address there.
I have written a playbook to install the nginx package.
I'm getting the following error:
false, msg" : Failed to connect to the host via ssh: connect to host myip : Connection refused, unreachable=true
How can I solve this?
You could use the hosts keyword with the value localhost
- name: Install nginx package
hosts: localhost
tasks:
- name: Install nginx package
apt:
name: nginx
state: latest
Putting your host IP directly in your inventory treats your local machine as any other remote target. Although this can work, ansible will use the ssh connection plugin by default to reach your IP. If an ssh server is not installed/configured/running on your host it will fail (as you have experienced), as well as if you did not configure the needed credentials (ssh keys, etc.).
You don't need to (and in most common situations you don't want to) declare localhost in your inventory to use it as it is implicit by default. The implicit localhost uses the local connection plugin which does not need ssh at all and will use the same user to run the tasks as the one running the playbook.
For more information on connection plugins, see the current list
See #gary lopez answer for an example playbook to use localhost as target.

Hearbeat icmp configuration host aliases

I have a elastic stack (version 7.3.0) configured, with a Heartbeat set up to ping my different hosts.
The config file of my monitor looks like this:
- type: icmp
name: icmp_monitor
schedule: '#every 5s'
hosts:
- machine1.domain.com # Machine 1
- machine2.domain.com # Machine 2
- machine3.domain.com # Machine 3
Is there a way to give the hosts an "alias" in the configuration file ?
In my organisation, the server hostname is not very meaningfull, it would be great for example to specify that machine1.domain.com is MongoDB main server.
The example on the documentation page shows that you can set host names in the hosts section/key. There they specify "myhost". So I assume that it is possible to define any name you want.
Elasticsearch is however not responsible for aliasing/resolving hostnames. It is a task of your OS.
If your heartbeat runs on a Linux machine I would set the aliases in /etc/hosts like
192.168.1.X mongodb-main
and would set the alias in the monitor config like
- type: icmp
name: icmp_monitor
schedule: '#every 5s'
hosts:
- mongodb-main
and see if heartbeat accepts it and can resolve the alias/hostname.

AWS EC2 instance can only be accessible via port 80

I recently setup an ec2 Instance (RHEL7.2) on Amazon Web Services. I am having trouble getting it to respond to http requests. I run docker run -p 12345:80 nginx:latest successfully and I have added port 12345 to the inbound rules in the instance's security group. But this hasn't worked so far - I've tried both adding it to the default security group, and creating a new security group. And in local curl http://localhost:12345/ works right.
But the strange thing is if I change -p 12345:80 to -p 80:80, it works well!!! Then I have tried other ports mapping, but the result is only 80 works!
Has anyone else had a similar experience? Or give me some help and advice, thanks in advance!
PS:
My containers:
Image nginx 0:0:0:0:12345->80/tcp
Image nginx 0:0:0:0:80->80/tcp
Security group:
All TCP All TCP 1~65535 0:0:0:0
EC2:
Public IPv4: xx.xx.zz.zz
I can access via http://xx.xx.zz.zz/ in browser and ssh via port 22. But http://xx.xx.zz.zz:12345/ failed.

Ansible connect to jump machine through VPN?

I was wondering if it were possible to tell Ansible to set up a VPN connection before executing the rest of the playbook. I've googled around, but haven't seen much on this.
You could combine a local playbook to setup a VPN and a playbook to run your tasks against a server.
Depending on whats the job you can use ansible or a shell script to connect the VPN. Maybe there should be another playbook to disconnect afterwards.
As result you will have three playbooks and one to combine them via include:
- include: connect_vpn.yml
- include: do_stuff.yml
- include: disconnect_vpn.yml
Check How To Use Ansible and Tinc VPN to Secure Your Server Infrastructure.
Basically, you need to install thisismitch/ansible-tinc playbook and create a hosts inventory file with the nodes that you want to include in the VPN, for example:
[vpn]
prod01 vpn_ip=10.0.0.1 ansible_host=162.243.125.98
prod02 vpn_ip=10.0.0.2 ansible_host=162.243.243.235
prod03 vpn_ip=10.0.0.3 ansible_host=162.243.249.86
prod04 vpn_ip=10.0.0.4 ansible_host=162.243.252.151
[removevpn]
Then you should review the contents of the /group_vars/all file such as:
---
netname: nyc3
physical_ip: "{{ ansible_eth1.ipv4.address }}"
vpn_interface: tun0
vpn_netmask: 255.255.255.0
vpn_subnet_cidr_netmask: 32
where:
physical_ip is IP address which you want tinc to bind to;
vpn_netmask is the netmask that the will be applied to the VPN interface.
If you're using Amazon Web Services, check out the ec2_vpc_vpn module which can create, modify, and delete VPN connections. It uses boto3/botocore library.
For example:
- name: create a VPN connection
ec2_vpc_vpn:
state: present
vpn_gateway_id: vgw-XXXXXXXX
customer_gateway_id: cgw-XXXXXXXX
- name: delete a connection
ec2_vpc_vpn:
vpn_connection_id: vpn-XXXXXXXX
state: absent
For other cloud services, check the list of Ansible Cloud Modules.

Resources