This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
ansible:ansible_cmd [2021/09/14 12:32] manu |
ansible:ansible_cmd [2024/04/19 12:26] (current) manu [All ansible commands] |
||
---|---|---|---|
Line 1: | Line 1: | ||
====== Ansible command examples ====== | ====== 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 ===== | ===== cmd ===== | ||
- | <cli> | + | <cli prompt='#'> |
- | ansible all -m ping | + | # ansible all -m ping |
- | ansible foo.example.com -m yum -a "name=httpd state=installed" | + | # ansible -vvv -i "node1," all -u user1 -m ping # debug |
- | ansible -i hosts all -m yum -a 'name=ncdu state=present' | + | # ansible foo.example.com -m yum -a "name=httpd state=installed" |
- | ansible -i hosts all -m yum -a 'name=ncdu state=absent' | + | # ansible -i hosts all -m yum -a 'name=ncdu state=present' |
- | ansible foo.example.com -a "/usr/sbin/reboot" | + | # 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" | ||
</cli> | </cli> | ||
+ | Commands modules for **ansible** | ||
+ | command | ||
+ | expect | ||
+ | psexec (for windows) | ||
+ | raw | ||
+ | script | ||
+ | shell | ||
+ | telnet | ||
+ | | ||
+ | |||
Only way to pass a command on target without python installed | Only way to pass a command on target without python installed | ||
<cli prompt='#'> | <cli prompt='#'> | ||
Line 35: | Line 78: | ||
aix01 | SUCCESS => {"changed": false,"ping": "pong"} | aix01 | SUCCESS => {"changed": false,"ping": "pong"} | ||
aix20 | SUCCESS => {"changed": false,"ping": "pong"} | aix20 | SUCCESS => {"changed": false,"ping": "pong"} | ||
+ | </cli> | ||
+ | |||
+ | <cli prompt='$'> | ||
+ | $ 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" | ||
+ | } | ||
+ | </cli> | ||
+ | |||
+ | |||
+ | |||
+ | File conversion: | ||
+ | <cli prompt='#'> | ||
+ | [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" | ||
+ | ] | ||
+ | } | ||
+ | } | ||
+ | </cli> | ||
+ | |||
+ | <cli prompt='#'> | ||
+ | [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: {} | ||
</cli> | </cli> | ||
===== playbook ===== | ===== playbook ===== | ||
+ | |||
+ | ==== Copy file ==== | ||
+ | |||
+ | <cli prompt='#'> | ||
+ | # 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' }}" | ||
+ | </cli> | ||
+ | |||
+ | ==== Firewalld ==== | ||
+ | |||
+ | <cli prompt='#'> | ||
+ | # 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' | ||
+ | </cli> | ||
+ | |||
+ | |||
+ | ==== Security ==== | ||
+ | |||
+ | <cli prompt='#'> | ||
+ | --- | ||
+ | - 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' | ||
+ | </cli> | ||
+ | |||
+ | ==== change /etc/rc.tcpip ==== | ||
+ | |||
+ | <cli prompt='#'> | ||
+ | # 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 | ||
+ | </cli> | ||