Configurar GIT para AWS Codecommit

Para acceder a repositorios en CodeCommit a través de git, se requiere configurar git para que utilice el comando de consola de AWS como “ayudante de autenticación”, es decir, que “aws” genere un usuario/clave al vuelo que pueda utilizar git para la operación contra el repositorio.

Es muy común que intentando descargar repositorios desde AWS con Git nos topemos con el siguiente mensaje error:

fatal: unable to access 'https://git-codecommit.us-east-1.amazonaws.com/v1/repos/mi-repositorio/': The requested URL returned error: 403

Veamos a continuación como solucionar este problema y configurar correctamente nuestro entorno para usar AWS Codecommit con Git.

 

Paso 1 – Obtener las credenciales

Opción 1: desde la consola AWS, IAM user, obtener aws_access_key_id, aws_secret_acces_key. Más información AQUI.

Opción 2: usar el plugin de chrome SAML to AWS STS Key para descargar la llave que se genera para el navegador cuando se hace login.

 

Paso 2 – Incluir las credenciales en el archivo de credenciales de AWS 

El archivo ~/.aws/credentials contiene las credenciales AWS presentes en la cuenta local. Ahí crear una sección con un nombre que identifique al perfil:

[mi-perfil]
aws_access_key_id = ASIASP6...
aws_secret_access_key = Kb5ufJqwJ1t…..
aws_session_token = FwoGZXIvYXdzECcaD…...

Se puede validar el acceso correcto listando los repositorios con el siguiente comando. Reemplazar la región (us-east-1 en este ejemplo) por la que corresponda.

aws --profile mi-perfil --region us-east-1 codecommit list-repositories

Resultado:

{
    "repositories": [
        {
            "repositoryName": "mi-repositorio",
            "repositoryId": "aaaaa-bbbb-cccc-dddd-eeeeeeeee"
        },
        (...)
    ]
}

 

Paso 3 – Configurar el uso del perfil para acceder a los repositorios AWS

Se debe indicar a GIT que se quiere utilizar un “credential helper” para acceder a los repositorios de AWS Codecommit, pero que no esté disponible para el resto, de lo contrario no podríamos acceder correctamente a Github o repos privados.

Para personalizar que repositorios usarán que credential helper, editamos el archivo de configuración git global del usuario ~/.gitconfig. Agregamos las siguientes líneas para los repos AWS Codecommit que se estén usando. Si se tiene más de una región, hay que agregar una sección por cada una.

[credential "https://git-codecommit.us-east-1.amazonaws.com"]
        helper = !aws --profile mi-perfil codecommit credential-helper $@
        UseHttpPath = true

 

Aquí se indica que para los repositorios de la región us-east-1 se utilice el perfil mi-perfil de la configuración de llaves AWS.

Con esto podemos realizar operaciones contra el repo Codecommit a través de Git, por ejemplo un clone: 

git clone https://git-codecommit.us-east-1.amazonaws.com/v1/repos/mi-repositorio

 

Niveles de configuración GIT – Problemas para configurar credential helper

Git tiene varios niveles de configuración que se sobreponen para armar el conjunto de parámetros que se utilizando en cada ejecución. Según la documentación, la precedencia de las configuraciones va desde lo más general hasta lo particular:

1. Nivel “system” – Todo el sistema operativo
Linux: /etc/gitconfig
OSX: /Applications/Xcode.app/Contents/Developer/usr/share/git-core/gitconfig

2. Nivel “global” (usuario)
~/.gitconfig

3. Nivel “local” (repositorio)
.git/config

Así, se pueden definir configuraciones generales a nivel sistema o para el usuario, a la vez que se personalizan otras para un repositorio en particular.

Para listar las configuraciones vigentes de git, se puede usar el siguiente comando dentro de un repositorio local para que muestra cada parámetro y el archivo de origen desde donde lo obtiene.

jmakuc$ git config --show-origin -l
file:/Applications/Xcode.app/Contents/Developer/usr/share/git-core/gitconfig credential.helper=osxkeychain
file:/Users/jmakuc/.gitconfig core.excludesfile=/Users/jmakuc/.gitignore_global
file:/Users/jmakuc/.gitconfig user.name=Jonathan Makuc
file:/Users/jmakuc/.gitconfig user.email=jmakuc@bithaus.cl
file:/Users/jmakuc/.gitconfig commit.template=/Users/jmakuc/.stCommitMsg
file:/Users/jmakuc/.gitconfig credential.https://git-codecommit.us-east-1.amazonaws.com.helper=!aws --profile mi-perfil codecommit credential-helper $@
file:/Users/jmakuc/.gitconfig credential.https://git-codecommit.us-east-1.amazonaws.com.usehttppath=true
file:.git/config core.repositoryformatversion=0
file:.git/config core.filemode=true
file:.git/config core.bare=false
file:.git/config core.logallrefupdates=true
file:.git/config core.ignorecase=true
file:.git/config core.precomposeunicode=true
file:.git/config remote.origin.url=https://git-codecommit.us-east-1.amazonaws.com/v1/repos/mi-repositorio
file:.git/config remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
file:.git/config branch.development.remote=origin
file:.git/config branch.development.merge=refs/heads/development

