guidelines structure - adeck/ansible-deployments GitHub Wiki
- Notation Used in This Document
- Goals
- Overall Structure
- Project Structure
- Role Structure
- Compliance Functions
Whenever a directory tree is shown, it is shown in tree
's output format, with a few notable exceptions.
- All directories are suffixed with a
/
character, all symbolic links are suffixed with an@
, and all regular files lack a suffix. - If and only if a directory has
...
as a child it is permissible for that directory to have children not listed. Usually, it should be relatively obvious when this would be the case for a directory, but it is equally important to note when it would not be the case. If a directory should only contain symlinks,...
is suffixed with an@
. If a directory should only contain directories,...
is suffixed with a/
. Otherwise a directory may contain files, directories, or symlinks.
The goals underlying the structure of this repository are as follows:
- Every role should be easily pluggable into any project which might wish to use that role, which means that:
- All variables should be easy to locate.
- All variables should be easy to override.
- Variables of the same name are used consistently across roles.
- Variables which depend upon project, or upon the specific details of a deployment (for example, the set of ports which should be open to the public in a given application), are documented in the wiki page for the role and left undefined (so that the play will fail without hardcoding an obscure default).
- Each project should be easily usable and customizable by any end user, which means that:
- A project is defined by a playbook, a set of project-agnostic roles, and a set of groups which together define all variables except those which the end-user would need to define (e.g. IP address, connection / authentication parameters, hostname, DDNS update auth token, etc.).
- All the end user needs to do to get their project running is define the inventory file, fill in the
host_vars
for their setup as specified in the documentation for the role, and run the playbook.
Everything else in this document can be understood within that framework.
.
├── README.md
├── lib.sh
├── projects/
| └── ...
└── shared/
├── ansible.cfg
└── roles/
└── ...
The shared
directory is for any resources that would be shared across projects. At the moment, that only includes roles and ansible.cfg but, as the repo matures, support for sharing further resources may be added to this specification. Apart from README.md
, you'll notice all of the filenames are lowercase and contain no spaces. This is intentional. As with variables, all files / directories are named using lower_snake_case
, and limited to lowercase alphanumerics ([a-z0-9]
), underscores (_
), and full stops (.
).
The projects
directory contains a single directory for each project, as defined below.
Within the context of this repo, a project
is a collection of playbooks, roles, and groups intended to accomplish a given goal. Playbooks and groups are unique to projects. Roles, however, are shared between multiple projects. This is what a person would normally think of as an "ansible project", with the simple caveats that:
- It shares its roles entirely with other projects.
- It conforms to a relatively strict set of constraints, as outlined below.
Specifically, the directory structure is as follows (directories should be omitted if they would be empty):
.
├── ansible.cfg@
├── plays/
| └── ...
├── inventory/
| ├── template.ini
| └── group_vars/
| └── .../
| └── ...
└── roles/
└── ...@
As may be expected, ansible.cfg
and the inventory
and group_vars
directories behave as they normally do in an ansible deployment, and should be used similarly; inventory files should go directly under inventory
, beside group_vars
and host_vars
(although inventory files other than template.ini, and group_vars
, should never be pushed to the repository). Directories should be used for each group's entry in group_vars
, so that the vars files for each group are further separated by category, and are all suffixed with .yml
(making it that much easier for text editors to automatically highlight).
NOTE: While placing the group_vars
and host_vars
directory beside inventory files in their own directory, rather than keeping them alongside the playbooks, is unusual, it is written into ansible. Which means that, once you've specified the inventory file to use via -i inventory/<FILE>
, you don't need to pass any other options to account for the group_vars
or host_vars
locations.
The roles
directory should contain only symlinks to directories in the shared/roles
directory of this repo. The plays
directory should contain playbooks, and the inventory
directory should contain inventory files (which, pivotally, do not contain variable assignments, only group membership).
template.ini
is the inventory file developers of the project are using, which contains only group definitions, and comments saying # insert hosts here
where the hosts would be listed. The idea being that an end user could simply copy template.ini
, replace the # insert hosts here
comments with their list of hosts, define host_vars
, and everything would work out of the box.
For more information on how the inventory and host_vars
should be handled, see the document on How to Run a Deployment.
.
├── tasks/
| ├── main.yml
| └── ...
├── handlers/
| └── ...
├── vars/
| └── defaults/
| └── ...
├── files/
| └── ...
└── templates/
└── ...
The omission of defaults
and meta
is intentional. defaults
is omitted because it only loads defaults/main.yml
, which means that it is impossible in the defaults
directory to split variables into multiple files / organize by category. As such, the current solution is to include_vars
(from within tasks/main.yml
) all the files under vars/defaults/
, and then do the same thing with all the files in vars/extern/
(which should not be defined in the repo, because it is only necessary if a user wants to override a default that should never need to be overridden. It is a convenience provided to the end-user which repo developers should never need to use).
For more information on how vars/extern
is to be used, see the document on How to Run a Deployment.
To make compliance with these guidelines easier, the lib.sh
file contains some useful functions which perform common tasks. The file is intended to be sourced.
The functions are as follows:
-
create <ROLE>
when your CWD is theprojects
directory,create
will generate an empty project skeleton.