Welcome to Rule of Clarity: Applied to Infrastructure as Code, in this post I am going to go over the rule of clarity, and why it's important to your scripts, playbooks, modules and recipes.

What is the Rule of Clarity?
Simply put, the rule of clarity tells us that we should be writing code for communication to ourselves and other developers, and we should not be writing code for cleverness or looking cool with some obscure function.

When writing functions or components or roles or any piece of code, you should be writing for clarity in that you should never trade off a small performance gain for obscurity and complexity.

You should strive to write your code to be read like a book. You can start reading that book and gain context about the topic fairly quickly. You should understand the story your code is trying to tell you when finished.

Having easy to read and understand code is much easier to debug and maintain than overly complex and clever code. If you're reading and re-reading your code after coming back to it or another developer is doing the same to your code... It's time to consider refactoring it into something a bit clearer.

If there is no way around the complexity of a function and a deadline is looming, then this is where comments can help, but comments are not a crutch for poor naming and clearly written code.

Self-Documenting Code

To me, code should also be self-documenting, comments are fine, but they often become stale and outdated. Some people tend to put a lot of effort into their code comments with little regard into the code itself.

While the below are extremely oversimplified bash examples, the difference in the two is clear. If I come back months later to code that is written in the style of the first example, it will take me a lot longer to get a solid understanding of what is happening vs the second example, where I can get up to speed a lot quicker.


#Not Self-Documenting:
for X in myFile; do  
  # do something with ${X} ...
done  
# Self-Documenting:
for HOSTNAME in hostInventory; do  
  # do something with ${HOSTNAME} ...
done  


Name With Meaning

If you have been following along, then you know I do not advocate one tool over another, but prefer to adhere to a set of principles. This is not a comparison of ansible vs puppet vs salt vs chef. However, this is to demonstrate, that no matter your choice of configuration management, you need to give your variables meaning.

Ansible

  config_file_path:  '/etc/nginx/nginx.conf'
  config_file_mode:  '0644'
  config_file_owner: 'nginx'
  config_file_group: 'nginx'

Puppet

  $config_file_path  = '/etc/nginx/nginx.conf'
  $config_file_mode  = '0644'
  $config_file_owner = 'nginx'
  $config_file_group = 'nginx'

Notice this is a common sense approach. Config File Path is a lot clearer than say Path, path to what? Variable length shouldn't matter and should be clear and descriptive. This is self-documenting. You will not require superfluous comments peppered throughout your code when your code speaks for itself.

comments are no excuse for poor naming

This does not just apply to variables, but names of roles and components. This applies to everything that you provide a name for. Do not simply name something off the top of your head or provide a temporary name only to forget its purpose down the road.

When we go into the Rule of Least Surprise, this will become clearer as when names provide meaning, it's easier on the consumers of your automation as well, not just on the developers.