Git and SourceTree setup with AWS federation on Windows
Tags: git, aws, tutorial, windows
Published: 2019-02-21 15:54:22

---
title: Git and SourceTree setup with AWS federation on Windows
published: true
tags: git,aws,tutorial,windows
canonical_url: https://katiekodes.com/git-aws-federation/
---

Do you have "single sign-on" for your Amazon Web Services accounts, but need to set up your computer to talk to their CodeCommit git repository hosting?<br/><br/>If you have Windows, Python, and Git installed on your computer, here's how you can do so without messing up any other plain-old-username-and-password repositories you connect to!

I didn't figure any of this out -- I'm just transcribing it "for dummies"<br/>_(i.e. my future self when my computer gets replaced)_.

## Summary

Here's the guts of what we're going to do to tell Git how to talk to Amazon:

1. We'll set up an easy way of putting fresh contents into `c:\users\MY_USERNAME\.aws\credentials` once an hour<br/>_(that is, we'll make it easy to run a 300-line Python script dedicated to giving us a nice little "username" & "password" prompt)_
2. We'll tell our Git installation that any repositories hosted at AWS CloudCommit should use the AWS CLI to facilitate login, not a username and password, but to go ahead and use username and password for everything else
3. We'll install the "AWS CLI" onto our computers and tell Git how to find it when executing the command "`aws`"

### Level:  intermediate+

Not everything is covered here.  I'm going to presume you have the experience necessary to do the following things on your own and that you have admin access to your computer to facilitate software installation:

1. Use command lines comfortably
2. Set up Git / SourceTree and establish a working relationship between a repository on your hard drive and an ordinary "remote" repository on another machine _(when connecting to the "remote" is as simple as entering a username and password as prompted by Git or SourceTree, anyway)_
3. Edit your Windows "PATH" environment variables
4. Set up Python on your computer and demonstrate that your computer is capable of executing `print('Hello World')` _(even if just through an IDE like Spyder)_
5. Install Python modules you don't yet have as part of your Python installation with the `pip` command in whatever command-line environment you installed / configured to be able to run `pip` _(e.g. "Anaconda Prompt")_

---

