Git Your Deploy Just Right


Before we go too much further, we need to make our development environment a little more user friendly. Well, I do. You may be more than comfortable with Vi, and happy to work on the server to make all your edits.

Personally, I like to get everything into git, that way it's pushed up to my Gitlab for backup and for ease of use with things like History and commit reasons, and all that other good stuff we use git for.

I've covered this process in a previous video, so I won't be going over the set up of the git push here in any great detail.

Instead, I am concentrating on the Ansible side of things.

There's a few concepts used in this video that we haven't touched on yet - with_items and ansible-galaxy. Don't worry about those at this stage. There's a good reason for using both, but you don't need to understand either just yet. They are covered in lessons to follow.

How To

To start with, we need to make sure Git is installed on our Ansible Master server.

We could do this the standard way using apt-get, but as this is a course on using Ansible, why not get Ansible to do the dirty work for us?

There is a really good reason for doing this. Our Ansible Playbooks start to become living technical documentation (of sorts) of how our infrastructure is configured.

Say you get an SMS alert at 3am one Thursday morning that your secondary MySQL server has just died. Would you know exactly what software to re-install to get that server back up to Production standard? If your processes and procedures are better than most then maybe. But even so, doing everything from downloading the right ISO image for the server (you made a note of that, right?), sticking it on a bootable USB pen, re-installing, then starting the arduous task of manually installing each piece of software that makes up the server as it was before... well, you may be lucky if you're back out of the door by midday.

However, if your config is managed by Ansible, after re-installing the OS, you're one command, and a short wait away from going right back home to bed.

Anyway, that's why we are going to install git with Ansible :)

We can create a new Playbook and call it our common-playbook.yml.

Tasks that live in the common-playbook.yml file are - as the name would suggest - going to be common tasks that we want to run on every server we manage. Things like:

  • ensuring our SSH keys are on so we can do password-less login
  • installing the common tools we use for diagnostics, maintenance, and general servery tasks (htop, curl, vim, etc)
  • setting our server hostname

And many other things.

These are the pain in the arse tasks that need doing every time you build a server. Do you really want to do all this manually for the umpteenth time? I don't.

In this example though, all we need is Git.

So we can add just this in to our common-playbook.yml and let Ansible handle the installation of Git from here on in.

---
- name: Install Server Basics
  apt: pkg={{ item }} state=installed update_cache=true
  with_items:
    - git

Again, don't worry about the with_items syntax, it will be covered shortly.

With our new Playbook created, the setup after this mirrors the standard Git Deploy we've already covered before. Set up a git dir, set up an Ansible dir, configure the post-receive hook file, and then we should be good to go. Again, if unsure, watch the previous video that covers that in greater depth.

4 Minute Warning

As mentioned in the video, aside from the creation of the common-playbook.yml file, the real guts of this video starts around the 4 minute mark.

Here, we are taking a copy of the files we have been working on from the server. We now want to move those files to our local machine so we can use a friendly text editor like Sublime.

This process is pretty simple if you're from a Linux background, but if you're not, it might seem a little daunting.

Firstly, from the server, we create a new directory called copy_me in to which we will move all the Playbooks we have been working on.

cd ~ 
mkdir copy_me
mv apache-playbook.yml copy_me/
mv common-playbook.yml copy_me/
mv our-playbook.yml copy_me/

Of course, there are faster ways to do this. If your following along exactly, then feel free to replace the three mv commands with one simpler one:

mv *.yml copy_me/

Don't do that if you're working on an existing server that may very well already have other .yml files in the current dir.

Next up, we want to change in to the copy_me dir:

cd copy_me

And then we are going to use another new command, the ansible-galaxy init command.

Again, don't be alarmed here if this is new to you. I go in to Ansible Galaxy in a later lesson, but to give you a heads up here, we are going to make use of the ansible-galaxy init command to create a directory structure for a template Role.

Say what?

Exactly, if that makes no sense, the main take away here is that we are doing this to save ourselves work in the future. Creating the directory structure by hand is fine, but if we can save ourselves a bit of work in the future, then why not?

ansible-galaxy init __template__

Then, we swap back to our local machine.

Now we have all our files and folders on the server, we want to copy them from the server and start working on them locally.

So, from our local machine, we can use the Secure Copy (scp) command to bring the files over from the server, to our local, using SSH.

cd /wherever/you/are/working/from/locally
scp -r codereview@192.168.1.169:/home/codereview/copy_me . 

The -r flag is important, as it tells Secure Copy to run recursively - and therefore, to copy the directory contents of template.

Then we can add the files to our local git repository:

git add .
git commit -am "files from server"

And now, with our git deploy set up, the next time we do a git push server master, we will push up all these new files to our ansible directory.

In summary, we get the best of both worlds. Ansible is kept separated on its own server, but we get to work locally using a nice text editor and our files are under version control.

What's not to like?

Code For This Course

Get the code for this course.

Episodes