Aquí podemos ver que hay 2 archivos origen desde donde se define el parámetro “credential.helper”. El primero es el nivel sistema que indica el keychain de OSX. El segundo a nivel “global” del usuario, que indica al comando AWS como proveedor de autenticación.

En mi caso, Git no quiso tomar la configuración global (usuario) para sobreescribir el valor de sistema, por tanto las operaciones contra el repositorio AWS fallaban.

Para detectar el problema, es útil activar el “trace” de Git a través del siguiente comando:

 export GIT_TRACE=1

Con esto, se puede ver que aunque la configuración global (usuario) tiene un credential helper, el comando está tomando la configuración de sistema.

jmakuc$ git fetch
10:51:43.335023 git.c:340 trace: built-in: git 'fetch'
10:51:43.337159 run-command.c:626 trace: run_command: 'git-remote-https' 'origin' 'https://git-codecommit.us-east-1.amazonaws.com/v1/repos/mi-repositorio'
10:51:43.996457 run-command.c:626 trace: run_command: 'git credential-osxkeychain get'
10:51:44.003678 git.c:572 trace: exec: 'git-credential-osxkeychain' 'get'
10:51:44.004250 run-command.c:626 trace: run_command: 'git-credential-osxkeychain' 'get'
fatal: unable to access 'https://git-codecommit.us-east-1.amazonaws.com/v1/repos/mi-repositorio/': The requested URL returned error: 403

Si bien se puede editar el archivo nivel sistema y quitar la configuración que usa el Keychain, es poco conveniente para el resto de los repositorios que se tengan en el ambiente. Es mejor deshabilitar el uso de la configuración nivel sistema para esta sesión de terminal:

export GIT_CONFIG_NOSYSTEM=1

Así, la configuración que muestra Git solo tiene los parámetros “global” (usuario) y “local”:

jmakuc$ git config --show-origin -l
file:/Users/jmakuc/.gitconfig core.excludesfile=/Users/jmakuc/.gitignore_global
file:/Users/jmakuc/.gitconfig user.name=Jonathan Makuc
file:/Users/jmakuc/.gitconfig user.email=jmakuc@bithaus.cl
file:/Users/jmakuc/.gitconfig commit.template=/Users/jmakuc/.stCommitMsg
file:/Users/jmakuc/.gitconfig credential.https://git-codecommit.us-east-1.amazonaws.com.helper=!aws --profile mi-perfil codecommit credential-helper $@
file:/Users/jmakuc/.gitconfig credential.https://git-codecommit.us-east-1.amazonaws.com.usehttppath=truefile:.git/config core.repositoryformatversion=0
file:.git/config core.filemode=true
file:.git/config core.bare=false
file:.git/config core.logallrefupdates=true
file:.git/config core.ignorecase=true
file:.git/config core.precomposeunicode=true
file:.git/config remote.origin.url=https://git-codecommit.us-east-1.amazonaws.com/v1/repos/mi-repositorio
file:.git/config remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
file:.git/config branch.development.remote=origin
file:.git/config branch.development.merge=refs/heads/development

Finalmente, el comando Git funciona! 😀

jmakuc$ git fetch
11:18:49.014356 git.c:340 trace: built-in: git 'fetch'
11:18:49.039127 run-command.c:626 trace: run_command: 'git-remote-https' 'origin' 'https://git-codecommit.us-east-1.amazonaws.com/v1/repos/mi-repositorio'
11:18:49.763053 run-command.c:626 trace: run_command: 'aws codecommit credential-helper $@ get'
11:18:51.022539 run-command.c:626 trace: run_command: 'aws codecommit credential-helper $@ store'
11:18:51.596029 run-command.c:626 trace: run_command: 'aws codecommit credential-helper $@ store'
11:18:52.164858 run-command.c:626 trace: run_command: 'rev-list' '--objects' '--stdin' '--not' '--all' '--quiet'
11:18:52.185185 run-command.c:626 trace: run_command: 'rev-list' '--objects' '--stdin' '--not' '--all' '--quiet'
11:18:52.188531 git.c:340 trace: built-in: git 'rev-list' '--objects' '--stdin' '--not' '--all' '--quiet'
11:18:52.200980 run-command.c:1452 run_processes_parallel: preparing to run up to 1 tasks
11:18:52.201074 run-command.c:1484 run_processes_parallel: done
11:18:52.201234 run-command.c:626 trace: run_command: 'gc' '--auto'
11:18:52.206087 git.c:340 trace: built-in: git 'gc' '--auto'

 

No es tan complicado cuando sabemos como funciona 🙂

Enjoy!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s