Comment déchiffrer les states Terraform stockés dans le backend GitLab
En supposant que vous utilisez la fonctionnalité de stockage des states Terraform dans GitLab dans votre instance managée et que vous utilisez l'utilitaire intégré de sauvegarde fourni par GitLab.
Les fichiers de state Terraform sont chiffrés avant d'être stockés. Cela signifie que vous ne pouvez pas récupérer leur contenu à froid. À cette fin, GitLab utilise applications secrets (et dérive de nouveaux secrets à partir de ces clés si nécessaire) pour chiffrer le contenu sensible.
Vous souhaitez récupérer le contenu d'un fichier de state à partir d'une sauvegarde GitLab. Comme expliqué dans cette issue, il n'est pas possible de récupérer facilement un contenu déchiffré si l'instance est hors ligne.
Procédure de récupération
Récupération des secrets d'instance GitLab
En utilisant la documentation GitLab sur les secrets d'application, vous devez récupérer la valeur de db_key_base
.
Récupération des informations du projet
Le stockage des states Terraform est lié à un projet GitLab. Si le projet existe toujours dans votre instance, enregistrez le project_id
pour plus tard.
Si vous avez supprimé le projet, nous aurons besoin de la sauvegarde de la base de données (également stockée dans la sauvegarde GitLab).
Commencez par rechercher dans la table public.routes
votre projet. Vous pouvez filtrer par source_type=Project
et path=path/of/your/project
. Notez la valeur dans la colonne namespace_id
.
Regardez ensuite la table public.projects
filtrant le namespace_id
récupéré juste avant. Notez l'id
du projet.
Calcul du chemin de stockage du state
Les states sont stockés avec un chemin haché.
La première partie est la somme hash256 du projet id
. Vous pouvez utiliser la commande suivante pour le calculer :
La deuxième partie peut être récupérée de la base de données dans la table public.terraform_states
. Filtrez par project_id
et le name
du state enregistrez le uuid
.
Le chemin complet du dossier contenant le fichier de state est maintenant :
Si vous avez activé le versionning, le state est stocké avec le nom de fichier <serial_number>.tfstate
Récupération du contenu
C'est la partie la plus difficile et vous devez être un peu familier avec Ruby.
GitLab utilise un outil nommé Lockbox pour chiffrer le contenu du state de Terraform avant de le stocker. Nous allons utiliser le même outil pour déchiffrer nos fichiers.
Compléter et utilisez le script suivant :
#################
# Configuration #
#################
# Retreived from GitLab rails secrets
# https://docs.gitlab.com/ee/development/application_secrets.html
# This is a dummy key base. Don't bother using it
db_key_base = "<FILL_DB_KEY_BASE>"
# The project ID in GitLab
project_id = "<FILL_PROJECT_ID>"
# The file to decrypt
input_file = "<FILL_ENCRYPTED_STATE_FILE_PATH>"
# The file where to write the terraform state content
output_file = "<FILL_DECRYPTED_STATE_FILE_PATH>"
#############
# ALGORITHM #
#############
# Compute encryption key
key = OpenSSL::HMAC.digest('SHA256', db_key_base, project_id)
# Generate LockBox tool
# https://github.com/ankane/lockbox
lockbox = Lockbox.new(key: key)
encrypted_state_content = File.binread(input_file)
state_content = lockbox.decrypt_str(encrypted_state_content)
File.write(output_file, state_content)
Je ne suis pas un expert en Ruby mais voici un simple script bash pour configurer le bon environnement :
#!/bin/bash
rails new myapp
cd myapp/
echo 'gem "lockbox"' >> Gemfile
bundle install
bundle exec rails runner decode.rb