Welcome to Rule of Modularity, Part II. Now, that we have a basic understanding of what to do when faced with a monolithic playbook/module/recipe. We can start to take a bit of a deeper look at how we could take some existing automation and refactor it to be more modular.

I believe that these rules apply to not just automation, but any type of scripting or programming you may do. So when it comes to automation, it certainly doesn't matter if you're a Puppet Master, a 4-Star Chef, an Ansible Machine or a Salt Aficionado. The battle of configuration management tools is not even a debate in my opinion.

A tool is only as good as it's implementation, and it's ability to be maintained easily throughout its lifecycle, and consumed by the technical and non-technical alike. Maintenance of a complex code base is extremely time-consuming, difficult and downright a displeasure to work in.

Components V.S. Roles

To best determines how to break apart a monolithic playbook/module/recipe is to take a step back and think about what you're trying to accomplish. What I mean is you need to determine if what you're working on is a component level playbook/module/recipe, or a role level playbook/module/recipe.

NOTE: Not to be confused with Ansible Roles

A component; is a piece of reusable and flexible code. It does one thing and does it well. It can be used by itself or in combination with another or many components.

A role; is a collection of components. It takes little to no action on its own but is simply the conductor of the collection of components. Each component plays its own instrument, and its the job of the role (conductor) to orchestrate the components into a symphony.

Component Examples

Some examples of components level playbooks/modules/recipes might be;

  • SSH
  • SMTP
  • PAM
  • SELinux
  • Kernel Tuning
  • Repository Management
  • NGINX / Apache
  • An Interpreter (Ruby/Python)
  • HAProxy
  • Java
  • Tomcat
Role Examples

Some examples of role level playbooks/modules/recipes might be:

  • A LAMP Stack:
    • A Common Linux component, Apache component, MySQL component, PHP component
  • Java Application:
    • Java of a given version, Tomcat component, The Application, A directory structure, Kernel Tuning component, A service account
  • A Database Cluster:
    • 3 Mongo Instances in a replica set, An Arbiter, A user, Kernel Tuning
  • A Webserver Cluster
    • n+ webservers, ha proxy, a user(s)
  • A Rails Application
    • A rails server like unicorn, a web server, a user, ruby
  • An Initial OS Build
    • Commonly installed packages, SA accounts, Your build standards

So, it should be easy to see how roles utilize components to create the bigger picture. This allows for you to easily rip out and replace small components in the role instead of a big refactoring effort to change a small bit of functionality that may be added or removed.

In part III of Modularity, we will look at a practical example of a monolithic playbook/module/recipe and how to refactor it for a modular approach and identify the components involved.

In Rule of Composition, we will take these components and assemble a meaningful role.