Présentation de Pulumi

Depuis l'arrivée d’outils comme Terraform ou AWS CloudFormation (pour ne citer que les plus connus) l’Infrastructure as Code (IaC) est une pratique devenue incontournable. En automatisant l'approvisionnement d’une infrastructure par le biais du code, il est possible de gérer facilement les versions de l’infrastructure et de supprimer les processus manuels.

L’Infrastructure as Code apporte plusieurs bénéfices. Elle permet de gérer le versionning de l’infrastructure à l’aide de logiciels comme Git. Le Shadow IT est réduit, c'est-à-dire l’ensemble des systèmes informatiques qui ne sont pas officiellement répertoriés. La mise en place de plusieurs environnements de déploiement est simplifiée. Les erreurs manuelles et les patchs mineurs réalisés à la volée sont éliminés. Enfin, elle accélère la mise en place de l’infrastructure ce qui entraîne la diminution des coûts d’exploitation d’une solution et l’augmentation de la satisfaction client.

Dans le paysage des langages d’IaC, Terraform est l’un des plus utilisés. Néanmoins, il est nécessaire d’apprendre l’Hashicorp Configuration Language (HCL), qui est le langage de configuration créé par Hashicorp pour utiliser Terraform.

Dans cet article, je vais présenter l'outil Pulumi, son fonctionnement et quelques exemples de code. C’est parti !

Pulumi ? Qu’est ce que c’est ?

Pulumi est un outil permettant de déployer une infrastructure à partir de code. Le projet est open source et développé en Go. Il est relativement jeune : la première version stable est sortie le 3 septembre 2019. Le projet possède une large communauté active et il évolue rapidement. Le projet en est à sa version 3.

Grâce à Pulumi, vous pouvez déployer une “EC2” sur AWS, un “Active Directory” sur Azure et même des containers Docker ! Pulumi prend en charge la plupart des provider connus : AWS, Azure, Google Cloud, Alibaba Cloud…  Les possibilités sont multiples.

Contrairement à Terraform, Pulumi permet d’utiliser des langages de programmation standards comme Python, Javascript, TypeScript ou Go. Cela permet de réduire le temps d'accommodation d’un développeur en supprimant l’étape d’apprentissage d’un nouveau langage. De plus, vous avez la possibilité de réutiliser votre environnement de développement adapté à votre langage préféré pour développer du code et les librairies de tests seront aussi les mêmes !

La force de Pulumi réside dans la possibilité d’ajouter plus de logique dans votre code d’infrastructure. Contrairement à Terraform qui se veut être un langage déclaratif, Pulumi est procédural. Vous pouvez profiter de la puissance d’un langage de programmation comme Python pour ajouter des boucles, des conditions et des fonctions. C’est ici que réside la valeur ajoutée de Pulumi : toute la puissance des langages de programmation classique se met à disposition de l’IaC. Pulumi supporte les Runtime de langage suivants : Python, NodeJs, Go et .NET Core.

Fonctionnement interne

À l’instar de Terraform, Pulumi utilise un “State” stocké dans un fichier local ou sur le cloud pour gérer l’infrastructure (vous pouvez le mettre où vous le souhaitez). Ce “State” décrit l’état de vos services déployés lors de la dernière exécution de votre script. Cela permet de calculer les ressources qui doivent être créées, supprimées ou mises à jour.
Pulumi utilise les APIs des clouds providers pour déployer et maintenir votre infrastructure.

Regardons comment fonctionne Pulumi grâce à ce schéma :

Language host

C’est la partie qui va configurer et lire votre code. Lorsque vous instanciez un nouvel objet, le “Language Host” va transmettre l’information au moteur de déploiement (la partie “Engine”).

CLI and Engine

La logique de déploiement est gérée grâce à cette partie. Ce moteur va prendre en compte l’état actuel de votre architecture pour effectuer les actions qui permettront de faire correspondre l’architecture souhaitée définie dans votre code et l’architecture actuellement présente dans votre Cloud. L’état de votre application est sauvegardé et stocké à chaque lancement de votre script dans votre state.

À chaque instanciation d’un composant dans votre code, le moteur va vérifier si la ressource existe, si elle a besoin d’être mise à jour ou bien supprimée. Selon la propriété mise à jour pour une ressource existante, celle-ci sera modifiée à la volée ou simplement supprimée puis recréée.

Providers

Les “Resource Provider” permettent au moteur de Pulumi de faire des actions sur les ressources dans le cloud. Chaque SDK correspond à un provider différent et ils sont tous disponibles dans les langages supportés actuellement par Pulumi.

Exemples de code

Rien de mieux que la pratique pour vous montrer la force de Pulumi. Dans cette partie, je vous présente un code qui déploie une EC2 chez AWS en Terraform et en Pulumi.

Commençons par Terraform, voici le code HCL :

terraform {
    required_providers {
      aws = {
        source  = "hashicorp/aws"
        version = "~> 3.27"
      }
	}
	required_version = ">= 0.14.9"
}

provider "aws" {
    profile = "default"
    region  = "eu-west-3"
}

resource "aws_instance" "ubuntu_terraform" {
    ami           = "ami-079a31cd1838f6b60"
    instance_type = "t2.micro"
    tags = {
    	deployed_by = "terraform"
	}
}
output "ubuntu_terraform_public_ip" {
	value = aws_instance.ubuntu_terraform.public_ip
}

La première partie définit le provider Terraform à utiliser, ici AWS car nous souhaitons déployer une EC2.
La partie Provider permet de configurer la région et le compte AWS à utiliser.
La partie Resource contient la configuration minimale pour une EC2.Et nous souhaitons afficher l’adresse IP public de l’EC2.
Voici maintenant le même code en Pulumi. J’ai décidé d’utiliser Python pour cet exemple.
La configuration se fait dans des fichiers différents.

