*L'auteur a choisi le Free and Open Source Fund comme récipiendaire d'une donation dans le cadre du programme Write for Donations.*

Introduction

Vault, de Hashicorp, est un outil open-source permettant de stocker en toute sécurité des secrets et des données sensibles dans des environnements cloud dynamiques. Il offre un cryptage solide des données, un accès basé sur l'identité à l'aide de politiques personnalisées, ainsi qu'une location et une révocation secrètes, de même qu'un journal d'audit détaillé, enregistré à tout moment. Vault dispose également d'une API HTTP, ce qui en fait le choix idéal pour le stockage d'identifiants dans des déploiements dispersés orientés sur les services tels que Kubernetes.

Packer et Terraform, également développés par Hashicorp, peuvent être utilisés ensemble pour créer et déployer des images de Vault. Dans le cadre de ce flux de travail, les développeurs peuvent utiliser Packer pour écrire des images immuables pour différentes plateformes à partir d'un seul fichier de configuration qui spécifie ce que l'image doit contenir. Terraform déploiera ensuite le nombre requis d'instances personnalisées des images créées.

Dans ce tutoriel, vous utiliserez Packer pour créer un instantané immuable du système avec Vault installé, et orchestrer son déploiement à l'aide de Terraform. Au final, vous disposerez d'un système automatisé pour le déploiement de Vault, ce qui vous permettra de vous concentrer sur le travail avec Vault lui-même et non sur le processus d'installation et d'approvisionnement sous-jacent.

Conditions préalables

cloud provider illustration for: Conditions préalables
  • Un jeton d'accès personnel (clé API) avec des droits en lecture et en écriture pour votre compte the cloud provider. Pour savoir comment en créer un, consultez le tutoriel Comment créer un jeton d'accès personnel de la documentation.
  • Une clé SSH que vous utiliserez pour vous authentifier avec les droplets Vault déployées ; elle est disponible sur votre machine locale et ajoutée à votre compte the cloud provider. Vous aurez également besoin de l'empreinte digitale associée, que vous pourrez copier à partir de la page de sécurité de votre compte une fois que vous l'aurez ajoutée. Consultez la documentation de the cloud provider pour obtenir des instructions détaillées, ou encore le tutoriel Comment configurer les clés SSH.

Étape 1 - Création d'un modèle Packer

Dans cette étape, vous allez écrire un fichier de configuration Packer, appelé _modèle_, qui indiquera à Packer comment construire une image contenant Vault préinstallé. Vous allez écrire la configuration au format JSON, un format de fichier de configuration couramment utilisé, lisible par l'homme.

Aux fins de ce tutoriel, vous allez stocker tous les fichiers sous ~/vault-orchestration. Créez le répertoire en exécutant la commande suivante :

				
					
mkdir ~/vault-orchestration

				
			

Rendez-vous-y :

				
					
cd ~/vault-orchestration

				
			

Vous stockerez les fichiers de configuration pour Packer et Terraform séparément, dans des sous-répertoires différents. Créez-les en utilisant la commande suivante :

				
					
mkdir packer terraform

				
			

Comme vous allez d'abord travailler avec Packer, naviguez vers son répertoire :

				
					
cd packer

				
			

Utilisation des variables du modèle

Le stockage de données privées et de secrets d'application dans un fichier de variables séparé est le moyen idéal de les tenir à l'écart de votre modèle. Lors de la construction de l'image, Packer remplacera les variables référencées par leurs valeurs. Le codage en dur de valeurs secrètes dans votre modèle constitue un risque pour la sécurité, surtout s'il doit être communiqué aux membres de l'équipe ou affiché sur des sites publics tels que GitHub.

Vous les stockerez dans le sous-répertoire packer, dans un fichier appelé variables.json. Créez celui-ci avec votre éditeur de texte préféré :

				
					
nano variables.json

				
			

Ajoutez les lignes suivantes :

				
					
[label ~/vault-orchestration/packer/variables.json]

{

    "do_token": "<^>your_do_api_key<^>",

    "base_system_image": "ubuntu-18-04-x64",

    "region": "nyc3",

    "size": "s-1vcpu-1gb"

}

				
			

Le fichier de variables se compose d'un dictionnaire JSON, qui associe les noms de variables à leurs valeurs. Vous utiliserez ces variables dans le modèle que vous êtes sur le point de créer. Si vous le souhaitez, vous pouvez modifier les valeurs de l'image de base, de la région et de la taille des droplets, en fonction de la documentation des développeurs.

