Recherche de site Web

Utilisez votre langage de programmation préféré pour provisionner l'Infrastructure as Code


Provisionnez tout ce dont vous avez besoin pour faire décoller votre infrastructure avec Node.js ou un autre langage de programmation.

Lorsque vous naviguez dans le monde de l’informatique et de la technologie, certains termes vous reviennent fréquemment. Certains d’entre eux sont difficiles à quantifier et peuvent prendre des significations différentes au fil du temps. "DevOps" est un exemple de mot qui semble (me) changer en fonction de la personne qui l'utilise ; les premiers pionniers du DevOps ne reconnaissent peut-être même pas ce que nous appelons aujourd'hui DevOps.

Si vous êtes un développeur de logiciels, « Infrastructure as Code » (IaC) peut être l'un de ces termes. IaC utilise les mêmes pratiques de développement logiciel que vous utiliseriez pour écrire des fonctionnalités destinées aux utilisateurs afin de déclarer l'infrastructure sur laquelle les applications s'exécutent. Cela signifie souvent utiliser des outils comme Git ou Mercurial pour le contrôle de version et Puppet, Chef ou Ansible pour la gestion de la configuration. Au niveau de la couche de provisionnement de l'infrastructure, la technologie la plus courante est CloudFormation (pour AWS en particulier) ou Terraform comme alternative open source pour créer des ressources de cloud hybride sur lesquelles vos applications peuvent s'exécuter.

Il existe d'excellentes options dans l'espace de gestion de configuration pour écrire IaC sous forme de fichiers de configuration ou de langages de programmation préférés, mais ce choix n'est pas bien connu dans l'espace de provisionnement d'infrastructure.

Pulumi offre la possibilité d'utiliser des langages de programmation standard pour définir l'infrastructure. Il prend en charge un large éventail de langages, notamment JavaScript, TypeScript, Go, Python et C#. Tout comme Terraform, Pulumi bénéficie d'un support de premier ordre pour de nombreux fournisseurs de cloud familiers, tels qu'AWS, Azure, Google Cloud et d'autres fournisseurs.

Dans cet article, je vais vous montrer comment utiliser Pulumi pour écrire une infrastructure dans Node.js.

Conditions préalables

Tout d’abord, assurez-vous que vous êtes prêt à utiliser Pulumi. Pulumi prend en charge tous les principaux systèmes d'exploitation. Les méthodes que vous utilisez pour installer ses prérequis dépendent donc du système d'exploitation que vous utilisez.

Tout d’abord, installez l’interpréteur pour votre langage de programmation préféré. J'utiliserai TypeScript, je dois donc installer le binaire node. Consultez les instructions d'installation de Node pour obtenir des informations sur votre système d'exploitation. Vous pouvez utiliser Homebrew sur Mac ou Linux pour installer :

brew install node

Sous Linux, vous pouvez alternativement utiliser votre gestionnaire de paquets habituel, tel que apt ou dnf :

$ sudo dnf install nodejs

