Ansible – Ansible Roles (Part-9)

Posted by

What is an Ansible Role?

An Ansible role is a way to group multiple tasks, variables, handlers, files, templates, and other resources into a reusable and structured format. Roles provide a method to organize playbooks into separate, independent, and reusable components. This modular approach enhances readability, maintainability, and scalability of Ansible projects.

Creating roles using Ansible Galaxy is a streamlined process. Ansible Galaxy is a command-line tool bundled with Ansible that helps you create, share, and manage roles. Here’s a step-by-step guide to creating roles using Ansible Galaxy:

Step-by-Step Guide to Creating Roles

Create a New Role

Use the ansible-galaxy command to create a new role. Replace role_name with the desired name of your role.

ansible-galaxy init role_name

This command creates a directory structure for the role:

role_name/
├── README.md
├── defaults
│   └── main.yml
├── files
├── handlers
│   └── main.yml
├── meta
│   └── main.yml
├── tasks
│   └── main.yml
├── templates
├── tests
│   ├── inventory
│   └── test.yml
└── vars
    └── main.yml

Key Components of an Ansible Role

  1. TasksTasks are the main workhorse of a role. They define the steps to be executed. Tasks are stored in tasks/main.yml.
# roles/role_name/tasks/main.yml
---
- name: Install Apache
  ansible.builtin.apt:
    name: apache2
    state: present

- name: Start Apache service
  ansible.builtin.service:
    name: apache2
    state: started

2.Handlers

Handlers are special tasks that are triggered by the notify directive. They are stored in handlers/main.yml.

# roles/role_name/handlers/main.yml
---
- name: Restart Apache
  ansible.builtin.service:
    name: apache2
    state: restarted

3.Templates

Templates are files that can be dynamically generated based on variables. They are stored in the templates directory.

Template Example (templates/index.html.j2):

<html>
<head>
    <title>Welcome to {{ ansible_hostname }}</title>
</head>
<body>
    <h1>Welcome to {{ ansible_hostname }}</h1>
</body>
</html>

4.Files

The files directory contains static files that are transferred to the managed hosts.

File Example (files/motd):

Welcome to our server!

5.Variables

Variables can be defined at two levels:

  • Default Variables (defaults/main.yml): These are the default values which can be overridden.
  • Role Variables (vars/main.yml): These are role-specific variables.

Default Variables Example (defaults/main.yml):

# roles/role_name/defaults/main.yml
---
apache_port: 80

Role Variables Example (vars/main.yml):

# roles/role_name/vars/main.yml
---
apache_port: 8080

Meta

The meta/main.yml file defines metadata about the role, such as its dependencies.

Meta Example (meta/main.yml):

# roles/role_name/meta/main.yml
---
dependencies:
  - { role: common, some_parameter: 3 }

LibraryThe library directory can contain custom modules that can be used in your role.

TestsThe tests directory is used to store test playbooks and inventory files to test the role.Test Playbook Example (tests/test.yml):