N'oubliez pas de remplacer <^>your_do_api_key<^> par votre clé API que vous avez créée dans le cadre des conditions préalables, puis enregistrez et fermez le fichier.

Créer des constructeurs et des fournisseurs

Le fichier de variables étant prêt, vous allez maintenant créer le modèle Packer lui-même.

Vous allez stocker le modèle Packer pour Vault dans un fichier nommé template.json. Créez celui-ci avec votre éditeur de texte :

				
					
nano template.json

				
			

Ajoutez les lignes suivantes :

				
					
[label ~/vault-orchestration/packer/template.json]

{

     "builders": [{

         "type": "the cloud provider",

         "api_token": "{{user `do_token`}}",

         "image": "{{user `base_system_image`}}",

         "region": "{{user `region`}}",

         "size": "{{user `size`}}",

         "ssh_username": "root"

     }],

     "provisioners": [{

         "type": "shell",

         "inline": [

             "sleep 30",

             "sudo apt-get update",

             "sudo apt-get install unzip -y",

             "curl -L &lt;^&gt;https://releases.hashicorp.com/vault/1.3.2/vault_1.3.2_linux_amd64.zip&lt;^&gt; -o vault.zip",

             "unzip vault.zip",

             "sudo chown root:root vault",

             "mv vault /usr/local/bin/",

             "rm -f vault.zip"

         ]

	}]

}

				
			

Dans le modèle, vous définissez des tableaux de _constructeurs_ et de _fournisseurs_. Les constructeurs indiquent à Packer comment construire l'image du système (en fonction de leur type) et où la stocker, tandis que les fournisseurs contiennent des ensembles d'actions que Packer doit effectuer sur le système avant de le transformer en une image immuable, comme l'installation ou la configuration de logiciels. Sans fournisseurs, vous vous retrouveriez avec une image du système de base inchangée. Les constructeurs et les fournisseurs exposent des paramètres pour une personnalisation plus poussée du flux de travail.

Vous définissez d'abord un constructeur unique du type the cloud provider, ce qui signifie que lorsqu'on lui commande de construire une image, Packer utilisera les paramètres fournis pour créer une droplet temporaire de la taille définie en utilisant la clé API fournie avec l'image du système de base spécifiée et dans la région spécifiée. Le format permettant de récupérer une variable est {{user '<^>variable_name<^>'}}, où la partie surlignée représente son nom.

Lorsque la droplet temporaire est fournie, le fournisseur se connectera à celle-ci en utilisant SSH avec le nom d'utilisateur spécifié, et exécutera séquentiellement tous les fournisseurs définis, avant de créer un instantané the cloud provider à partir de la droplet et de le supprimer.

