Private repos and AWS CodeCommit - Initial Thoughts

As part of re-doing my home infrastructure I’m looking to add a remote location for my private git repos. My use case is a simple one, I need lots of low cost, tiny, private repos, each with a few dozen files at most. I don’t need a comprehensive set of collaboration features as I’m normally the only one working on them. My current practice is to keep my private repos on a local git server and anything open source goes to GitHub.

Ignoring the idea of keeping all my git eggs in one basket I’ve looked at three main options, private repos on GitHub, private repos on BitBucket or trying the quite new AWS CodeCommit. While GitHub’s the default choice for my open source code, we also happily use it at $WORK for company-wide source code management, the private repo pricing model is too high for my use case. I’d need the “medium” or “large” plan at 22/50USD a month for a few files in each repo. I’m not willing to merge everything in to fewer, larger repos, so this rules GitHub out for my usage.

BitBucket offers unlimited free private repos and has its own version of the collaboration features GitHub users have come to expect. In my testing BitBucket seems like a fine service, with a pricing model that’s hard to beat (FREE!). If I wasn’t so heavily invested in AWS at the moment I think I’d be quite a happy user of it.

Now we come to the newest, and consequently least mature and featured of the three options, AWS CodeCommit. As you’d expect from an AWS service the CLI and API support is excellent, CloudFormation resources will appear one day and third party tools like Terraform are well on their way to feature parity.

Assuming you already have your AWS account created, and credentials in the ~/.aws/credentials file, using CodeCommit is simple. As usual Amazon provides comprehensive Getting Started instructions so I won’t repeat those here. Once we’re all set up we can see how easy CodeCommit is to use. We’ll create a new repo, make a commit to it and then remove the repository, all via the command line tools.

# create the repo
$ aws codecommit \ 
      create-repository \
      --repository-name puppet-strace \ 
      --repository-description 'Puppet module to manage strace'

{
    "repositoryMetadata": {
        "repositoryName": "puppet-strace",
        "cloneUrlSsh": "ssh://git-codecommit.us-east-1.amazonaws.com/v1/repos/puppet-strace",
        "lastModifiedDate": 1445430790.709,
        "repositoryDescription": "Puppet module to manage strace",
        "cloneUrlHttp": "https://git-codecommit.us-east-1.amazonaws.com/v1/repos/puppet-strace",
        "creationDate": 1445430790.709,
        "repositoryId": "b731cSDFF0-5121-4512e-123cd-4DF3FC042db5",
        "Arn": "arn:aws:codecommit:us-east-1:111111111111:puppet-strace",
        "accountId": "111111111111"
    }
}

Once the the command returns you can view the repo either via the web console or the command line

# show the repo name and id.
$ aws codecommit list-repositories --query 'repositories[?repositoryName==`puppet-strace`]'

# show full repo details
$ aws codecommit get-repository --repository-name puppet-strace

Now we know the repo exists we’ll extract the HTTPS clone URL and add a file:

# get the clone url
$ aws codecommit get-repository \
  --repository-name puppet-strace  \
  --query 'repositoryMetadata.cloneUrlHttp'

"https://git-codecommit.us-east-1.amazonaws.com/v1/repos/puppet-strace"

$ git clone https://git-codecommit.us-east-1.amazonaws.com/v1/repos/puppet-strace

$ cd puppet-strace

# from here your normal git command are all available.

Once you’ve commited and pushed a file or two you can view them via the AWS web console. At this point you’ll probably remember how new a product CodeCommit is; its current UI is quite bare. Knowing AWS I’d expect this to change quickly. For my usage, which is nearly all CLI/API driven with the occasional reading of a committed text file, the UI is perfectly functional. Now we’ve created, added to and pushed a repo let’s finish the round trip and remove it.

$ aws codecommit delete-repository --repository-name puppet-strace

Although I’m a fan of CodeCommits simplicity and automation support there are a few negatives to consider before migrating everything to it. There is a cost, albeit a small one, to using it. You’re charged by number of users accessing your repos and the number of git operations. I’m assuming I’m not going to hit the operations limit often but I will immediately be paying for an extra user or two. I’ll have my own AWS CodeCommit user for normal read/write repo access and I’ll need additional, locked down, users for my CI services. Access control is handled using IAM, this is both a positive and a negative depending on how much you like the JSON based policy language. There’s currently no concept of a public CodeCommit repo so you can’t start a code base off in private and then promote it to public view as you can with GitHub or BitBucket. The dashboard UI lacks the familliar collaboration features, there’s no pull requests, issue tracking or wiki built in. If you’re working in a team you’ll need a seperate way to handle those. These current limitations means GitHub doesn’t need to be worried just yet, the lack of collaboration features alone will prevent most people from considering CodeCommit as an option even for private only repos.

Although I’ve only been using it for a few days I’m quite positive about CodeCommit for my specific use case. The pricing model works well for me, and combined with simple API/CLI access it allows embedded git repo creation in my local tooling, which has opened up some new options for things like puppet module development.