====== Ansible command examples ======
===== All ansible commands =====
https://docs.ansible.com/ansible/latest/command_guide/command_line_tools.html
**ansible-rulebook** : start a playbook based on a specific event
https://blog.stephane-robert.info/post/ansible-event-driven/
**ansible-pull** : opposite to ansible is based on the push mode, offering a central management, the pull mode can be use in specific cases
https://blog.octo.com/ansible-pull-killer-feature
**ansible-galaxy** : get collections of playbooks
**ansible** : Define and run a single task ‘playbook’ against a set of hosts
**ansible-playbook** : Define and run a single task ‘playbook’ against a set of hosts
**ansible-config** : View ansible configuration
**ansible-console** : REPL console for executing Ansible tasks
**ansible-doc** : plugin documentation tool
**ansible-galaxy** : Perform various Role and Collection related operations
**ansible-inventory** : Show Ansible inventory information, by default it uses the inventory script JSON format
**ansible-vault** : encryption/decryption utility for Ansible data files
**ansible-lint** : check playbook syntax
===== cmd =====
# ansible all -m ping
# ansible -vvv -i "node1," all -u user1 -m ping # debug
# ansible foo.example.com -m yum -a "name=httpd state=installed"
# ansible -i hosts all -m yum -a 'name=ncdu state=present'
# ansible -i hosts all -m yum -a 'name=ncdu state=absent'
# ansible foo.example.com -a "/usr/sbin/reboot"
# ansible aix1 -m script -a "./myscript.sh"
Commands modules for **ansible**
command
expect
psexec (for windows)
raw
script
shell
telnet
Only way to pass a command on target without python installed
# ansible myhost --become -m raw -a "yum -y install python"
ansible-inventory --list
ansible-inventory -i ./sample.yml --graph
ansible-config dump --only-changed
ansible -m module_name -a attributes
ansible-config dump
ansible-config list
ansible-config view
# ansible all -m ping --one-line
lnx80 | SUCCESS => {"changed": false,"ping": "pong"}
lnx81 | SUCCESS => {"changed": false,"ping": "pong"}
aix01 | SUCCESS => {"changed": false,"ping": "pong"}
aix20 | SUCCESS => {"changed": false,"ping": "pong"}
$ ANSIBLE_REMOTE_USER=user01 ansible all -k -K -m ping
SSH password:
BECOME password[defaults to SSH password]:
172.16.120.155 | FAILED! => {
"msg": "Using a SSH password instead of a key is not
possible because Host Key checking is enabled and sshpass
does not support this. Please add this host's fingerprint
to your known_hosts file to manage this host."
}
172.16.120.122 | FAILED! => {
"msg": "Using a SSH password instead of a key is not
possible because Host Key checking is enabled and sshpass
does not support this. Please add this host's fingerprint
to your known_hosts file to manage this host."
}
172.16.120.123 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/
platform-python"
},
"changed": false,
"ping": "pong"
}
File conversion:
[root@srv1]/usr/bdl/ansible# ansible-inventory -i inventory/hosts --list
{
"ALL": {
"children": [
"cluster",
"test1"
]
},
"_meta": {
"hostvars": {}
},
"all": {
"children": [
"ALL",
"empty",
"managedClients",
"ungrouped"
]
},
"cluster": {
"hosts": [
"cl1labo",
"cltest"
]
},
"test1": {
"hosts": [
"laboh"
]
}
}
[root@srv1]/usr/bdl/ansible# ansible-inventory -i inventory/hosts --list --yaml
all:
children:
ALL:
children:
cluster:
hosts:
cl1labo: {}
cltest: {}
test1:
hosts:
laboh: {}
empty: {}
managedClients: {}
ungrouped: {}
===== playbook =====
==== Copy file ====
# cat copy_file.yml
---
- hosts: app
tasks:
- name: Fetch the file from the mwiapp01 to master
run_once: yes
fetch: src=/tmp/app01-to-app02.jar dest=buffer/ flat=yes
when: "{{ inventory_hostname == 'mwiapp01' }}"
- name: Copy the file from master to mwiapp02
copy: src=buffer/app01-to-app02.jar dest=/tmp/
when: "{{ inventory_hostname == 'mwiapp02' }}"
==== Firewalld ====
# cat fiwalld.yml
---
- name: FirewallD
hosts: localhost
connection: local
tasks:
- name: FirewallD rules
firewalld:
permanent: yes
immediate: yes
service: "{{ item }}"
state: enabled
with_items:
- http
- https
tasks:
- name: FirewallD rules
firewalld:
permanent: yes
immediate: yes
port: "{{item.port}}/{{item.proto}}"
state: "{{item.state}}"
zone: "{{item.zone}}"
with_items:
- {port: "8080", proto: "tcp", state: "disabled", zone: "public" }
- {port: "161-162", proto: "udp", state: "disabled", zone: "internal" }
- {port: "9001", proto: "tcp", state: "enabled", zone: "public" }
tasks:
- name: FirewallD rules
firewalld:
permanent: yes
immediate: yes
rich_rule: "{{ item }}"
state: enabled
with_items:
- 'rule service name="ftp" audit limit value="1/m" accept'
- 'rule service name="http" audit limit value="1/m" drop'
tasks:
- name: FirewallD rules
firewalld:
permanent: yes
immediate: yes
rich_rule: "{{ item }}"
state: enabled
with_items:
- 'rule forward-port port=8080 protocol=tcp to-port=80 family=ipv4'
==== Security ====
---
- hosts: all
become: true
handlers:
- name: restart ssh
service: name=sshd state=restarted
tasks:
# Use secure and encrypted communication.
- name: Allow sshd to listen on tcp port 2849.
seport:
ports: 2849
proto: tcp
setype: ssh_port_t
state: present
when: ansible_selinux.status == 'enabled'
- name: Update SSH configuration to be more secure.
lineinfile:
dest: /etc/ssh/sshd_config
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
state: present
validate: 'sshd -t -f %s'
with_items:
- regexp: "^PasswordAuthentication"
line: "PasswordAuthentication no"
- regexp: "^PermitRootLogin"
line: "PermitRootLogin no"
- regexp: "^Port"
line: "Port 2849"
notify: restart ssh
# User account configuration.
- name: Add a deployment user.
user:
name: johndoe
state: present
# Disable root login and use `sudo`.
- name: Add sudo rights for deployment user.
lineinfile:
dest: /etc/sudoers
regexp: '^johndoe'
line: 'johndoe ALL=(ALL) NOPASSWD: ALL'
state: present
validate: 'visudo -cf %s'
# Remove unused software, open only required ports.
- name: Remove unused packages.
package:
name:
- nano
- sendmail
state: absent
# File permissions.
- name: Configure the permissions for the messages log.
file:
path: /var/log/messages
owner: root
group: root
mode: 0600
# Automating updates for RHEL systems.
- name: Install dnf-automatic.
yum:
name: dnf-automatic
state: present
- name: Ensure dnf-automatic is running and enabled on boot.
service:
name: dnf-automatic-install.timer
state: started
enabled: yes
# Automating updates for Debian systems.
- name: Install unattended upgrades package.
apt:
name: unattended-upgrades
state: present
when: ansible_os_family == 'Debian'
- name: Copy unattended-upgrades configuration files in place.
template:
src: "../templates/{{ item }}.j2"
dest: "/etc/apt/apt.conf.d/{{ item }}"
owner: root
group: root
mode: 0644
with_items:
- 20auto-upgrades
- 50unattended-upgrades
when: ansible_os_family == 'Debian'
# Configuring a firewall with `firewalld` on RHEL.
- name: Ensure firewalld is running.
service:
name: firewalld
state: started
- name: Configure open ports with firewalld.
firewalld:
state: "{{ item.state }}"
port: "{{ item.port }}"
zone: external
immediate: yes
permanent: yes
with_items:
- { state: 'enabled', port: '22/tcp' }
- { state: 'enabled', port: '80/tcp' }
- { state: 'enabled', port: '123/udp' }
# Monitor logins and block suspect IP addresses.
- name: Ensure EPEL repo is present.
yum:
name: epel-release
state: present
when: ansible_os_family == 'RedHat'
- name: Install fail2ban (RedHat).
yum:
name: fail2ban
state: present
enablerepo: epel
when: ansible_os_family == 'RedHat'
- name: Install fail2ban (Debian).
apt:
name: fail2ban
state: present
when: ansible_os_family == 'Debian'
- name: Ensure fail2ban is running and enabled on boot.
service:
name: fail2ban
state: started
enabled: yes
# Use SELinux (Security-Enhanced Linux).
- name: Install Python SELinux library.
yum:
name: python3-libselinux
state: present
- name: Ensure SELinux is enabled in `targeted` mode.
selinux:
policy: targeted
state: enforcing
- name: Ensure httpd can connect to the network.
seboolean:
name: httpd_can_network_connect
state: yes
persistent: yes
when: ansible_selinux.status == 'enabled'
==== change /etc/rc.tcpip ====
# cat update_rc_tcpip.yml
- name: Update /etc/rc.tcpip
gather_facts: no
hosts: ALL
#########################################################################################################
# Latest version date 06/10/2022
#########################################################################################################
# Playbook will comment line "sendmail ..."
#########################################################################################################
tasks:
- name: Comment line begining with time_last_login
ansible.builtin.lineinfile:
path: /etc/rc.tcpip
regexp: '^start /usr/lib/sendmail'
line: '#start /usr/lib/sendmail "$src_running" "-bd -q${qpi}"'
backup: yes
firstmatch: yes
backrefs: yes
register: results
- name: Restart tcpip demon group if file modified
shell: "/usr/sbin/refresh -g tcpip"
when: results.changed == true