Il est de type shell, qui va exécuter les commandes données sur la cible. Les commandes peuvent être spécifiées soit en ligne (sous la forme d'un tableau de chaînes de caractères), soit définies dans des fichiers de script séparés si leur insertion dans le modèle devient difficile en raison de leur taille. Les commandes du modèle attendront 30 secondes pour que le système démarre, puis téléchargeront et décompresseront Vault <^>1.3.2<^>. Consultez la page officielle de téléchargement de Vault et remplacez le lien présent dans les commandes par une version plus récente pour Linux, si disponible.

Lorsque vous avez terminé, enregistrez et fermez le fichier.

Pour vérifier la validité de votre modèle, exécutez la commande suivante :

				
					
packer validate -var-file=variables.json template.json

				
			

Packer accepte un chemin vers le fichier de variables via l'argument -var-file.

Vous verrez la sortie suivante :

				
					
[secondary_label Output]

Template validated successfully.

				
			

Si vous obtenez une erreur, Packer vous indiquera exactement où elle s'est produite afin que vous puissiez la corriger.

Vous disposez maintenant d'un modèle de travail qui produit une image avec Vault installé, avec votre clé API et d'autres paramètres définis dans un fichier séparé. Vous êtes prêt à appeler Packer et à construire l'instantané.

Étape 2 - Création de l'instantané

Dans cette étape, vous allez construire un instantané the cloud provider à partir de votre modèle en utilisant la commande Packer build.

Pour créer votre instantané, exécutez la commande suivante :

				
					
packer build -var-file=variables.json template.json

				
			

L'exécution de cette commande prendra un certain temps. Vous verrez beaucoup de sorties qui ressembleront à ceci :

				
					
[secondary_label Output]

the cloud provider: output will be in this color.



==&gt; the cloud provider: Creating temporary ssh key for droplet...

==&gt; the cloud provider: Creating droplet...

==&gt; the cloud provider: Waiting for droplet to become active...

==&gt; the cloud provider: Using ssh communicator to connect: ...

==&gt; the cloud provider: Waiting for SSH to become available...

==&gt; the cloud provider: Connected to SSH!

==&gt; the cloud provider: Provisioning with shell script: /tmp/packer-shell035430322

...

==&gt; the cloud provider:   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current

==&gt; the cloud provider:                                  Dload  Upload   Total   Spent    Left  Speed

    the cloud provider: Archive:  vault.zip

==&gt; the cloud provider: 100 45.5M  100 45.5M    0     0   154M      0 --:--:-- --:--:-- --:--:--  153M

    the cloud provider:   inflating: vault

==&gt; the cloud provider: Gracefully shutting down droplet...

==&gt; the cloud provider: Creating snapshot: packer-1581537927

==&gt; the cloud provider: Waiting for snapshot to complete...

==&gt; the cloud provider: Destroying droplet...

==&gt; the cloud provider: Deleting temporary ssh key...

Build 'the cloud provider' finished.



==&gt; Builds finished. The artifacts of successful builds are:

--&gt; the cloud provider: A snapshot was created: 'packer-1581537927' &lt;^&gt;(ID: 58230938)&lt;^&gt; in regions '...'

				
			

Packer enregistre toutes les étapes de la création de votre modèle. La dernière ligne contient le nom de l'instantané (tel que packer-1581537927) et son identifiant entre parenthèses, marqué en rouge. Notez votre ID de l'instantané, car vous en aurez besoin à l'étape suivante.

Si le processus de construction échoue à cause d'erreurs d'API, attendez quelques minutes puis réessayez.

Vous avez construit un instantané the cloud provider selon votre modèle. L'instantané contient Vault préinstallé, et vous pouvez maintenant déployer les droplets avec lui comme image système. Dans l'étape suivante, vous allez écrire la configuration de Terraform pour automatiser ces déploiements.

Étape 3 - Rédaction de la configuration de Terraform

Dans cette étape, vous allez écrire la configuration de Terraform pour automatiser les déploiements de droplets de l'instantané contenant Vault que vous venez de construire avec Packer.

Avant d'écrire la configuration réelle de Terraform pour le déploiement de Vault à partir de l'instantané construit précédemment, vous devrez d'abord configurer le fournisseur the cloud provider pour celui-ci. Naviguez vers le sous-répertoire terraform en exécutant :

				
					
cd ~/vault-orchestration/terraform

				
			

Ensuite, créez un fichier nommé do-provider.tf, où vous stockerez le fournisseur :

				
					
nano do-provider.tf

				
			

Ajoutez les lignes suivantes :

				
					
[label ~/vault-orchestration/terraform/do-provider.tf]

variable "do_token" {

}



variable "ssh_fingerprint" {

}



variable "instance_count" {

  default = "1"

}



variable "do_snapshot_id" {

}



variable "do_name" {

  default = "vault"

}



variable "do_region" {

}



variable "do_size" {

}



variable "do_private_networking" {

  default = true

}



provider "the cloud provider" {

  token = var.do_token

}

				
			

Ce fichier déclare les variables de paramètres et fournit au fournisseur the cloud provider une clé API. Vous utiliserez plus tard ces variables dans votre modèle Terraform, mais vous devrez d'abord spécifier leurs valeurs. Pour cela, Terraform permet de spécifier des valeurs de variables dans un fichier de _définitions de variables_, de façon similaire à Packer. Le nom de fichier doit se terminer par .tfvars ou .tfvars.json. Vous transmettrez plus tard ce fichier à Terraform en utilisant l'argument -var-file.

Enregistrez et fermez le fichier.

Créez un fichier de définitions de variables appelé definitions.tfvars en utilisant votre éditeur de texte :

				
					
nano definitions.tfvars

				
			

Ajoutez les lignes suivantes :

				
					
[label ~/vault-orchestration/terraform/definitions.tf]

do_token         = "&lt;^&gt;your_do_api_key&lt;^&gt;"

ssh_fingerprint  = "&lt;^&gt;your_ssh_key_fingerprint&lt;^&gt;"

do_snapshot_id   = &lt;^&gt;your_do_snapshot_id&lt;^&gt;

do_name          = "vault"

do_region        = "nyc3"

do_size          = "s-1vcpu-1gb"

instance_count   = 1

				
			

N'oubliez pas de remplacer <^>your_do_api_key<^>, <^>your_ssh_key_fingerprint<^>, et <^>your_do_snapshot_id<^> par la clé API de votre compte, l'empreinte digitale de votre clé SSH, et l'identifiant de l'instantané que vous avez noté à l'étape précédente, respectivement. Les paramètres do_region et do_size doivent porter les mêmes valeurs que dans le fichier de variables Packer. Si vous souhaitez déployer plusieurs instances en même temps, ajustez instance_count à la valeur souhaitée.

Lorsque vous avez terminé, sauvegardez et fermez le fichier.

Pour plus d'informations sur le fournisseur the cloud provider Terraform, consultez les documents officiels.

Vous allez stocker la configuration de déploiement de l'instantané de Vault dans un fichier nommé deployment.tf, sous le répertoire terraform. Créez celui-ci avec votre éditeur de texte :

				
					
nano deployment.tf

				
			

Ajoutez les lignes suivantes :

				
					
[label ~/vault-orchestration/terraform/deployment.tf]

resource "the cloud provider_droplet" "vault" {

  count              = var.instance_count

  image              = var.do_snapshot_id

  name               = var.do_name

  region             = var.do_region

  size               = var.do_size

  private_networking = var.do_private_networking

  ssh_keys = [

    var.ssh_fingerprint

  ]

}



output "instance_ip_addr" {

  value = {

    for instance in the cloud provider_droplet.vault:

    instance.id =&gt; instance.ipv4_address

  }

  description = "The IP addresses of the deployed instances, paired with their IDs."

}

				
			

Vous définissez ici une _ressource_ unique du type the cloud provider_droplet nommée vault. Ensuite, vous définissez ses paramètres en fonction des valeurs des variables et ajoutez une clé SSH (en utilisant son empreinte digitale) de votre compte the cloud provider à la ressource droplet. Enfin, vous output à la console les adresses IP de toutes les instances qui viennent d'être déployées.

Enregistrez et fermez le fichier.

Avant de faire quoi que ce soit d'autre avec votre configuration de déploiement, vous devrez initialiser le répertoire en tant que projet Terraform :

				
					
terraform init

				
			

Vous verrez la sortie suivante :

				
					
[secondary_label Output]



Initializing the backend...



Initializing provider plugins...



The following providers do not have any version constraints in configuration,

so the latest version was installed.



To prevent automatic upgrades to new major versions that may contain breaking

changes, it is recommended to add version = "..." constraints to the

corresponding provider blocks in configuration, with the constraint strings

suggested below.



* provider.the cloud provider: version = "~&gt; 1.14"



Terraform has been successfully initialized!



You may now begin working with Terraform. Try running "terraform plan" to see

any changes that are required for your infrastructure. All Terraform commands

should now work.



If you ever set or change modules or backend configuration for Terraform,

rerun this command to reinitialize your working directory. If you forget, other

commands will detect it and remind you to do so if necessary.

				
			

Lors de l'initialisation d'un répertoire en tant que projet, Terraform lit les fichiers de configuration disponibles et télécharge les plugins jugés nécessaires, tels qu'ils sont enregistrés dans la sortie.

Vous disposez maintenant de la configuration de Terraform à utiliser pour le déploiement de votre instantané Vault. Vous pouvez passer à la validation et au déploiement sur une Droplet.

Étape 4 - Déploiement de Vault à l'aide de Terraform

Dans cette section, vous allez vérifier votre configuration Terraform à l'aide de la commande validate. Une fois qu'elle aura été vérifiée avec succès, vous l'appliquerez et déploierez une droplet en conséquence.

Exécutez la commande suivante pour tester la validité de votre configuration :

				
					
terraform validate

				
			

Vous verrez la sortie suivante :

				
					
[secondary_label Output]

Success! The configuration is valid.

				
			

Ensuite, lancez la commande plan pour voir ce que Terraform va tenter pour fournir l'infrastructure en fonction de votre configuration :

				
					
terraform plan -var-file="definitions.tfvars"

				
			

Terraform accepte un fichier de définitions de variables via le paramètre -var-file.

Le résultat sera similaire à :

				
					
[secondary_label Output]

Refreshing Terraform state in-memory prior to plan...

The refreshed state will be used to calculate this plan, but will not be

persisted to local or remote state storage.





------------------------------------------------------------------------



An execution plan has been generated and is shown below.

Resource actions are indicated with the following symbols:

  + create



Terraform will perform the following actions:



  # the cloud provider_droplet.vault[0] will be created

  + resource "the cloud provider_droplet" "vault" {

		...

    }



Plan: 1 to add, 0 to change, 0 to destroy.



------------------------------------------------------------------------



Note: You didn't specify an "-out" parameter to save this plan, so Terraform

can't guarantee that exactly these actions will be performed if

"terraform apply" is subsequently run.

				
			

Le + vert au début de la ligne de la ressource "the cloud provider_droplet" "vault" signifie que Terraform va créer une nouvelle droplet appelée vault en utilisant les paramètres qui suivent. Ceci est correct, vous pouvez donc maintenant exécuter le plan en lançant l'application terraform :

				
					
terraform apply -var-file="definitions.tfvars"

				
			

Entrez yes (oui) lorsque cela vous est demandé. Après quelques minutes, la droplet terminera l'approvisionnement et vous verrez un résultat similaire à celui-ci :

				
					
[secondary_label Output]

An execution plan has been generated and is shown below.

Resource actions are indicated with the following symbols:

  + create



Terraform will perform the following actions:



  + the cloud provider_droplet.vault-droplet



...



Plan: 1 to add, 0 to change, 0 to destroy.



...



the cloud provider_droplet.vault-droplet: Creating...



...



Apply complete! Resources: 1 added, 0 changed, 0 destroyed.



Outputs:



instance_ip_addr = {

  "181254240" = "&lt;^&gt;your_new_server_ip&lt;^&gt;"

}

				
			

Dans la sortie, Terraform enregistre les actions qu'il a effectuées (dans ce cas, pour créer une droplet) et affiche son adresse IP publique à la fin. Vous l'utiliserez pour vous connecter à votre nouvelle droplet, lors de la prochaine étape.

Vous avez créé une nouvelle droplet à partir de l'instantané contenant Vault et vous êtes maintenant prêt à la vérifier.

Étape 5 - Vérification de votre droplet déployée

Dans cette étape, vous allez accéder à votre nouvelle droplet en utilisant SSH et vérifier que Vault a été installé correctement.

Si vous êtes sous Windows, vous pouvez utiliser un logiciel tel que Kitty ou Putty pour vous connecter à la droplet à l'aide d'une clé SSH.

Sur les machines Linux et macOS, vous pouvez utiliser la commande ssh déjà disponible pour vous connecter :

				
					
ssh root@&lt;^&gt;your_server_ip&lt;^&gt;

				
			

Répondez yes (oui) lorsque cela vous est demandé. Une fois que vous êtes connecté, lancez Vault en exécutant :

				
					
vault

				
			

Vous verrez sa sortie « aide », qui ressemble à ceci :

				
					
[secondary_label Output]

Usage: vault &lt;command&gt; [args]



Common commands:

    read        Read data and retrieves secrets

    write       Write data, configuration, and secrets

    delete      Delete secrets and configuration

    list        List data or secrets

    login       Authenticate locally

    agent       Start a Vault agent

    server      Start a Vault server

    status      Print seal and HA status

    unwrap      Unwrap a wrapped secret



Other commands:

    audit          Interact with audit devices

    auth           Interact with auth methods

    debug          Runs the debug command

    kv             Interact with Vault's Key-Value storage

    lease          Interact with leases

    namespace      Interact with namespaces

    operator       Perform operator-specific tasks

    path-help      Retrieve API help for paths

    plugin         Interact with Vault plugins and catalog

    policy         Interact with policies

    print          Prints runtime configurations

    secrets        Interact with secrets engines

    ssh            Initiate an SSH session

    token          Interact with tokens

				
			

Vous pouvez quitter la connexion en tapant exit.

Vous avez maintenant vérifié que votre droplet qui vient d'être déployée a été créée à partir de l'instantané que vous avez créé, et que Vault est correctement installé.

Conclusion

Vous disposez maintenant d'un système automatisé pour déployer Vault de Hashicorp sur les droplets the cloud provider en utilisant Terraform et Packer. Vous pouvez désormais déployer autant de serveurs Vault que nécessaire. Pour commencer à utiliser Vault, vous devez l'initialiser et le configurer davantage. Pour savoir comment procéder, consultez les documents officiels.

Pour accéder à d'autres tutoriels sur l'utilisation de Terraform, consultez notre page de contenus Terraform.