Day 58 - Ansible Playbooks

Day 58 - Ansible Playbooks

Ansible playbooks run multiple tasks, assign roles, and define configurations, deployment steps, and variables. If you’re using multiple servers, Ansible playbooks organize the steps between the assembled machines or servers and get them organized and running in the way the users need them to. Consider playbooks as the equivalent of instruction manuals.

Task-01

Write an Ansible playbook to create a file on a different server

Before proceeding to the playbooks, we need to setup Ansible Master and Host nodes

Connect to the Ansible Master, install Ansible and configure the host nodes in the inventory host file.

$ sudo nano /etc/ansible/hosts

I configured host Publics IPs as server_1 and server_2 and also mentioned the pem key location

# Check the connection status of Host node
$ sudo ansible all -m ping
$ sudo ansible server_1:server_2 -m ping

Ansible is set up successfully. Let's start writing some playbooks.

📂 File Creation Playbook

Imagine you need to create a file on multiple servers simultaneously. Instead of connecting to each server individually, you can use an Ansible playbook to perform this task seamlessly. Here's an example playbook to create a file named "file.txt" on a group of servers:

---
- name: This playbook will create a file
  hosts: all
  become: true
  tasks:
  - name: Create a file
    file:
     path: /home/ubuntu/file.txt
     state: touch
  • The name field describes the playbook.

  • hosts specify the target hosts or groups of hosts where the tasks will be executed.

  • become: true ensure the tasks are executed with administrative privileges.

  • tasks define a list of tasks to be performed, and each task consists of a name and a module (in this case, the file module).

  • The file module is used with the path parameter to specify the file path and the state parameter to indicate that the file should be created (touched).

      # Command to check the syntax of playbook
      $ ansible-playbook <playbook file name> --syntax-check
    
      # Command to run the playboook.yml
      $ ansible-playbook <playbook file name>
    

Verify that the file has been created on different servers

$ ansible all -m shell -a "ls /home/ubuntu" -i <inventory-file> --private-key=<key-path>
$ ansible all -m shell -a "ls /home/ubuntu"

Playbook to create a new user 👤

---
- name: this playbook will create a user
  hosts: all
  become: true
  tasks:
  - name: Create a user named Devops
    user: name=Devops
  • The user module is used to create the user account.

  • The name parameter specifies the username.

      # Command to check the syntax of playbook
      $ ansible-playbook <playbook file name> --syntax-check
    
      # Command to run the playboook.yml
      $ ansible-playbook <playbook file name>
    

To check whether the user is created, you can login to the hosts machines and check by using cat /etc/passwd command or

Use the below Ansible command in the Ansible master

# Command to check all the users in all servers
$ ansible all -m shell -a "cat /etc/passwd"

# Command to check users in a particular server
$ ansible server_1 -m shell -a "cat /etc/passwd"

Playbook to install docker 🐳 on a group of servers

---
- name: This playbook will install Docker
  hosts: all
  become: true
  tasks:
  - name: Add Docker GPG apt Key
    apt_key:
     url: https://download.docker.com/linux/ubuntu/gpg
     state: present

  - name: Add Docker Repository
    apt_repository:
     repo: deb https://download.docker.com/linux/ubuntu focal stable
     state: present

  - name: Install Docker
    apt:
     name: docker-ce
     state: latest
  • The apt_key module is used to add the Docker GPG apt key.

  • The apt_repository module is used to add the Docker repository.

  • The apt module is used to install the latest version of Docker.

      # Command to check the syntax of playbook
      $ ansible-playbook <playbook file name> --syntax-check
    
      # Command to run the playboook.yml
      $ ansible-playbook <playbook file name>
    

Use to below commands to check the Docker -version in hosts machine

Command to check docker version in all servers
$ ansible all -m shell -a "docker --version"

# Command to check docker version in a particular server
$ ansible server_1 -m shell -a "docker --version"

Task-02

Declaring Variables in Playbook at Run time for playbook

---
- name: This playbook will install httpd package
  hosts: all
  become: true
  tasks:
    - name: install httpd package
      apt:
        name: "{{package_name}}"
        state: latest
    - name: start httpd server
      service:
        name: "{{package_name}}"
        state: started

The yaml file does not have a package name that needs to be installed

By using the below command we are declaring a variable (package name) at run time of the playbook.yaml file

$ ansible-playbook playbook.yaml --extra-vars “package_name=httpd”

Variables declared in the playbook itself

---
- name: This playbook will install httpd package
  hosts: all
  become: true
  vars:
   package_name: httpd
  tasks:
    - name: install httpd package
      apt:
        name: "{{package_name}}"
        state: latest
    - name: start httpd server
      service:
        name: "{{package_name}}"
        state: started

Use variables:

Variables can make your playbook more flexible and reusable. They allow you to store values that can be used across multiple tasks and playbooks. You can define variables in the playbook itself or separate files, such as group_vars or host_vars.

- name: Install Nginx web server
  apt:
    name: nginx
    state: latest

- name: Configure Nginx web server
  template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
  vars:
    nginx_port: 80

In this example, we are using a variable nginx_port to define the port number used by Nginx. The variable is defined in the vars section of the template task.

Handlers and tags

Ansible provides feature named handlers, which is like a task but will only run when called by a notifier in another task. This feature is important because your requirements for running a task may depend on the state of a service, the existence of a file or follow-up tasks when the state changed.

If you have a large playbook, it may be useful to run only specific parts of it instead of running the entire playbook. You can do this with Ansible tags. Using tags to execute or skip selected tasks is a two-step process:

  1. Add tags to your tasks, either individually or with tag inheritance from a block, play, role, or import.

  2. Select or skip tags when you run your playbook

- hosts: all
  become: true
  gather_facts: no
  vars:
    package_name: httpd
  tasks:
    - name: install httpd
      apt:
        name: "{{package_name}}"
        state: present
      tags:
        - install
    - name: Copy index.html
      copy:
        src: index.html
        dest: /var/www/html/
      tags:
          - copy
      notify:
        Start Httpd Server
  handlers:
    - name: Start Httpd Server
      service:
        name: "{{package_name}}"
        state: started
$ ansible-playbook filename.yaml --tags "install"

By this command, we can only run the installation step of httpd

Use roles:

Roles are a way to organize your tasks, variables, and files into reusable components. They can be used across multiple playbooks and provide a way to share functionality between different teams. Roles can also make your playbook more modular and easier to maintain.

How do we create Ansible roles?

To create an Ansible role, use the ‘ansible-galaxy’ command which has the templates

$ sudo su ansible

$ cd /home/ansible

$ mkdir roles

$ ansible-galaxy init roles/apache

-> where, ansible-galaxy is the command to create the roles using the templates

-> init is to initialize the role

-> Apache is the name of the role

List out the directory created under /etc/ansible/roles

$ sudo yum install tree

$ tree roles/apache/

Watch this video to learn about ansible Playbooks

https://github.com/rjthapaa/ansible_playbooks_samples