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!

The power of full-stack monitoring

There is this magic sense of confidence you get when a status dashboard is all green. Suddenly, a highly complex system with dozens or hundred of modules, is saying ‘well, so far so good’. Visually alive in front of you, showing how many users are connected, how many transactions are being generated and how many resources are used to serve all that.

blog_2_01

Otherwise, the only way you’ll find out when something is wrong, is that angry customer’s call notifying that your system is down, and you didn’t know. Not anyone’s idea of a happy day.

Continue reading The power of full-stack monitoring

Custom Postgres metrics in Datadog

Instrumenting applications is something we are used to at Bithaus. Having the code reporting itself delivers great information, and every person involved in the system from developers, operations and managers appreciate it.

But you cannot always change the code to get metrics, or not as fast as you would like to.

An excellent way to gather business metric of your application, is to look in your tables in the database. Continue on reading for step-by-step on how to create a custom metric based on a SQL query, so we can display it on a dashboard and create monitors to check it’s value.

Continue reading Custom Postgres metrics in Datadog