Skip to content

Ansible Coding Conventions

John Jarvis edited this page Jul 18, 2013 · 20 revisions

Coding Conventions

Conditionals and return status

Always use the when: for conditionals

  • To check if a variable is defined when: my_var is defined or when: my_var is not defined
  • To verify return status
 - command: /bin/false
    register: my_result
    ignore_errors: True
  - debug: msg="task failed"
    when: my_result|failed

Also see conditional execution

Module arguments

Option 1 - On a single line

This is the preferred method, there is no need for quotes around the string after debug:

YES

  - debug: msg={{ test }}

OK but not necessary

  - debug: "msg={{ test }}"

INVALID

  - debug: msg="{{ test }}"

Option 2 - Use YAML line continuations to break long lines

  - debug: >
      msg={{ test }}

Option 3 - Hash syntax

Use a nested hash to pass complex arguments Quotes are required for variables.

YES

  - debug:
      msg: "{{ test }}"

INVALID

  - debug:
      msg: {{ test }}

General

  • YAML files - All yaml files should use 2 space indents and end with .yml

  • Variables - Use jinja variable syntax over deprecated variable syntax

  • Keep roles self contained - Roles should avoid including tasks from other roles when possible

  • Plays should do nothing more than include a list of roles except where pre_tasks and post_tasks are required (to manage a load balancer for example)

  • Plays/Playbooks that apply to the general community should be copied to configuration/playbooks

  • Plays/Playbooks that apply only to a specific organization (edx-east, edx-west) should be copied to a sub-directory under configuration/playbooks

  • Variable overrides - Some variables are only used as command-line overrides using the "-e" option, for these the convention is to prefix them with c_

  • Tests - For automated integration tests every role should contain a test.yml file that is included and run when a run_tests var is set to validate the role installation on a single instance.

  • Deploys - Every role should have a deploy.yml with a list of tasks that start with service stop and end with a service start that is run to deploy an application update.

  • Handers - Every role should have one or more handler for restarting the service(s), for tasks that run in main.yml that require service restarts they/it will be notified.

  • Tags - Every task in deploy.yml should be tagged with deploy

Roles

  • group_vars/all - Contains variable definitions that apply to all roles.
  • "common" role - Contains variables and tasks that apply to all roles.
  • Roles variables - Variables specific to a role should be defined in /vars/main.yml. All variables should be prefixed with the role name.
  • Role defaults - Default variables should configure a role to install edx in such away that all services can run on a single server
  • Role names - Terse, one word, no underscores and start with a lowercase letter.
  • Role task names - Terse, descriptive, spaces are OK and should be prefixed with the role name.
  • Role handlers - Terse, descriptive, spaces are OK and should be prefixed with the role name

Secure vs. Insecure data

As a general policy we want to protect the following data:

  • Usernames
  • Public keys (keys are OK to be public, but can be used to figure out usernames)
  • Hostnames
  • Passwords, API keys

The following yml files and examples serve as templates that should be overridden with your own environment specific configuration:

  • vars in secure_example/vars
  • files in secure_example/files

Directory structure for the secure repository:


ansible
├── files
├── keys
└── vars

The same directory structure, required yml files and files are in the secure_example dir:

secure_example/
├── files
├── keys
└── vars

The default secure_dir is set in group_vars/all and can be overridden by adding another file in group_vars that corresponds to a deploy group name.

The directory structure should follow Ansible best practices.

http://ansible.cc/docs/bestpractices.html

  • At the top level there are yml files for every group where a group name is an identifier that corresponds to a set of roles plus an environment.
  • The standard environments are stage and production.
  • Additional environments can be named as well, below an example is given called custom.