The purpose of this message is to come up with a best practices for
role/playbook/library layout that encourages re-use and logically
separates projects & roles into their own repositories. Just as an
aside, I'm not a git expert by any means, so I'm always looking to
simplify my workflow and organization. If I'm overcomplicating
things, by all means let me know!
*TL;DR - what's the best way to re-use roles and playbooks across projects?
Let's say I have project voltron. Project voltron uses the following
roles -- web and db
Of course the web and db roles all live in source control with the
general layout:
ansible-web-role:
.
├── files
├── handlers
├── library
├── tasks
├── templates
└── vars
These roles are also used outside of the voltron project, so there's
also a repo that uses ansible-web-role as a subrepo and would look
something like this:
ansible-web:
.
├── bender.yml
├── roles
│ └── web
│ ├── files
│ ├── handlers
│ ├── library
│ ├── tasks
│ ├── templates
│ └── vars
└── setup_web.yml
As you can see there are some additional playbooks that I am using,
and the roles/web subdirectory is just a git subrepo, which means any
changes that happen to the ansible-web-role project can be pulled down
into the ansible-web project. Also changes made in the roles/web
directory can get pushed up to the ansible-web-role repo.
Now to tie it all together in the voltron project:
.
└── roles
├── db
│ ├── files
│ ├── handlers
│ ├── library
│ ├── tasks
│ ├── templates
│ └── vars
└── web
├── files
├── handlers
├── library
├── tasks
├── templates
└── vars
Here the web and db roles are subrepos of the voltron-repo. The
problem that comes into play is what if I want to re-use the
bender.yml and setup_web.yml playbooks from the ansible-web repo?
One (hacky) solution I can think of is running a script that would
copy those playbooks into the root of the voltron project, or
checkout the ansible-web repo
Another idea is something like this. Place all the subprojects (roles
and associative playbooks) into a "subprojects" folder that lives at
the root of the project. Subrepo all of dependent projects into the
"subprojects" folder. Symlink the roles and playbooks to their proper
locations. It would end up looking something like this:
voltron_project:
.
├── bender.yml -> subprojects/web/bender.yml
├── roles
│ ├── db -> ../subprojects/db/roles/db
│ └── web -> ../subprojects/web/roles/web
├── setup_db.yml -> subprojects/db/setup_db.yml
├── setup_web.yml -> subprojects/web/setup_web.yml
└── subprojects
├── db
│ ├── roles
│ │ └── db
│ │ ├── files
│ │ ├── handlers
│ │ ├── library
│ │ ├── tasks
│ │ ├── templates
│ │ └── vars
│ └── setup_db.yml
└── web
├── bender.yml
├── roles
│ └── web
│ ├── files
│ ├── handlers
│ ├── library
│ ├── tasks
│ ├── templates
│ └── vars
└── setup_web.yml
Symlinks in git make me feel icky, but this is just to get a
conversation started. This keeps the playbook outside of the role (as
it's not a roles purpose to house playbooks), but is messier.
Another thought would be to just include a subdir in the role that
provided playbooks that used that role exclusively. Then just those
playbooks could be symlinked into the project.
Something like this:
.
├── bender.yml -> roles/web/playbooks/bender.yml
├── roles
│ ├── db
│ │ ├── files
│ │ ├── handlers
│ │ ├── library
│ │ ├── playbooks
│ │ │ └── setup_db.yml
│ │ ├── tasks
│ │ ├── templates
│ │ └── vars
│ └── web
│ ├── files
│ ├── handlers
│ ├── library
│ ├── playbooks
│ │ ├── bender.yml
│ │ └── setup_web.yml
│ ├── tasks
│ ├── templates
│ └── vars
├── setup_db.yml -> roles/db/playbooks/setup_db.yml
├── setup_web.yml -> roles/web/playbooks/setup_web.yml
└── site.yml
If you made it this far, thanks!
James