Using AWS CodeCommit With Git Repositories In Multiple AWS Accounts

set up each local CodeCommit repository clone to use a specific cross-account IAM role with git clone --config and aws codecommit credentials-helper


2020-03-06 UPDATE! Amazon has released a git helper that replaces much of this article. Check this out:

https://docs.aws.amazon.com/codecommit/latest/userguide/setting-up-git-remote-codecommit.html


When I started testing AWS CodeCommit, I used the Git ssh protocol with uploaded ssh keys to provide access, because this is the Git access mode I’m most familiar with. However, using ssh keys requires each person to have an IAM user in the same AWS account as the CodeCommit Git repository.

In my personal and work AWS usage, each individual has a single IAM user in a master AWS account, and those users are granted permission to assume cross-account IAM roles to perform operations in other AWS accounts. We cannot use the ssh method to access Git repositories in other AWS accounts, as there are no IAM users in those accounts.

AWS CodeCommit comes to our rescue with an alternative https access method that supports Git Smart HTTP, and the aws-cli offers a credential-helper feature that integrates with the git client to authenticate Git requests to the CodeCommit service.

In my tests, this works perfectly with cross-account IAM roles. After the initial git clone command, there is no difference in how git is used compared to the ssh access method.

Most of the aws codecommit credential-helper examples I’ve seen suggest you set up a git config --global setting before cloning a CodeCommit repository. A couple even show how to restrict the config to AWS CodeCommit repositories only so as to not interfere with GitHub and other repositories. (See “Resoures” below)

I prefer to have the configuration associated with the specific Git repositories that need it, not in the global setting file. This is possible by passing in a couple --config parameters to the git clone command.

Create/Get CodeCommit Repository

The first step in this demo is to create a CodeComit repository, or to query the https endpoint of an existing CodeCommit repo you might already have.

Set up parameters:

repository_name=...   # Your repository name
repository_description=$repository_name   # Or more descriptive
region=us-east-1

If you don’t already have a CodeCommit repository, you can create one using a command like:

repository_endpoint=$(aws codecommit create-repository \
  --region "$region" \
  --repository-name "$repository_name" \
  --repository-description "$repository_description" \
  --output text \
  --query 'repositoryMetadata.cloneUrlHttp')
echo repository_endpoint=$repository_endpoint

If you already have a CodeCommit repository set up, you can query the https endpoint using a command like:

repository_endpoint=$(aws codecommit get-repository \
  --region "$region" \
  --repository-name "$repository_name" \
  --output text \
  --query 'repositoryMetadata.cloneUrlHttp')
echo repository_endpoint=$repository_endpoint

Now, let’s clone the repository locally, using our IAM credentials. With this method, there’s no need to upload ssh keys or modify the local ssh config file.

git clone

The git command line client allows us to specify specific config options to use for a clone operation and will add those config settings to the repository for future git commands to use.

Each repository can have a specific aws-cli profile that you want to use when interacting with the remote CodeCommit repository through the local Git clone. The profile can specify a cross-account IAM role to assume, as I mentioned at the beginning of this article. Or, it could be a profile that specifies AWS credentials for an IAM user in a different account. Or, it could simply be "default" for the main profile in your aws-cli configuration file.

Here’s the command to clone a Git repository from CodeCommit, and for authorized access, associate it with a specific aws-cli profile:

profile=$AWS_DEFAULT_PROFILE   # Or your aws-cli profile name

git clone \
  --config 'credential.helper=!aws codecommit --profile '$profile' --region '$region' credential-helper $@' \
  --config 'credential.UseHttpPath=true' \
  $repository_endpoint
cd $repository_name

At this point, you can interact with the local repository, pull, push, and do all the normal Git operations. When git talks to CodeCommit, it will use aws-cli to authenticate each request transparently, using the profile you specified in the clone command above.

Clean up

If you created a CodeCommit repository to follow the example in this article, and you no longer need it, you can wipe it out of existence with this command:

# WARNING! DESTRUCTIVE! CAUSES DATA LOSS!
aws codecommit delete-repository \
  --region "$region" \
  --repository-name $repository_name

You might also want to delete the local Git repository.

With the https access method in CodeCommit, there is no need to need upload or to delete any uploaded ssh keys from IAM, as all access control is performed seamlessly through standard AWS authentication and authorization controls.

Resources

Here are some other articles that talk about CodeCommit and the aws-cli credential-helper.

In Setup Steps for HTTPS Connections to AWS CodeCommit Repositories on Linux, AWS explains how to set up the aws-cli credential-helper globally so that it applies to all repositories you clone locally. This is the simplistic setting that I started with before learning how to apply the config rules on a per-repository basis.

In Using CodeCommit and GitHub Credential Helpers, James Wing shows how Amazon’s instructions cause problems if you have some CodeCommit repos and some GitHub repos locally and how to fix them (globally). He also solves problems with Git credential caches for Windows and Mac users.

In CodeCommit with EC2 Role Credentials, James Wing shows how to set up the credential-helper system wide in cloud-init, and uses CodeCommit with an IAM EC2 instance role.

[Update 2020-03-06: Added link to Amazon’s setting-up-git-remote-codecommit git helper]