System Automation – Part 3 – Git

Brian Carpio
GitPuppetDevOpsAutomation

This blog post assumes that you have completed Parts 1 and 2 of my System Automation blog series and that you have a working PuppetMaster up and running in your environment. See links at the bottom of this page. We will continue to talk about system automation by exploring Git and how Git will be used to version and manage the state of our puppet modules and site.pp files.

What is Git

Git is a distributed revision control and source code management system. Git's first release was on December 21, 2005 and was originally developed by Linus Torvalds. Git's development came as a result of the Linux Kernel development team loosing the ability to leverage BitKeeper due to a copyright holder of BitKeeper withdrawing free use of the product. Linus' goal when he went out to create Git was:

  • Take CVS as an example of what not to do; if in doubt, make the exact opposite decision.
  • Support a distributed, BitKeeper-like workflow
  • Very strong safeguards against corruption, either accidental or malicious.

Installing The Git Server

The first thing we need to do is setup our Git server. This is as easy as it sounds. I am not going to cover complex git security solutions such as Gitolite as this is a bit beyond the scope of this blog. I plan to have a blog post on this topic sometime in the future. The method we will be leveraging is just a simple network share where each user will be given access to the server through an RSA keypair. To install git on your Ubuntu server run the following:

sudo apt-get install git-core

Now we will create a directory where all of our "repositories" will be stored on the server.

sudo mkdir /repos
sudo chmod 777 /repos

Next, we are going to create our initial repository for this exercise. It is going to be called "puppet". A repository in Git is a collection of objects and refs that together store a history of how a collection of files has changed over time. There are certain files in this repository that we will not want to push back to Git. The files are files that are automatically created by editors like vi or emacs.

sudo git init --bare /repos/puppet.git
cat > /repos/puppet.git/info/exclude <<EOF
*~
*.swp
EOF

Setting Up The Development Machine

On your development machine, this machine could be your laptop, if you're running Ubuntu you will want to run the same command we ran on the server.

sudo apt-get install git-core

Next, we want to generate an RSA key pair for SSH access to the Git server. Please fill in the appropriate information such as email in the following steps.

cd
ssh-keygen -t rsa -C "your_email@youremail.com"
git config --global user.name "Firstname Lastname"
git config --global user.email "your_email@youremail.com"

You can also setup an alias to make typing git commands a bit shorter. For instance, you can add the following line to your bashrc or bash_profile to alias "git status" with "gs".

alias gs='git status'

Next, we need to copy our public key to the /home/ubuntu/.ssh/authorized_keys file on the Git server. Cat your public key with cat ~/.ssh/id_rsa.pub and copy the output to your authorized_keys file on the Git server.

Now, lets clone the repository we created earlier. Cloning from the server gives us a local copy of the puppet repo we setup earlier.

git clone ubuntu@IP_ADDRESS:/repos/puppet.git

Remember, in part 2 of this blog series I told you to save the files that puppet generated locally? Well lets add those files now to this empty repository and commit them to version control. We want to copy those files and folders from part 2 to the "puppet" folder. Next, we will run the following git commands (I assume you know how to copy files with the cp command):

cd puppet
git add -A
git commit -m "Initial Commit"
git push origin master

Setting Up The PuppetMaster

On the puppetmaster we need to clone the repository we created earlier. To do this we follow the same steps that we did on the development machine. I like to use the /repos folder for all of my repos so I don't "loose them" in the file system.

sudo apt-get install git-core
cd
ssh-keygen -t rsa -C "puppetmaster"
sudo mkdir /repos; sudo chmod 777 /repos
cd /repos
git clone ubuntu@IP_ADDRESS:/repos/puppet.git

Notice how the folder hierarchy is identical to the folder structure on the puppetmaster in /etc/puppet. We are going to remove the /etc/puppet folder and symlink in the puppet repo. The following steps assume we will be working in the "production" environment of puppet but feel free to choose any environment you want to work in.

sudo rm -rf /etc/puppet
sudo ln -s /repos/puppet /etc/puppet
sudo chown -R puppet /etc/puppet/

Now that we have all of our puppet configuration files in git we simply use the following commands to pull new or changed configurations from the central git server.

cd /etc/puppet
sudo git pull

Git Best Practices

There are hundreds of different ways to leverage Git. I will give a few examples of how I use Git on a day-to-day basis.

Branching Your Repository

As good practice you should never work in the "master" branch. The master branch should always be the "production ready" branch for any repository. To create a new branch:

git checkout -b development
git push origin development

You can see all of the branches you have created with:

git branch -a

I like to name my branches that are not production ready "development" but you can name the branch anything you want.

Merging Branches

When your development branch is production ready, you can merge your development branch into master with the following commands:

git checkout master
git merge development
git push

Switching Between Branches

Lets say you have master (production) in place on the puppetmaster and you want to test a new configuration in development. On the puppetmaster you would simply run the following:

cd /etc/puppet
sudo git checkout development
sudo git pull

In my next blog post I will explain how to leverage Fabric as a remote administration / orchestration tool so you never have to actually ssh into any server to run day to day system administration tasks.