![Screenshot of a web browser's URL bar](https://katiekodes.com/images/urlbar.png)

## Getting the URL for your repository

1. There's just "N. Virginia" ("East 1") where all of CodeCommit lives now.  So the URL to see your repositories is:<br/>https://console.aws.amazon.com/codecommit/home?region=us-east-1
2. Although first, to log in, you may have to go to:<br/>https://SOME-SORT-OF-WEB-SITE-YOUR-COMPANY-GIVES-YOU.com
3. In the left nav, expand "Source" and click on "Repositories"<br/>https://console.aws.amazon.com/codesuite/codecommit/repositories?region=us-east-1
4. Find a repository you have access to and click it.<br/>https://console.aws.amazon.com/codesuite/codecommit/repositories/OUR_AWESOME_REPOSITORY/browse?region=us-east-1
5. Far right, near the top of the page but not in the top nav, there's a button with a drop-down that says "Clone URL."<br/>Drop it down and pick "Connection Steps."<br/>https://console.aws.amazon.com/codesuite/codecommit/repositories/OUR_AWESOME_REPOSITORY/connect?region=us-east-1
6. **If you see a warning at the top of the instructions with the following text, this blog post is for you!**
> You are signed in using federated access or temporary credentials.  The only supported connection method for these sign-in types is to use the credential manager included with the AWS CLI, as documented below.  To configure a connection using SSH or Git credentials over HTTPS, sign in as an IAM user.
7. There should still be a "Clone URL" drop-down in about the same area of the page as it was on the last page.<br/>Drop it down and pick "Clone HTTPS."
8. A green alert bar should appear at the top of the page under the top-nav saying:
> Copied
> 
> https://git-codecommit.us-east-1.amazonaws.com/v1/repos/OUR_AWESOME_REPOSITORY
9. Put that URL for your repository somewhere ... you'll need it later.

---

![Git logo](https://git-scm.com/images/logos/downloads/Git-Logo-2Color.png)

## Install Git & SourceTree on your computer, if you haven't

Test that your Git setup is working with some "ordinary" remote repository you've already had working in the past.

* Use "`git fetch --all`" with the Git Bash command-line interface, make sure you get prompted for a password, and save
* Edit a post in a readme or a blog, pushing the changes to SourceTree, and make sure they go live

Get all that sorted out if even that doesn't work.

---

![Screenshot of a gitconfig file icon](https://katiekodes.com/images/gitconfig-fileicon.png)

## Edit your Git installation's "global" GitConfig file

You're going to need to edit your "global" GitConfig file to include these lines:

```
[credential]
	helper = 

[credential "https://github.com"]
	helper = 

[credential "https://bitbucket.org"]
	helper = 
	
[credential "https://git-codecommit.us-east-1.amazonaws.com"]
	helper = "!aws codecommit credential-helper "
	UseHttpPath = true
```

Mine was stored in the **`C:\users\MY_USERNAME\`** folder, and was a file called **`.gitconfig`**

**Test your git setup with "ordinary" remotes again** to make sure you didn't break anything.

_(Close & re-open SourceTree after saving your GitConfig contents and before testing.)_

Instead of "`helper = `," you can say "`helper = wincred`" for GitHub and BitBucket if you _**don't**_ want the Git Bash to prompt you for a password every time you do a `fetch`, `push`, `pull`, `clone`, etc.

If you ever realize you regret storing your password for a given account in the Windows Credential Manager, just type the Windows Key, start searching "**manage windo...**," and click the Control Panel app "**Manage Windows Credentials**."  You can go through the list and delete your credentials against a given repository there.

---

![Screenshot of an Admit One ticket](https://katiekodes.com/images/admitone.png)

## Getting an hourly token from AWS

[Tim Sullivan built a handy Python script](https://github.com/tjsullivan1/aws_saml_auth) that lets you fetch a fresh credential from AWS and dump it onto the part of your hard drive that AWS's "command line interface" tool looks for such things, called "**`aws_saml_auth.py`**."

_(You'll need to edit the value of `idpentryurl` on line 34, as the script on GitHub is tailored to the employer he was working for when he wrote the script.)_

I don't have "Python" added to my path, so running a given Python script from my command line looks a bit absurd right now:

```
c:\users\MY_USERNAME\AppData\Local\Continuum\anaconda3\python.exe c:\users\MY_USERNAME\Desktop\auth_saml\aws_saml_auth.py
```

If I put Python into my Windows "PATH" environment variable and executed the command from within the same folder that I'd put "`aws_saml_auth.py`," I could have simply executed the following command:

```
python aws_saml_auth.py
```

Presuming my Python installed has all the modules that "`aws_saml_auth.py`" refers to installed _(look up `pip install`)_, running this script on a command-line interface should ask me for my username & password _(it's my single-sign-on credentials for checking my work e-mail ... with the "@CompanyName.com" at the end of the username)_.

If I type the correct values, I'll see the following output, telling me that there's a new folder on my hard drive under **`C:\Users\MY_USERNAME\`** called **`.aws`** with a file called **`credentials`** _(no file extension)_ in it whose contents will be good for signing into Amazon for the next hour _(after which, I'll have to run this Python script again to generate fresh contents for "`credentials`")_:

```
----------------------------------------------------------------
Your new access key pair has been stored in the AWS configuration file C:\Users\MY_USERNAME\.aws\credentials under the default profile.
Note that it will expire at 2019-02-20 19:35:01+00:00.
After this time, you may safely rerun this script to refresh your access key pair.
If you specified a credential other than default, to use this credential, call the AWS CLI with the --profile option (e.g. aws --profile default ec2 describe-instances).
----------------------------------------------------------------
```

Note that it says the word "`default`" in lines 1 and 4 because that's what "`aws_saml_auth.py`" says to do in line 87: 🤷‍♀️

```python
profile: ("The name of the profile we want to put it the credential file", 'option', 'p')='default',
```

You'll need to to run this Python script once an hour or so.

Therefore, you might find it handy to add a command to your command-line environment called "`awslogin`" as a shortcut to pull up the username & password prompt any time you notice "`git fetch`," etc. isn't working against an AWS-hosted repository that uses "federated" login.

My colleague set it up as a command called "`login`" that only worked within the "Git Bash" command-line interface by going to `C:\Program Files\Git\usr\bin\` and creating a new file in it called "`login`" _(no file extension)_ whose contents are:

```
python /usr/bin/aws_saml_auth.py
```

_(In his case, he had saved "`aws_saml_auth.py`" into `C:\Program Files\Git\usr\bin\`, and "`python`" was part of his PATH.)_

---

![CodeCommit](https://katiekodes.com/images/awscodecommitlogo.png)

## Installing the AWS CLI so that Git's attempt to execute the command "`aws codecommit credential-helper`" actually works

Now we need to install the AWS CLI so that Git's attempt to execute the command "`aws codecommit credential-helper`" actually works.

Otherwise, Git Bash / SourceTree will dutifully follow our instructions to "use the command '`aws`' instead of username and password for AWS CloudCommit remotes," then "fall back" to prompting for a username & password _(which won't work, because Amazon doesn't allow that for "federated" logins)_.

Let's [download the AWS CLI installer](https://docs.aws.amazon.com/cli/latest/userguide/install-windows.html#install-msi-on-windows), install it, and [add "`aws`" to our PATH environment variable](https://docs.aws.amazon.com/cli/latest/userguide/install-windows.html#awscli-install-windows-path).

In my case, the AWS CLI installer took care of the PATH environment variable for me:  it added `C:\Program Files\Amazon\AWSCLI\bin\` to the system-wide PATH.

If I open up a standard Windows command prompt _(Windows key -> type "`cmd`" and hit Enter)_, and if I type "`aws --version`," I get an answer about what version of the AWS CLI is installed on my computer.

However, Git _**still**_ doesn't _quite_ understand what "`aws`" is supposed to mean.

I can see that I have this problem because if I open up the "Git Bash" CLI and type "`aws --version`," I got an "aws: command not found" complaint.

To fix that, I added a file called "**`aws`**" _(with no file extension)_ to `C:\Program Files\Git\bin` whose contents are:

```
C:\Program Files\Amazon\AWSCLI\bin\aws.cmd
```

_([Thanks, Stack Overflow](https://stackoverflow.com/questions/53015630/bash-aws-command-not-found-on-windows-7-in-git-bash).)_

I think that's what made it suddenly start working, anyway.

I'm a little nervous that isn't it, because now that I've gotten it working, if I erase the contents of this file, `aws --version` still works.

Anyway, as soon as "`aws --version`" works from the Git Bash CLI, I should be good to go!

1. I have a way of putting fresh contents into `c:\users\MY_USERNAME\.aws\credentials` once an hour
2. I've told Git that any repositories hosted at AWS CloudCommit use the AWS CLI to facilitate login, not a username and password, but to go ahead and use username and password for everything else
3. I've installed the AWS CLI onto my computer and told Git how to find it

---

![Photo of a clock](https://katiekodes.com/images/goldclock.jpg)

## Detecting and fixing expired credentials

Unfortunately, getting all this set up and blogging about it took so much troubleshooting to figure out, my 1-hour credentials from Amazon expired, so I may need to run "`aws_saml_auth.py`" from a command line again and update the contents of `c:\users\MY_USERNAME\.aws\credentials` with a fresh token.

Expired credentials looked like this when doing a `git fetch --all` in the Git Bash CLI against a repo I'd gotten everything working for earlier:

```
MY_USERNAME@MY_COMPUTER_ID MINGW64 ~/Desktop/aws_test3/test_repo_3 (master)
$ git fetch --all
Fetching origin
fatal: unable to access 'https://git-codecommit.us-east-1.amazonaws.com/v1/repos/OUR_AWESOME_REPOSITORY/': The requested URL returned error: 403
error: Could not fetch origin
```

In SourceTree, right-clicking on "origin" beneath "Remotes" in the left-nav and clicking "Fetch from origin" gave me the following error:

```
git -c diff.mnemonicprefix=false -c core.quotepath=false fetch origin
fatal: unable to access 'https://git-codecommit.us-east-1.amazonaws.com/v1/repos/OUR_AWESOME_REPOSITORY/': The requested URL returned error: 403
Completed with errors, see above.
```

A successful fetch in the Git Bash looks like this:

```
MY_USERNAME@MY_COMPUTER_ID MINGW64 ~/Desktop/aws_test3/test_repo_3 (master)
$ git fetch --all
Fetching origin

MY_USERNAME@MY_COMPUTER_ID MINGW64 ~/Desktop/aws_test3/test_repo_3 (master)
```

And in SourceTree, the progress bar just goes away, unless you have "Show Full Output" checked, in which case the output looks like this:

```
git -c diff.mnemonicprefix=false -c core.quotepath=false fetch origin
Completed successfully.
```

---

![Git logo](https://git-scm.com/images/logos/downloads/Git-Logo-2Color.png)

## Running your first working `git` command against AWS

Of course, it was a bit presumptuous of me to presume you'd be doing a "`git fetch`" -- that implies you had a remote-local pair set up in the first place.  :-)

Remember that URL we got from Amazon waaaaay back at the beginning?

```
https://git-codecommit.us-east-1.amazonaws.com/v1/repos/OUR_AWESOME_REPOSITORY
```

Let's set up 2 local repositories on our computer, each using it as a "remote" -- one with the "Git Bash" CLI _(or with our Windows CLI if we set it up to be able to execute "git" commands when we installed Git)_, and the other with SourceTree.

### Clone with Git Bash

1. Create a new folder on your hard drive, `c:\example\`
2. Do `cd c:\example` in the Git Bash command prompt
3. Do `git clone https://git-codecommit.us-east-1.amazonaws.com/v1/repos/OUR_AWESOME_REPOSITORY aws_test_1`

The output should look something like this, and you should have a new `c:\example\aws_test_1\` folder on your computer.  There should be files in it, if there were files in the remote.

```
MY_USERNAME@MY_COMPUTER_ID MINGW64 /c/example
$ git clone https://git-codecommit.us-east-1.amazonaws.com/v1/repos/OUR_AWESOME_REPOSITORY aws_test_1
Cloning into 'aws_test_1'...
remote: Counting objects: 3, done.
Unpacking objects: 100% (3/3), done.
```

### Clone with SourceTree

1. Click the "+" by the tabs of your open repositories, near the top, and in the big buttons near the top of the "Local Repositories" screen, click the "Clone" button with an icon that looks like an arrow pointing into an open box.
2. In "Source Path / URL," type: `https://git-codecommit.us-east-1.amazonaws.com/v1/repos/OUR_AWESOME_REPOSITORY`
3. In "Destination Path," type:  `C:\example\aws_test_2`
4. In "Name," type:  `Best AWS Test 2`
5. Click the "Clone" button

If you don't check the "Show Full Output" checkbox of the progress bar, it might just disappear when done.  But if you do, its log will look something like this:

```
git -c filter.lfs.smudge= -c filter.lfs.required=false -c diff.mnemonicprefix=false -c core.quotepath=false clone --branch master https://git-codecommit.us-east-1.amazonaws.com/v1/repos/OUR_AWESOME_REPOSITORY C:\example\aws_test_2
Cloning into 'C:\example\aws_test_2'...
warning: templates not found in C:\Program Files\Git\share\git-core\templates

remote: 
remote: Counting objects: 0
remote: Counting objects: 3
remote: Counting objects: 3
remote: Counting objects: 3, done.        
Completed successfully.
```

In the left nav, if you click "Branches" and click "master" _(or whatever your branch is called)_, you should be able to see the full commit-log history from the remote copy of the repository _(that is, AWS)_, presuming there is any history.

You should have a new `c:\example\aws_test_2\` folder on your computer.  There should be files in it, if there were files in the remote.

CONGRATULATIONS, YOU'RE IN!

Happy git-ting!

---

![Stack of books](https://upload.wikimedia.org/wikipedia/commons/thumb/1/1c/Book_sale_loot_%284552277923%29.jpg/800px-Book_sale_loot_%284552277923%29.jpg)

## Further Resources

* [Using CodeCommit and GitHub Credential Helpers](https://jameswing.net/aws/using-codecommit-and-git-credentials.html) by James Wing