# roles/role_name/tests/test.yml
---
- name: Test Role
  hosts: localhost
  roles:
    - role_name

    Using Roles in a Playbook

    Once you have defined a role, you can use it in a playbook as follows:

    Example Playbook (site.yml):

    ---
    - name: Apply common configuration to all nodes
      hosts: all
      roles:
        - common
    
    - name: Configure web servers
      hosts: webservers
      roles:
        - role_name
    

    Example: Creating and Using a Role

    Let’s create a role named webserver to install and configure Apache.

    Create the Role Directory Structure:

    ansible-galaxy init webserver

      Define Tasks:

      roles/webserver/tasks/main.yml:

      ---
      - name: Install Apache
        ansible.builtin.apt:
          name: apache2
          state: present
      
      - name: Deploy the index.html file
        ansible.builtin.template:
          src: index.html.j2
          dest: /var/www/html/index.html
        notify:
          - Restart Apache
      
      - name: Ensure Apache is running
        ansible.builtin.service:
          name: apache2
          state: started
      

      Define Handlers:

      roles/webserver/handlers/main.yml:

      ---
      - name: Restart Apache
        ansible.builtin.service:
          name: apache2
          state: restarted
      

      Create a Template:

      roles/webserver/templates/index.html.j2:

      <html>
      <head>
          <title>Welcome to {{ ansible_hostname }}</title>
      </head>
      <body>
          <h1>Welcome to {{ ansible_hostname }}</h1>
      </body>
      </html>
      

      Define Default Variables:

      roles/webserver/defaults/main.yml:

      ---
      apache_port: 80
      

      Use the Role in a Playbook:

      site.yml:

      ---
      - name: Configure web servers
        hosts: webservers
        become: yes
        roles:
          - webserver
      

      Run the Playbook:

      ansible-playbook -i inventory site.yml

      Ansible roles provide a powerful way to organize and reuse your automation code. By structuring your playbooks into roles, you can manage complex environments more effectively, ensuring consistency and maintainability. Roles encapsulate tasks, handlers, templates, files, variables, and other resources, making it easier to share and reuse configurations across multiple projects and teams. Understanding how to create and use roles is essential for building scalable and maintainable Ansible-based automation solutions.

      Example: Creating an nginx Role

      Let’s create a role named nginx to install and configure Nginx.

      Create the Role:

      ansible-galaxy init nginx

        Define Tasks:

        roles/nginx/tasks/main.yml:

        ---
        - name: Install Nginx
          ansible.builtin.apt:
            name: nginx
            state: present
        
        - name: Start Nginx service
          ansible.builtin.service:
            name: nginx
            state: started
        

        Define Handlers:

        roles/nginx/handlers/main.yml:

        ---
        - name: Restart Nginx
          ansible.builtin.service:
            name: nginx
            state: restarted

        Create a Template:

        roles/nginx/templates/nginx.conf.j2:

        server {
            listen 80;
            server_name {{ server_name }};
        
            location / {
                proxy_pass http://{{ proxy_pass }};
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
            }
        }
        

        Add Variables:

        roles/nginx/defaults/main.yml:

        ---
        server_name: localhost
        proxy_pass: 127.0.0.1:8080
        

        Update Meta Information:

        roles/nginx/meta/main.yml:

        ---
        galaxy_info:
          role_name: nginx
          author: your_name
          description: Install and configure Nginx
          company: your_company
          license: MIT
          min_ansible_version: 2.9
          platforms:
            - name: Ubuntu
              versions:
                - bionic
                - focal
        dependencies: []
        

        Test the Role:

        roles/nginx/tests/test.yml:

        ---
        - name: Test nginx role
          hosts: localhost
          roles:
            - nginx
        

        Run the test playbook:

        ansible-playbook roles/nginx/tests/test.yml
        

        Live Practices

        root@Jami2:/home/jami# ansible-galaxy init webserver
        - Role webserver was created successfully
        ls 
        tree
        ├── webserver
        │   ├── defaults
        │   │   └── main.yml
        │   ├── files
        │   ├── handlers
        │   │   └── main.yml
        │   ├── meta
        │   │   └── main.yml
        │   ├── README.md
        │   ├── tasks
        │   │   └── main.yml
        │   ├── templates
        │   ├── tests
        │   │   ├── inventory
        │   │   └── test.yml
        │   └── vars
        │       └── main.yml
        

        vi webserver/defaults/main.yml

            myname: "Rajesh Kumar"
            port: 81

        webserver/files/index.html

        Ansible variable
        

        webserver/templates/ports.conf.j2

        
        Listen {{port}}
        
        <IfModule ssl_module>
                Listen 443
        </IfModule>
        
        <IfModule mod_gnutls.c>
                Listen 443
        </IfModule>
        

        webserver/tasks/main.yml

          - name: Install Apache in Ubuntu
            ansible.builtin.apt:
              name: apache2
              state: latest
          - name: Copy index.html
            ansible.builtin.copy:
              src: /home/jami/index.html
              dest: /var/www/html/index.html
          - name: Starting a Apache Server
            ansible.builtin.service:
              name: apache2
              state: started
          - name: Template for httpd.conf
            template:
              src:  /home/jami/ports.conf.j2
              dest: /etc/apache2/ports.conf
            notify:
              - ReStarting a Apache Server

        vi webserver/handlers/main.yml

          - name: ReStarting a Apache Server
            ansible.builtin.service:
              name: httpd
              state: restarted

        vi webserver/meta/main.yml

        galaxy_info:
          author: jami
        description: your role description
          company: your company (optional)
        
          # If the issue tracker for your role is not on github, uncomment the
          # next line and provide a value
          # issue_tracker_url: http://example.com/issue/tracker
        
          # Choose a valid license ID from https://spdx.org - some suggested licenses:
          # - BSD-3-Clause (default)
          # - MIT
          # - GPL-2.0-or-later
          # - GPL-3.0-only
          # - Apache-2.0
          # - CC-BY-4.0
          license: license (GPL-2.0-or-later, MIT, etc)
        
          min_ansible_version: 2.1
        
          # If this a Container Enabled role, provide the minimum Ansible Container version.
          # min_ansible_container_version:
        
          #
          # Provide a list of supported platforms, and for each platform a list of versions.
          # If you don't wish to enumerate all versions for a particular platform, use 'all'.
          # To view available platforms and versions (or releases), visit:
          # https://galaxy.ansible.com/api/v1/platforms/
        

        Ansible galaxy – having roles developed by developer

        https://galaxy.ansible.com/ui/standalone/roles/geerlingguy/java/install/
        ansible-galaxy role install geerlingguy.java

        Run roles via below script (currently I have two roles one web and another geerlingguy.java

        run below to check role list

        ansible-galaxy role list
        root@Jami2:/home/jami# ansible-galaxy role list
        # /root/.ansible/roles
        - geerlingguy.java, 2.5.0
        # /etc/ansible/roles
        

        site.yaml

        ---
        - name: Update web servers
          hosts: web
        
          roles:
            -webserver
            -geerlingguy.java

        Run ansible playbook

         ansible-playbook -i inventory /home/jami/site.yaml -u jami -k -b
        

        As am running on remote server on various server so using inventory in above command

        guest
        0 Comments
        Inline Feedbacks
        View all comments
        0
        Would love your thoughts, please comment.x
        ()
        x