Pulumi.yaml : (Métadata de votre projet)

name: testpulumi
runtime:
	name: python
	options:
		virtualenv: venv
		description: A minimal AWS Python Pulumi program


Pulumi.dev.yaml : (Configuration de votre stack, ici c’est la stack “dev”)

config:
	aws:
    	region: eu-west-1


__main__.py : (Code de l’infrastructure)

import pulumi
import pulumi_aws as aws
ubuntu_pulumi = aws.ec2.Instance("ubuntu_pulumi",
	ami="ami-079a31cd1838f6b60",
	instance_type="t2.micro",
	tags={
		"deployed_by": "pulumi",
	})
pulumi.export('ubuntu_pulumi_public_ip',  ubuntu_pulumi.public_ip)

Comme vous pouvez le constater, le code est très simple. Après avoir importé le SDK, on instancie une EC2 et on affiche son adresse IP publique dans la console lorsqu’elle sera déployée. Vous pouvez consulter toutes les informations relatives à une Stack après son déploiement grâce à la commande 'pulumi stack’.

Nous pouvons bénéficier de la puissance des boucles en python pour instancier plusieurs machines. Voici un deuxième exemple :

__main__.py :

import pulumi
import pulumi_aws as aws
nbEC2Instances = 5
for i in range(0, nbEC2Instances):
	instanceName = "ubuntu_pulumi_" + str(i)
	ubuntu_pulumi = aws.ec2.Instance( instanceName,
	ami="ami-079a31cd1838f6b60",
	instance_type="t2.micro",
	tags={
		"deployed_by": "pulumi",
	})
pulumi.export(instanceName + "_public_ip",  ubuntu_pulumi.public_ip)

Ce code permet d'instancier cinq EC2 et montrer leur adresse public dans votre VPC par défaut de la région configurée pour votre stack.

Le CLI : Les commandes de base pour déployer

Pour exécuter votre code et voir apparaître votre architecture dans l’UI de votre Provider Cloud préféré, voici les commandes à lancer dans votre shell bash.

$ pulumi up
Please choose a stack, or create a new one: dev
Previewing update (dev)

View Live: https://app.pulumi.com/TheoPth1/testpulumi/dev/previews/d20af2e1-6f03-4b8e-9884-9867757e391f

     Type                 Name            Plan     
     pulumi:pulumi:Stack  testpulumi-dev           
 
Resources:
    3 unchanged

Do you want to perform this update?  [Use arrows to move, enter to select, type to filter]
> yes
  no
  details

pulumi up : Crée ou met à jour les ressources d’une “Stack”. Les changements à appliquer s’afficheront. Vous pouvez ensuite choisir si vous souhaitez exécuter ces modifications.

pulumi refresh : Permet de vérifier l’état actuel de votre “Stack” et y appliquer des modifications si nécessaire.

pulumi destroy : Supprimer toutes les ressources de votre “Stack” .

Pour clore cette démonstration, je vous propose le test d’une fonctionnalité.

Import d’une ressource dans une Stack existante :
Nous allons importer un Bucket S3 existant dans la Stack déployée précédemment.

Notre Stack “Dev” est composée d’une Ec2. Commençons par importer la ressource à l’aide de la commande suivante :

pulumi import aws:s3/bucket:Bucket import-in-stack import-in-stack

Le bucket import-in-stack est importé avec le même nom. Une fois exécuté, la commande nous donne le code à ajouter dans notre script. Il suffit de la copier / coller.

Please copy the following code into [ … ] take effect.

import pulumi
import pulumi_aws as aws

import_in_stack = aws.s3.Bucket("import-in-stack",
    acl="private",
    bucket="import-in-stack",
    force_destroy=False,
    opts=pulumi.ResourceOptions(protect=True))

Voilà ! Votre ressource est importée, vous pouvez la mettre à jour ou la supprimer en modifiant le code ci-dessus.Maintenant, c’est à vous. Pour commencer correctement : https://www.pulumi.com/docs/get-started/aws/.

Ouverture

Pulumi est une jeune technologie pleine de promesses et déjà un concurrent sérieux dans le domaine de l’IaC. Avec un langage de programmation tel que Python ou JavaScript, il est plus facile de retrouver ses marques. La mise en place des tests, la réutilisation de morceaux de code ou encore la mise en place de modules haut niveau sont plus rapides à mettre en place. La flexibilité qu’offre Pulumi est très intéressante dans les projets aux besoins spécifiques qui ont besoin de beaucoup de logique dans la construction de l’architecture.

Terraform proposera bientôt la possibilité de provisionner une infrastructure à l’aide de Python ou TypeScript. Cette fonctionnalité est encore en version Bêta. Cela montre l'intérêt que portent les développeurs au déploiement d’architecture à l’aide langage de programmation classique.

Comme nous avons pu le voir dans l’exemple ci-dessus, il n’existe pas  réellement de différences notables pour les projets de taille réduite. Les concurrents de Pulumi proposent des fonctionnalités similaires pour les tâches basiques.

Il existe également Pulumi Crosswalk qui propose des modules pour la création d’une architecture complète selon les meilleures pratiques. Vous pouvez ainsi utiliser ces modules haut niveau pour mettre en place des VPC pour isoler vos réseaux, monter un cluster EKS ou ajouter de la sécurité à votre architecture facilement.

Vous pouvez facilement migrer de Terraform à Pulumi. Vous trouverez sur leur site officiel les instructions et les commandes pour migrer votre infrastructure un langage supporté.
Pulumi est opensource et gratuit. Essayez-le !