Go back to the main page

Create your own git server easily with Chef and the Vagrant AWS plugin: Part 2.

This article is over 2 years old. Proceed with caution.

Regards ♨ – Minimul

 

Part 2 Goal. Create your own Git server

Continuing from Part 1 we are in the process of creating a personal Git server using Chef and the Vagrant AWS plugin.

  1. Let's go back to our Vagrant workspace directory at ~/WorkSpaces/git-server and edit the Berksfile to look like this.
  2. site :opscode
    
    cookbook 'gitolite', git: 'git@github.com:julionc/chef-gitolite.git'
    metadata
    
  3. Edit the metadata.rb to look like this.
  4. name             'git-server'
    maintainer       'YOUR_NAME'
    maintainer_email 'YOUR_EMAIL'
    license          'All rights reserved'
    description      'Installs/Configures git-server'
    long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
    version          '0.1.0'
    
    depends 'apt'
    depends 'git'
    depends 'gitolite'
    
    DISCUSSION: Cookbooks put in metadata.rb will automatically use the official Opscode community cookbooks. However, for Gitolite we are using a different cookbook, hence the designation before the metadata call.
  5. Edit the recipes/default.rb as so:
  6. include_recipe 'apt'
    include_recipe 'git'
    include_recipe 'gitolite'
    
    gitolite_user node.gitolite.username do
      home node.gitolite.home
      version node.gitolite.version
      ssh_key node.misc.ssh_key
    end
    
    
    DISCUSSION: The gitolite_user method is a LWRP that will handle setting up Gitolite with an admin user. We are going to use the default attributes for node.gitolite.username (default: git), node.gitolite.home (default: /home/git), and node.gitolite.version (default: 'stable'). The ssh_key value is to be set in the next step.
  7. Update the Vagrantfile from Part 1 with the information highlighted in gray.
  8. Vagrant.configure("2") do |config|
      config.vm.hostname = "git-server"
      config.vm.box = "aws-basic"
      config.vm.boot_timeout   = 120
      config.omnibus.chef_version = :latest
    
      config.berkshelf.enabled = true
    
      config.vm.provision :chef_solo do |chef|
        chef.json = {
          misc: {
            ssh_key: File.read(ENV['MY_PUBLIC_SSH_KEY_PATH'])
          }
        }
        chef.run_list = [
          'recipe[git-server::default]'
        ]
      end
    
      config.vm.provider :aws do |aws, override|
        aws.access_key_id = ENV['AWS_ACCESS_KEY_ID']
        aws.secret_access_key = ENV['AWS_SECRET_ACCESS_KEY']
        aws.keypair_name = ENV['AWS_KEYPAIR_NAME']
        aws.security_groups = ['your-security-group-here']
        aws.instance_type = "t1.micro"
        aws.ami = "ami-d0f89fb9"
        override.ssh.username = "ubuntu"
        override.ssh.private_key_path = ENV['MY_PRIVATE_AWS_SSH_KEY_PATH']
      end
    end
    
    DISCUSSION: (1) With the config.berkshelf.enabled setting we are wiring up Vagrant and Berkshelf via the vagrant-berkshelf plugin we installed in Part 1. Every time you run vagrant provision, up, or reload Berkshelf installs or updates the cookbooks it is managing, which is nice because it saves you from having to do that step; (2) the node.misc.ssh_key value called in the previous step is set here; (3) the chef.run_list is pointing to the recipes/default.rb, which we added to in the last step.
  9. Now run vagrant provision. Below is the output for a successful run (truncated, scroll to see all).
  10. [Berkshelf] Updating Vagrant's berkshelf: '/Users/christian/.berkshelf/default/vagrant/berkshelf-20130928-42384-1m0r5fh-default'
    [Berkshelf] Installing gitolite (0.1.0) from git: 'git@github.com:julionc/chef-gitolite.git' with branch: 'master' at ref: '020a1ac324f1b9f9e9f39325e291d0ef31666eff'
    [Berkshelf] Using git-server (0.1.0)
    [Berkshelf] Using git (2.6.0)
    [Berkshelf] Using dmg (2.0.0)
    [Berkshelf] Using build-essential (1.4.2)
    [Berkshelf] Using yum (2.3.2)
    [Berkshelf] Using windows (1.10.0)
    [Berkshelf] Using chef_handler (1.1.4)
    [Berkshelf] Using runit (1.2.0)
    [Berkshelf] Using perl (1.2.0)
    [Berkshelf] Using apt (2.1.1)
    [default] Rsyncing folder: /Users/christian/WorkSpaces/blog/git-server/ => /vagrant
    [default] Rsyncing folder: /Users/christian/.berkshelf/default/vagrant/berkshelf-20130928-42384-1m0r5fh-default/ => /tmp/vagrant-chef-1/chef-solo-1/cookbooks
    [default] Chef 11.6.0 Omnibus package is already installed.
    [default] Running provisioner: chef_solo...
    Generating chef JSON and uploading...
    Running chef-solo...
    stdin: is not a tty
    [2013-10-07T14:37:02+00:00] INFO: Forking chef instance to converge...
    [2013-10-07T14:37:02+00:00] INFO: *** Chef 11.6.0 ***
    [2013-10-07T14:37:04+00:00] INFO: Setting the run_list to ["recipe[git-server::default]"] from JSON
    [2013-10-07T14:37:04+00:00] INFO: Run List is [recipe[git-server::default]]
    [2013-10-07T14:37:04+00:00] INFO: Run List expands to [git-server::default]
    [2013-10-07T14:37:04+00:00] INFO: Starting Chef Run for ip-10-164-49-55.ec2.internal
    [2013-10-07T14:37:04+00:00] INFO: Running start handlers
    [2013-10-07T14:37:04+00:00] INFO: Start handlers complete.
    [2013-10-07T14:37:32+00:00] INFO: execute[apt-get-update-periodic] ran successfully
    [2013-10-07T14:37:32+00:00] INFO: directory[/var/cache/local] created directory /var/cache/local
    [2013-10-07T14:37:32+00:00] INFO: directory[/var/cache/local] owner changed to 0
    [2013-10-07T14:37:32+00:00] INFO: directory[/var/cache/local] group changed to 0
    [2013-10-07T14:37:32+00:00] INFO: directory[/var/cache/local] mode changed to 755
    [2013-10-07T14:37:32+00:00] INFO: directory[/var/cache/local/preseeding] created directory /var/cache/local/preseeding
    [2013-10-07T14:37:32+00:00] INFO: directory[/var/cache/local/preseeding] owner changed to 0
    [2013-10-07T14:37:32+00:00] INFO: directory[/var/cache/local/preseeding] group changed to 0
    [2013-10-07T14:37:32+00:00] INFO: directory[/var/cache/local/preseeding] mode changed to 755
    [2013-10-07T14:37:40+00:00] INFO: Starting Gitolite installation.
    [2013-10-07T14:37:41+00:00] INFO: user[git] created
    [2013-10-07T14:37:41+00:00] INFO: directory[/home/git/.ssh] created directory /home/git/.ssh
    [2013-10-07T14:37:41+00:00] INFO: directory[/home/git/.ssh] owner changed to 1001
    [2013-10-07T14:37:41+00:00] INFO: directory[/home/git/.ssh] group changed to 1001
    [2013-10-07T14:37:41+00:00] INFO: directory[/home/git/.ssh] mode changed to 700
    [2013-10-07T14:37:41+00:00] INFO: directory[/home/git/bin] created directory /home/git/bin
    [2013-10-07T14:37:41+00:00] INFO: directory[/home/git/bin] owner changed to 1001
    [2013-10-07T14:37:41+00:00] INFO: directory[/home/git/bin] group changed to 1001
    [2013-10-07T14:37:41+00:00] INFO: directory[/home/git/bin] mode changed to 755
    [2013-10-07T14:37:41+00:00] INFO: git[clone the gitolite repository] cloning repo git://github.com/sitaramc/gitolite.git to /home/git/gitolite
    [2013-10-07T14:37:42+00:00] INFO: git[clone the gitolite repository] checked out branch: v3.04 reference: af437c3a7b9034c8bfda30d99daf3a8160ff904d
    [2013-10-07T14:37:42+00:00] INFO: file[/home/git/gitolite-admin.pub] created file /home/git/gitolite-admin.pub
    [2013-10-07T14:37:42+00:00] INFO: file[/home/git/gitolite-admin.pub] updated file contents /home/git/gitolite-admin.pub
    [2013-10-07T14:37:42+00:00] INFO: file[/home/git/gitolite-admin.pub] owner changed to 1001
    [2013-10-07T14:37:42+00:00] INFO: file[/home/git/gitolite-admin.pub] group changed to 1001
    [2013-10-07T14:37:42+00:00] INFO: execute[gitolite/install -ln] ran successfully
    [2013-10-07T14:37:44+00:00] INFO: execute[gitolite setup -pk gitolite-admin.pub] ran successfully
    [2013-10-07T14:37:45+00:00] INFO: execute[gitolite setup -pk gitolite-admin.pub] ran successfully
    [2013-10-07T14:37:45+00:00] INFO: Chef Run complete in 41.684073369 seconds
    [2013-10-07T14:37:45+00:00] INFO: Running report handlers
    [2013-10-07T14:37:45+00:00] INFO: Report handlers complete
    
    DISCUSSION: Looking at the output we can see that Gitolite was installed in the /home/git directory. The repositories reside in /home/git/repositories. The public key you supplied has been associated with the Gitolite admin account and added to the /home/git/.ssh/authorized_keys file.
  11. Now that the Git server is installed we are going to add this current Vagrant-Chef-Berkshelf project as our first repository.
    1. Obtain the IP address of the EC2 instance
    2. $ vagrant ssh-config | grep HostName 
      
    3. Switch to your home directory and git clone the gitolite-admin repo.
    4. $ cd ~
      $ git clone git@<ip-address-obtained-in-step-1>:gitolite-admin.git
      $ cd gitolite-admin/
      
    5. Edit the config/gitolite.conf to read.
    6. repo gitolite-admin
          RW+     =   gitolite-admin
      repo testing
          RW+     =   @all
      repo git-server
          RW+     =   @all
      
    7. Commit and push
    8. $ git commit -am "Add git server repo"
      $ git push origin master
      
    DISCUSSION: Gitolite works with git-hooks so that after you commit and push your changes to the gitolite.conf file, Gitolite creates your new git-server repo automatically. We are ready to make the initial commit of our project files.
    NOTE: You are going to want to put a pretty host name (e.g. gitserver.yourdomain.com) on that IP Address. The IP Address/Public DNS that Amazon assigns an EC2 or VPC instance is temporary and can change if the instance is stopped and restarted. A better solution is to create an Elastic IP to associate with dynamic instances. That said, for my git server I simply have a CNAME record pointing to the AWS Public DNS and no Elastic IP assigned.
  12. Add this project as your first repo.
  13. cd ~/WorkSpaces/git-server
    git add .
    git commit -am "Initial commit"
    git remote add origin git@<your-ip-address-obtained-above>:git-server.git
    git push origin master
    
    NOTE: You may have noticed we didn't have to issue a git init . command. That is because the berks cookbook command we ran in Part 1 does this.

Stay tuned as in part 3 we will automatically backup our private Git repositories to s3.

Comment on this article?