Dans les deux cas, le résultat devrait être que le binaire node est disponible dans votre ` PATH. Pour confirmer qu'il est accessible, exécutez :

node --version

Ensuite, installez l'interface de ligne de commande Pulumi (CLI). Vous pouvez trouver des instructions d'installation spécifiques au système d'exploitation dans la documentation de Pulumi. Avec brew sur Mac ou Linux :

brew install pulumi

Alternativement, vous pouvez utiliser le script d'installation. Téléchargez-le d'abord et examinez-le, puis exécutez-le :

$ curl -fsSL --output pulumi_installer.sh \
https://get.pulumi.com/ 
$ more  pulumi_installer.sh 
$ sh ./pulumi_installer.sh

Encore une fois, le résultat souhaité est d'avoir le binaire pulumi disponible dans votre chemin. Vérifiez la version pour vous assurer que vous êtes prêt à continuer :

pulumi version
v2.5.0

Configurer Pulumi

Avant de commencer à provisionner une infrastructure, donnez à Pulumi un endroit où stocker son état.

Pulumi stocke son état dans un backend. Le backend par défaut est le logiciel en tant que service de Pulumi (qui propose un forfait gratuit pour les utilisateurs individuels), mais pour cet exemple, utilisez le backend de fichiers alternatif. Le backend de fichiers créera un fichier sur votre système de fichiers local pour stocker l'état avec :

pulumi login --local

Si vous envisagez de partager ce projet avec quelqu'un d'autre, le backend de fichiers n'est peut-être pas un bon point de départ. Pulumi peut également stocker son état dans un magasin d'objets cloud comme AWS S3. Pour l'utiliser, créez un bucket S3 et connectez-vous :

pulumi login --cloud-url s3://my-pulumi-state-bucket

Maintenant que vous êtes connecté à un backend d'état, vous pouvez créer un projet et une pile !

Avant de commencer à créer un projet Pulumi, découvrez la terminologie Pulumi suivante, que vous verrez dans ce didacticiel.

Projet

Un projet est un répertoire qui contient un fichier Pulumi.yaml. Ce fichier contient des métadonnées que Pulumi a besoin de connaître pour faire son travail. Des exemples de champs que vous trouverez dans un fichier Pulumi.yaml sont :

  • Le moteur d'exécution (par exemple, Python, Node, Go, .Net)
  • Une description du projet (par exemple, « mon premier projet Pulumi »)
  • Un nom pour le projet

Un projet est un concept vaguement défini qui peut répondre à vos besoins. Généralement, un projet contient un ensemble de ressources, qui sont des éléments que vous souhaitez provisionner et contrôler. Vous pouvez choisir d'avoir de petits projets Pulumi avec très peu de ressources ou de grands projets contenant toutes les ressources dont vous avez besoin. Au fur et à mesure que vous vous familiariserez avec Pulumi, la manière dont vous souhaitez présenter vos projets deviendra plus évidente.

Empiler

Une stack Pulumi vous permet de différencier vos projets Pulumi en fonction de valeurs configurables. Une utilisation courante consiste à déployer un projet dans différents environnements tels que le développement ou la production ou dans différentes régions comme l'Europe, le Moyen-Orient, l'Afrique et les États-Unis.

Au début, vous n'aurez probablement pas besoin d'une configuration de pile complexe. Cette procédure pas à pas utilise donc le nom de pile par défaut, dev.

Utiliser TypeScript pour IaC

Vous pouvez démarrer un projet Pulumi à l'aide de la commande pratique pulumi new. La commande new contient toute une série d'indicateurs et d'options qui devraient vous aider à démarrer avec Pulumi, alors allez-y et créez votre premier projet :

$ pulumi new typescript
This command will walk you through creating a new Pulumi project.

Enter a value or leave blank to accept the (default), and press <ENTER>.
Press ^C at any time to quit.

project name: (pulumi) my-first-project
project description: (A minimal TypeScript Pulumi program) My very first Pulumi program
Created project 'my-first-project'

Please enter your desired stack name.
To create a stack in an organization, use the format <org-name>/<stack-name> (e.g. `acmecorp/dev`).
stack name: (dev) dev
Created stack 'dev'

Installing dependencies...


> node scripts/postinstall

added 82 packages from 126 contributors and audited 82 packages in 2.84s

13 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

Finished installing dependencies

Your new project is ready to go! ✨

To perform an initial deployment, run 'pulumi up'

Il s'est passé beaucoup de choses ici, alors je vais les décomposer :

La première partie identifie un modèle pour votre projet Pulumi. J'ai choisi l'option générique typescript, mais de nombreuses options sont disponibles.

Cette commande new a récupéré le modèle de votre référentiel de modèles et a copié ce fichier localement, y compris les dépendances d'exécution (dans ce cas, package.json).

La commande new s'est occupée d'installer ces dépendances en exécutant npm install dans ce répertoire. Ensuite, npm install a téléchargé et installé tout ce dont vous avez besoin pour exécuter votre programme Pulumi, ce qui, dans ce cas, est très simple : le package @pulumi/pulumi NPM.

Vous êtes prêt à créer votre toute première ressource !

Créez votre première ressource cloud

Une ressource est un élément géré par le cycle de vie de votre logiciel de provisionnement d'infrastructure. Les ressources sont généralement un objet de fournisseur de cloud, comme un compartiment S3. Les fournisseurs Pulumi gèrent les ressources Pulumi et les fournisseurs sont spécifiques au fournisseur de cloud qu'ils gèrent. Pulumi propose environ 40 fournisseurs que vous pouvez utiliser, mais pour votre première ressource, utilisez l'un des plus simples : le fournisseur aléatoire.

Le fournisseur aléatoire fait ce que son nom l'indique : il crée de manière idempotente une ressource aléatoire (qui pourrait être une chaîne, par exemple) et la stocke dans l'état Pulumi.

Ajoutez ceci comme dépendance à votre projet Pulumi en utilisant npm :

npm install @pulumi/random

Le gestionnaire de packages npm télécharge et installe le package du fournisseur aléatoire et l'installe pour vous. Vous êtes maintenant prêt à écrire votre programme Pulumi.

Lorsque vous avez généré votre projet plus tôt, le processus d'amorçage de Pulumi a créé un fichier TypeScript index.ts. Ouvrez-le dans votre environnement de développement intégré (IDE) préféré et ajoutez votre première ressource :

import * as pulumi from "@pulumi/pulumi";
import * as random from "@pulumi/random";

const password = new random.RandomString(`password`, {
    length: 10
})

Si vous êtes familier avec TypeScript ou JavaScript, cela vous semblera très familier car il est écrit dans un langage de programmation que vous connaissez. Cela s'applique également si vous utilisez l'une des autres langues prises en charge par Pulumi. Voici la même ressource aléatoire d'avant, mais cette fois en Python :

import pulumi_random as random

password = random.RandomString("password", length=10)

Les projets Pulumi ne prennent actuellement en charge qu'une seule langue, mais chaque projet peut faire référence à d'autres projets écrits dans d'autres langues, une astuce utile pour les membres de l'équipe polyglotte.

Vous avez écrit votre première ressource Pulumi. Vous devez maintenant le déployer.

Quittez votre éditeur et revenez à la ligne de commande. Depuis le répertoire de votre projet, lancez pulumi up et regardez la magie opérer :

pulumi up 

Previewing update (dev):
     Type                          Name                  Plan
 +   pulumi:pulumi:Stack           my-first-project-dev  create
 +   └─ random:index:RandomString  password              create

Resources:
    + 2 to create

Do you want to perform this update? yes
Updating (dev):
     Type                          Name                  Status
 +   pulumi:pulumi:Stack           my-first-project-dev  created
 +   └─ random:index:RandomString  password              created

Resources:
    + 2 created

Duration: 2s

Permalink: file:///Users/lbriggs/.pulumi/stacks/dev.json

Excellent, vous avez votre première ressource Pulumi ! Même si vous appréciez peut-être ce sentiment d'accomplissement, malheureusement, cette ressource aléatoire n'est pas très utile : c'est juste une chaîne aléatoire, et vous ne pouvez même pas voir de quoi il s'agit. Répondez d'abord à cette partie : modifiez votre programme précédent et ajoutez export à la constante que vous avez créée :

import * as pulumi from "@pulumi/pulumi";
import * as random from "@pulumi/random";

export const password = new random.RandomString(`password`, {
    length: 10
})

Réexécutez pulumi up et regardez le résultat :

pulumi up
Previewing update (dev):
     Type                 Name                  Plan
     pulumi:pulumi:Stack  my-first-project-dev

Outputs:
  + password: {
      + id             : "&+r?{}J$J7"
      + keepers        : output<string>
      + length         : 10
      + lower          : true
      + minLower       : 0
      + minNumeric     : 0
      + minSpecial     : 0
      + minUpper       : 0
      + number         : true
      + overrideSpecial: output<string>
      + result         : "&+r?{}J$J7"
      + special        : true
      + upper          : true
      + urn            : "urn:pulumi:dev::my-first-project::random:index/randomString:RandomString::password"
    }

Resources:
    2 unchanged

Do you want to perform this update? yes
Updating (dev):
     Type                 Name                  Status
     pulumi:pulumi:Stack  my-first-project-dev

Outputs:
  + password: {
      + id        : "&+r?{}J$J7"
      + length    : 10
      + lower     : true
      + minLower  : 0
      + minNumeric: 0
      + minSpecial: 0
      + minUpper  : 0
      + number    : true
      + result    : "&+r?{}J$J7"
      + special   : true
      + upper     : true
      + urn       : "urn:pulumi:dev::my-first-project::random:index/randomString:RandomString::password"
    }

Resources:
    2 unchanged

Duration: 1s
Permalink: file:///Users/lbriggs/.pulumi/stacks/dev.json

Vous pouvez maintenant voir une chaîne générée aléatoirement sous la section result des Sorties. La ressource que vous avez créée possède un certain nombre de propriétés que vous pouvez voir maintenant.

C'est bien beau, mais si vous voulez profiter d'IaC, vous devrez provisionner autre chose qu'une chaîne aléatoire. Essaie!

Déployer un conteneur

Jusqu'à présent, vous avez démarré votre expérience Pulumi en installant des dépendances et en enregistrant une simple ressource aléatoire. Déployez maintenant une infrastructure réelle, mais sur votre machine locale.

Tout d'abord, ajoutez le fournisseur @pulumi/docker à votre pile. Utilisez le gestionnaire de packages de votre choix pour l'ajouter au projet :

npm install @pulumi/docker

Vous avez retiré le package du fournisseur Pulumi Docker de npm, ce qui signifie que vous pouvez désormais créer des images Docker dans votre projet.

Si Docker n’est pas installé sur votre ordinateur, c’est le moment idéal pour l’obtenir. Les instructions dépendront de votre système d'exploitation, alors jetez un œil à la page d'installation de Docker pour plus d'informations.

Ouvrez à nouveau votre IDE préféré et exécutez un conteneur Docker. Modifiez votre fichier index.ts précédent pour qu'il ressemble à ceci :

import * as pulumi from "@pulumi/pulumi";
import * as random from "@pulumi/random";
import * as docker from "@pulumi/docker";

const password = new random.RandomString(`password`, {
    length: 10
})

const container = new docker.Container(`my-password`, {
    image: 'hashicorp/http-echo',
    command: [ pulumi.interpolate`-text=Your super secret password is: ${password.result}` ],
    ports: [{
        internal: 5678,
        external: 5678,
    }]
})

export const id = container.id

Cela crée un conteneur qui crée un serveur Web. La sortie du serveur Web est votre chaîne générée aléatoirement, dans ce cas, un mot de passe. Exécutez ceci et voyez ce qui se passe :

pulumi up

Previewing update (dev):
     Type                       Name                  Plan
     pulumi:pulumi:Stack        my-first-project-dev
 +   └─ docker:index:Container  my-password           create

Outputs:
  + id      : output<string>
  ~ password: {
        id        : "&+r?{}J$J7"
        length    : 10
        lower     : true
        minLower  : 0
        minNumeric: 0
        minSpecial: 0
        minUpper  : 0
        number    : true
        result    : "&+r?{}J$J7"
        special   : true
        upper     : true
        urn       : "urn:pulumi:dev::my-first-project::random:index/randomString:RandomString::password"
    }

Resources:
    + 1 to create
    2 unchanged

Do you want to perform this update? yes
Updating (dev):
     Type                       Name                  Status
     pulumi:pulumi:Stack        my-first-project-dev
 +   └─ docker:index:Container  my-password           created

Outputs:
  + id      : "e73b34aeca34a64b72b61b0b9b8438637ce28853937bc359a1528ca99f49ddda"
    password: {
        id        : "&+r?{}J$J7"
        length    : 10
        lower     : true
        minLower  : 0
        minNumeric: 0
        minSpecial: 0
        minUpper  : 0
        number    : true
        result    : "&+r?{}J$J7"
        special   : true
        upper     : true
        urn       : "urn:pulumi:dev::my-first-project::random:index/randomString:RandomString::password"
    }

Resources:
    + 1 created
    2 unchanged

Duration: 2s
Permalink: file:///Users/lbriggs/.pulumi/stacks/dev.json

Vous remarquerez dans la section Sorties que les valeurs que vous produisez ont changé ; c'est juste un ID de conteneur Docker. Vérifiez si votre générateur de mot de passe très simple fonctionne :

curl http://localhost:5678
Your super secret password is: &+r?{}J$J7

Cela fait! Vous venez de provisionner votre premier élément d'infrastructure avec TypeScript !

Une note rapide sur les sorties Pulumi

Vous remarquerez dans le code qui crée le conteneur Docker qu'il utilise un appel spécial pulumi.interpolate. Si vous êtes familier avec TypeScript, vous pourriez être curieux de savoir pourquoi cela est nécessaire (car c'est spécifique à Pulumi). Il y a une raison intéressante.

Lorsque Pulumi crée une ressource, il y a des valeurs que Pulumi ne connaît pas jusqu'à l'exécution du programme. Dans Pulumi, celles-ci sont appelées Sorties. Ces Sorties peuvent être vues dans le code ci-dessus ; par exemple, dans votre première ressource aléatoire, vous avez utilisé le mot-clé export pour afficher les propriétés de la ressource aléatoire, et vous avez également exporté l'ID du conteneur que vous avez créé.

Parce que Pulumi ne connaît pas la valeur de ces Sorties avant le moment de l'exécution, il a besoin d'aides spéciales pour les utiliser lors de la manipulation des chaînes. Si vous souhaitez en savoir plus sur ce modèle de programmation spécial, regardez cette courte vidéo.

Emballer

L'IaC a évolué de nombreuses manières à mesure que la complexité est apparue dans les infrastructures de cloud hybride. Dans le domaine de l'approvisionnement d'infrastructure, Pulumi est un excellent choix pour utiliser votre langage de programmation préféré pour provisionner tout ce dont vous avez besoin pour faire décoller votre infrastructure, puis vous pouvez ajouter votre outil de gestion de configuration préféré pour passer aux étapes suivantes.

Articles connexes: