Server configuration using Ansible and Ansible Galaxy

Since working with @alex on a job for Outlandish around a year and a half ago, which involved him showing me how to use Ansible, I have been using it for almost all the server configuration work that we have, a lot of the code I have written is publicly available on git.coop.

Up until recently I have been using one git repo per server type, for example see the Nextcloud, Mailcow or Discourse repos.

I’m now looking at re-organising everything to use Ansible Galaxy, however rather than using existing Galaxy roles (I’d rather write my own) or uploading repos to GitHub (if I can find a easy way to mirror repos to GitHub I might do that), I’m going to use the ansible-galaxy command to pull roles into a repo that contains a hosts.yml file for managing all our servers.

The first repo that contains a single role that I have created from scratch is the Matomo one, this is used for upgrading all our Matomo servers, there isn’t much code in it but it illustrates the single role per repo model and the REAME documents how to use it and the format of the hosts.yml file.

Another example is the Docker repo, this was originally designed to be use as a stand-alone repo for installing Docker and Docker Compose but it has now been refactored to be used by ansible-galaxy and in addition, thanks to a few symlinks, it can still be used in a stand-alone role, which is handy for doing things like using it to install Docker locally.

The more complicated repos, like the Nextcloud one, will take some time to reorganise (see this issue), but I now have a very good reason to get this done — Chris from the Commons Cloud project has been using this repo (with some amendments) and following a very positive Nextcloud Talk video chat with him yesterday we have agreed to work on the code together.

I’m planning to document everything in the respective git repos but thought it would be worth creating a thread here for discussing the broad approach with the other Ansible users with accounts here.

2 Likes

Hey Chris, thanks for sharing! I’ll just pitch in my two cents …

I think that a role-per-repo makes a lot of sense since it aligns with Galaxy and the project’s future plans. You might have seen that Ansible Galaxy will adopt Molecule and Ansible-lint in order to increase the quality assurance of the roles on Galaxy. This means, we’ll have integrated CI, “ratings” based on automatic linting and some other niceties. Having your roles in a single repository is a way to “future proof” your role development, in that, you can take upstream galaxy upgrades into your roles as they come. BTW, you can read some notes from the latest “AnsibleFest” regarding the galaxy project: https://etherpad.openstack.org/p/ansible-summit-october-2018-galaxy.

On a more general note (potentially off topic), at Aptivate, we’re doing more and more with Ansible which you can find here with the same role-per-repo setup. Our roles are targetting CentOS but I wonder if it would be possible to re-use roles between coops? In my mind, actually having passing integration and unit tests with Molecule makes this feasible and not just “a nice idea but it would never work”. Would stop every coop having to write that mysql-server role each time. If we self-hosted a galaxy instance and had some vetting process for roles and code review for changes for “common core” roles, we might be going somewhere fast :wink:

1 Like

Cheers for the comments @lukewm, I’ll spend some time reading through your Ansible roles and also look into Molecule and Ansible-lint — I hadn’t come across these projects before.

That is the current plan, Chris, who is working on the Commons Cloud project, and I have and I’m sure it could be potentially expanded, we just need to take it one step at a time :slight_smile: .

The fact that you are targeting CentOS and we are targeting Debian would add to the complexity… I’m not sure it is worth having roles that can be used for either but I’m sure we can share a lot, we are using GPLv3 for everything so perhaps you could consider that also (seems the best fit since Ansible itself uses it).

The concern I have is a role seems to need to be associated with a responsible maintainer. So widely used public ones with good reputation and maybe backed by a company seem to address that, or personal roles that you know do what you want (and can read/edit them if not).

But a set of commons ones could potentially fall in the middleground - and making widely used shared ones seems like a lot of work (making them work across various OSes (as @chris pointed out), and being rock solid).

Having conversations about best practise and experiences seems very useful starting point!

1 Like

Last night I was working on a Apache Role (very much a work in progress, not ready to be used yet) and given the different packaging of Apache by Fedora / RHEL / CentOS and Debian it is hard to see the point of having one Apache Role for both… but this is probably an extreme example.

But a set of commons ones could potentially fall in the middleground - and making widely used shared ones seems like a lot of work (making them work across various OSes (as @chris pointed out), and being rock solid).

Agreed! To note about the workload, yes, it’s been my experience also. But lately, working on one of our more complicated roles, to make mysql-server run across different projects (mysql-server plain, mysql-community-server and software collections mysql-server) over at aptivate / ansible-roles / mysql-server · GitLab has been changing my opinion. We only target one OS but we’ve been leveraging molecule to test these different scenarios and it’s been promising so far. Check out molecule · master · aptivate / ansible-roles / mysql-server · GitLab if interested.

Newer versions of Ansible have more powerful functionality for conditionally running tasks, so it is becoming easier, I think, to imagine single roles supporting multiple OSes (without nightmarish spaghetti task maintenance issues) and then using molecule to actually ensure the tests pass.

Having conversations about best practise and experiences seems very useful starting point!

Please do join the CoTech gathering session inspired by this thread!

2 Likes

Look great @lukewm - would be glad to join the session :slight_smile:

I’ve been cracking on with writing separate Ansible roles for things, a recent example, is one for MariaDB, as well as installing the server this optionally sets the root password and creates a database and user,

I’m rather pleased with it (although I haven’t quite got it so all the output is green, there are some command and shell tasks that are always registered as changed, for example, 1, 2, 3 and 4).

The role should be able to be used for setting up any Debian server that needs a MySQL database, perhaps at some point I’ll add the ability to create multiple databases and users.

I have just had a look at the Aptivate mysql-server role and looking at your code to set the root password for CentOS and comparing with my code for Debian, it is hard to see any overlap, but I’m sure we could learn from each approach :slight_smile:.

Another example is the users role, this loads a YAML dictionary of users like this:

    users:
      foo:
        home: /opt/foo
        shell: /bin/false
        system: yes
      bar:
        home: /var/www/bar
        system: yes
        shell: /usr/sbin/nologin
        editor: vim
        groups:
          - ssl-cert
      baz:
        groups:
          - staff
          - users
        editor: vim
      chris:
        groups:
          - sudo
        editor: vim
        ssh_public_keys: https://git.coop/chris.keys 

You can optionally set the users $EDITOR and and also provide a URL for the users SSH public keys.

Again I’m happy with it, but it has ended up getting rather complicated, to the extent that if this was a role that someone else had written I’d probably not consider using it due to it being too complicated… perhaps this is why people end up writing all their own Ansible roles… :thinking:

Having said that a lot of the complication is a result of wanting all (or as many as possible) of the variable in each role to be optional — this is something I want to change on all the older roles as I think it makes reuse of roles a lot easier.

@lukewm and @nicksellen, need to give Polly a time preference for the Ansible session at the CoTech gathering, do you have one? I don’t think I do.

https://community.coops.tech/t/cotech-space4-gathering-29-30th-november-2018/1033/26

Interesting, yes let’s discuss this! I’d love to know what are people looking for to trust the roles of others :slight_smile:

New version of Galaxy is dropping: https://github.com/ansible/galaxy/blob/devel/CHANGELOG.rst

I’ll try and organise a time ASAP for the CoTech gathering meeting.

EDIT: Oops, hit enter too fast.

I have found that I have had to resort to using command to set the MariaDB root password, as the debconf trick doesn’t appear to work with Stretch / MariaDB 10.1, which is a bit of a shame…

I’m not going to do any more on the MariaDB role for now, but when I next have time to work on it I want to make it so it can be passed a YML a dictionary for database and user configuration, for example:

 vars:
   maria_databases:
     - wordpress
     - civicrm
     - matomo
   mariadb_users:
     wordpress:
       privs:
        - wordpress.*:ALL
        - civicrm.*:ALL
     matomo:
        privs:
          - matomo.*:ALL

Here is a list of the Ansible role repos that have been created so far:

They all need more work, and checking with ansible-lint etc… but I think they are mostly all working.

gcoop in Argentina have 24 public Ansible roles on GitHub that look great:

The services they provide are listed on nube.coop.

https://wiki.coops.tech/wiki/CoTech_Hack_2018/CoTech_and_Ansible

Just leaving this here :nerd_face::nerd_face::nerd_face:

1 Like