[toc] ### Ansible Playbooks #### Playbook components ![](https://i.imgur.com/KAOQXqR.png) #### ping.yaml :::warning vi ping.yaml ``` --- ## Using playbook to check cluster health - hosts: all tasks: - name: Ping all nodes in the cluster action: ping ``` Run the playbook via the following command: ansible-playbook ping.yaml ::: #### elinks.yaml :::warning vi elinks.yaml ``` --- ## Using playbook to install elinks package - hosts: all become: yes tasks: - name: install elinks apt: name: elinks update_cache: yes state: present ``` Run the playbook via the following command: ``` ansible-playbook ping.yaml ``` Validation: ``` ansible all -m shell -a 'which elinks' ``` ::: #### vars1.yaml :::warning vi vars.yaml ``` --- ## Using playbook to install package via variables - hosts: all become: yes tasks: - name: install the specified package apt: name: '{{ package }}' state: present ``` Run the playbook via the following command: ``` ansible-playbook vars.yaml --extra-vars 'package=tree' or ansible-playbook vars.yaml -e 'package=tree' ``` Validation: ``` ansible all -m shell -a 'which tree' ``` ::: #### vars2.yaml :::warning vi vars2.yaml ``` --- ## Using playbook to install package via variables - hosts: '{{ myhosts }}' become: yes tasks: - name: install the specified package apt: name: '{{ package }}' state: present ``` Run the playbook via the following command: ``` ansible-playbook vars.yaml --extra-vars 'package=tree myhosts=nodes' or ansible-playbook vars.yaml -e 'myhosts=nodes package=tree' ``` Validation: ``` ansible all -m shell -a 'which tree' ``` ::: #### user.yaml :::warning vi user.yaml ``` --- ## Playbook to create user on remote nodes - hosts: all become: yes tasks: - name: create users user: name: sk12k home: /home/sk12k password: mysupersecurepassword ``` Run the playbook via the following command: ``` ansible-playbook user.yaml ``` Validation: ``` ansible all -m shell -a 'id sk12k' ``` Expected Output: ``` localhost | CHANGED | rc=0 >> uid=1002(sk12k) gid=1002(sk12k) groups=1002(sk12k) worker2 | CHANGED | rc=0 >> uid=1002(sk12k) gid=1002(sk12k) groups=1002(sk12k) worker1 | CHANGED | rc=0 >> uid=1002(sk12k) gid=1002(sk12k) groups=1002(sk12k) ``` ::: #### prehash.yaml :::warning Create a hash for a password ``` openssl passwd -6 <password> ``` Write the Playbook with the hashed password vi prehash.yaml ``` --- ## Playbook to create user on remote nodes - hosts: all become: yes tasks: - name: create users user: name: sk12k home: /home/sk12k password: "$6$axdk8t1vkV34WU9e$aXkPt4iCV8IQaXvLWpF45bp3wYHAiew99jBR6dy5D/wNjUqCNHAYEPeAIDPteDGNCM5wi919uBo4ta7UqeXdp." ``` Run the playbook via the following command: ``` ansible-playbook user.yaml ``` Validation: ``` su - <username> ``` :arrow_right: *Put in the password when prompted. If you are able to successfully switch user that means your playbook with hashed value worked.* ::: #### userhash.yaml :::warning Write the Playbook with the hashed password vi userhash.yaml ``` --- ## Playbook to create user on remote nodes - hosts: all become: yes gather_facts: yes tasks: - name: create users user: name: sk14k home: /home/sk14k password: "{{ 'Passw0rd' | password_hash('sha512', 'mysalt') }}" ``` Run the playbook via the following command: ``` ansible-playbook userhash.yaml ``` Validation: ``` su - <username> ``` :arrow_right: *Put in the password when prompted. If you are able to successfully switch user that means your playbook with hashed value worked.* ::: #### loop.yaml :::warning vi loop.yaml ``` --- ## Using playbook to install multiple packages - hosts: all become: yes tasks: - name: install elinks apt: name: "{{item}}" state: present loop: - tree - git - elinks - telnet - screen - net-tools - nodejs ``` Run the playbook via the following command: ``` ansible-playbook loop.yaml ``` Validation: ``` which tree which screen ifconfig node -v ``` ::: #### loopuser.yaml :::warning vi loopuser.yaml ``` --- ## Playbook to create specified users on all nodes - hosts: all become: yes tasks: - name: Create specified users on all nodes user: name: sk12k ``` Run the playbook via the following command: ``` ansible-playbook loop.yaml ``` Validation: ``` which tree which screen ifconfig node -v ``` ::: #### useritems.yaml :::warning **Create multiple users with their own home directories** ##### Solution 1: ``` --- ## Playbook to create specified users on all nodes along with their own home directories - hosts: all become: yes tasks: - name: Create specified users on all nodes user: name: "{{item}}" home: /home/"{{item}}" loop: - cnst1 - cnst2 - cnst3 - cnst4 - cnst5 ``` ##### Solution 2: ``` --- ## Playbook to create specified users on all nodes along with their own home directories - hosts: all become: yes tasks: - name: Create specified users on all nodes user: name: "{{item.user}}" home: "{{item.homedir}}" password: Passw0rd with_items: - user: dba1 homedir: /home/dba1 - user: dba2 homedir: /home/dba2 - user: dev1 homedir: /home/dev1 - user: dev2 homedir: /home/dev2 ``` ::: #### handler.yaml :::warning **This Playbook will do the following:** - Install apache2 software - Create an index.html - Make sure apache2 service is up and running vi handler.yaml ``` --- ## Playbook to install and configure Apache - hosts: nodes become: yes tasks: - name: install apache ## Apache installation apt: name: apache2 state: present - name: Upload index file. ## copy index.html file from controller to all web nodes copy: src: index.html dest: /var/www/html/index.html mode: 0755 notify: start the apache2 service handlers: - name: start the apache2 service ## make sure the service is up and running service: name: apache2 state: restarted ``` Run the playbook: ``` ansible-playbook handler.yaml ``` Validation: ``` curl localhost elinks http://localhost ## commandline ipaddress ## on any other environment such as AWS, DigitalOcean ``` ::: :::info :arrow_right: *If you face problem with Cache update, try killing the process (id mentioned in the error message) by using the following command:* Syntax: ``` sudo kill -9 <process-id> ``` Example: ``` sudo kill -9 151360 ``` ::: ##### Sample index.html ````html= <!DOCTYPE html> <html> <head> <title>CMAT</title> <style> body { background-color: lightyellow; } </style> </head> <body> <h1>Welcome to Ansible and Terraform session</h1> <h2>We are learning Configuration Management and I-a-C</h2> </body> </html> ```` #### facts.yaml :::warning vi facts.yaml ``` --- ## Playbook to show how to use facts in Ansible - name: using-facts hosts: nodes become: yes tasks: - name: workerA folder command: mkdir /tmp/workerA when: ansible_facts['hostname'] == 'workerA' - name: controller folder command: mkdir /tmp/controller when: ansible_facts['hostname'] == 'Controller' ``` Run the playbook: ``` ansible-playbook facts.yaml ``` Validate: ``` ansible all -m shell -a 'ls /tmp' ``` ::: #### apache-conditional.yaml :::warning vi apache-conditional.yaml ``` --- ## Playbook to install Apache on both Debian and Redhat systems - hosts: nodes become: yes tasks: - name: Apache on Debian when: ansible_facts['os_family'] == "Debian" ansible.builtin.package: name: apache2 state: present - name: Apache on RedHat when: ansible_facts['os_family'] == "RedHat" ansible.builtin.package: name: httpd state: present ``` ::: ### References :::info - https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_intro.html - https://www.middlewareinventory.com/blog/ansible-playbook-example/#Ansible_Copy_SSH_Keys_between_remote_servers_example - https://www.cloudnweb.dev/2019/04/ansible-password-less-ssh-playbook/ - https://www.authgear.com/post/password-hashing-salting - https://www.okta.com/uk/blog/2019/03/what-are-salted-passwords-and-password-hashing/ - https://lindevs.com/generate-password-hash-using-openssl - Vulnaribility Management - CVE - Security Automation - Relative and absolute path in Linux - https://cve.mitre.org/cgi-bin/cvename.cgi?name=cve-2021-44228 - [Sudo without Password in Ubuntu](https://www.cyberciti.biz/faq/linux-unix-running-sudo-command-without-a-password/) - :::