Azure Native Qumulo Maintenant disponible dans l'UE, au Royaume-Uni et au Canada - En savoir plus

Ingénierie Qumulo : préparer notre logiciel pour la place de marché AWS

Rédigé par:

Se préparer à répertorier une version payante de notre Logiciel Qumulo File Fabric (QF2) sur AWS Marketplace signifie que notre équipe d'ingénierie cloud a dû résoudre des défis uniques.

Ce billet de blog est le premier d'une série où nous discutons de certains de ces défis et montrons comment nous les avons résolus au départ. Cela ne veut pas dire que c'est la solution finale ou même la meilleure solution, mais un moyen pour nous, ici à Qumulo, de partager ce que nous avons appris.

L'objet principal de l'obtention de votre produit dans AWS Marketplace est de permettre à vos clients d'acheter, de déployer et de gérer directement leur infrastructure. Pour les éditeurs de logiciels, c'est pratique car Amazon gère tous les aspects de la facturation et des licences.

AWS Marketplace: faciliter la tâche des clients, pratique pour les fournisseurs

Pour nous, le plus grand défi consiste à faciliter le déploiement du produit par les clients dans le processus le plus exempt de friction possible. Nous connaissons tous ces quelques premières secondes avec n'importe quel produit qui compte vraiment, de sorte que l'expérience de sortie de caisse est vraiment importante.

Pour distribuer des logiciels via Marketplace, AWS encourage les fournisseurs à utiliser CloudFormation, le mécanisme Infrastructure as Code d'Amazon, généralement livré dans un fichier au format JSON ou YAML.

Des constructions de langage simples sont manquantes dans CloudFormation, ce qui peut compliquer un peu les choses. Prenez une boucle, par exemple. Il n'est pas possible de créer facilement plusieurs bits identiques d'infrastructure sans recourir à AutoScaling, ce qui peut ne pas convenir à votre logiciel. Dans un langage comme Python, je définirais simplement ma limite supérieure et expulserais un tableau d'objets et passerais à autre chose. Avec CloudFormation, vous finissez par répéter le code pour créer une infrastructure.

Par exemple, chez Qumulo, nous prenons en charge les clusters de nœuds 4 et supérieurs. Aller avec le nombre le plus bas signifie que j'aurais quatre copies du code de création de l'instance EC2. Cela devient très lourd une fois que nous avons atteint le nombre de nœuds à deux chiffres.

"Resources": {
       "QF2Node1": {
           "Properties": {
               "ImageId": {
                   "Fn::FindInMap": [
                       "RegionMap",
                       {
                           "Ref": "AWS::Region"
                       },
                       "AMI"
                   ]
               },
               "InstanceType": {
                   "Ref": "InstanceType"
               },
               "KeyName": {
                   "Ref": "KeyName"
               },
               "NetworkInterfaces": [
                   {
                       "AssociatePublicIpAddress": "false",
                       "DeleteOnTermination": "true",
                       "DeviceIndex": 0,
                       "GroupSet": [
                           {
                               "Ref": "QumuloSecurityGroup"
                           }
                       ],
                       "SubnetId": {
                           "Ref": "SubnetId"
                       }
                   }
               ]
           },
           "Type": "AWS::EC2::Instance"
       },
       "QF2Node2": {
           "Properties": {
               "ImageId": {
                   "Fn::FindInMap": [
                       "RegionMap",
                       {
                           "Ref": "AWS::Region"
                       },
                       "AMI"
                   ]
               },
               "InstanceType": {
                   "Ref": "InstanceType"
               },
               "KeyName": {
                   "Ref": "KeyName"
               },
               "NetworkInterfaces": [
                   {
                       "AssociatePublicIpAddress": "false",
                       "DeleteOnTermination": "true",
                       "DeviceIndex": 0,
                       "GroupSet": [
                           {
                               "Ref": "QumuloSecurityGroup"
                           }
                       ],
                       "SubnetId": {
                           "Ref": "SubnetId"
                       }
                   }
               ]
           },
           "Type": "AWS::EC2::Instance"
       },
       "QF2Node3": {
           "Properties": {
               "ImageId": {
                   "Fn::FindInMap": [
                       "RegionMap",
                       {
                           "Ref": "AWS::Region"
                       },
                       "AMI"
                   ]
               },
               "InstanceType": {
                   "Ref": "InstanceType"
               },
               "KeyName": {
                   "Ref": "KeyName"
               },
               "NetworkInterfaces": [
                   {
                       "AssociatePublicIpAddress": "false",
                       "DeleteOnTermination": "true",
                       "DeviceIndex": 0,
                       "GroupSet": [
                           {
                               "Ref": "QumuloSecurityGroup"
                           }
                       ],
                       "SubnetId": {
                           "Ref": "SubnetId"
                       }
                   }
               ]
           },
           "Type": "AWS::EC2::Instance"
       },
       "QF2Node4": {
           "Properties": {
               "ImageId": {
                   "Fn::FindInMap": [
                       "RegionMap",
                       {
                           "Ref": "AWS::Region"
                       },
                       "AMI"
                   ]
               },
               "InstanceType": {
                   "Ref": "InstanceType"
               },
               "KeyName": {
                   "Ref": "KeyName"
               },
               "NetworkInterfaces": [
                   {
                       "AssociatePublicIpAddress": "false",
                       "DeleteOnTermination": "true",
                       "DeviceIndex": 0,
                       "GroupSet": [
                           {
                               "Ref": "QumuloSecurityGroup"
                           }
                       ],
                       "SubnetId": {
                           "Ref": "SubnetId"
                       }
                   }
               ]
           },
           "Type": "AWS::EC2::Instance"
       },

Obtenir une entrée utilisateur sur la taille du cluster

Un autre problème est que, sans saisie de la part de l'utilisateur, comment puis-je déterminer la taille que le client voudrait créer. Maintenant, CloudFormation peut prendre des entrées, mais l'utilisation de la logique conditionnelle limitée disponible dans le langage signifie que chaque permutation possible en entrée devrait être prise en compte dans le modèle CloudFormation. Idéalement, nous pourrions générer automatiquement un modèle CloudFormation par utilisateur, puis lancer l'utilisateur dans un cluster adapté à ses besoins.

Pour résoudre ce problème, nous avons commencé à créer un formulaire simple qu'un client pouvait utiliser pour saisir la taille du cluster qu'il souhaitait, recevoir des commentaires immédiats sur la capacité à laquelle il aurait accès, puis lancer directement sur CloudFormation. Dans le back-end, ce formulaire enverrait le nombre de nœuds, le type d'instance et la région AWS du cluster à un script principal. Ce script back-end est actuellement disponible sur notre page GitHub sous le dossier Cloud-Deployment-Samples. Il tire parti de Troposphere, qui vous permet de créer par programmation des modèles CloudFormation sur mesure. Par exemple, le même cluster 4-node montré précédemment peut être créé à l'aide de cette fonction:

# add_nodes () prend un objet Template donné, un nombre de nœuds à créer et # un nom pour préfixer toutes les instances EC2. Les instances EC2 seront créées avec la # structure de dénomination Prefix + Node + NodeNumber. def add_nodes (t, nodes, prefix): nodes_list = [] for x in range (0, nodes): node_name = prefix + "Node" + str ((x + 1)) t.add_resource (ec2.Instance (node_name, ImageId = FindInMap ("RegionMap", Ref ("AWS :: Region"), "AMI"), InstanceType = Ref ("InstanceType"), KeyName = Ref ("KeyName"), NetworkInterfaces = [ec2.NetworkInterfaceProperty (AssociatePublicIpAddress = False, GroupSet = [Ref ("QumuloSecurityGroup")], DeviceIndex = 0, DeleteOnTermination = True, SubnetId = Ref ("SubnetId"),)])) nodes_list.append (node_name) # Créer une liste contenant les adresses IP privées de tous nœuds. output_ips = [] for i in nodes_list: output_ips.append (GetAtt (i, "PrivateIp")) t.add_output (Output ("ClusterPrivateIPs", Description = "Copiez et collez cette liste dans l'écran de création de cluster QF2", Value = Join (",", output_ips),)) t.add_output (Output ("LinkToManagement", Description = "Cliquez pour lancer la console d'administration QF2", Value = Join ("", ["https: //", GetAtt ( nodes_list [0], "PrivateIp")]),)) t.add_output (Output ("InstanceId", Description = "Copiez et collez cet ID d'instance dans l'écran de création de cluster QF2.", Value = Ref (prefix + "Node1 "),))

À première vue, cela ne semble pas beaucoup plus court, mais décomposons ce qui se passe réellement ici. Cette fonction crée un nombre quelconque de nœuds en utilisant la configuration que le client sélectionne via d'autres parties du script. Tous les nœuds ont été créés dans les lignes de code 18 de la boucle for. Tout ce qui suit fournit en fait des subtilités d’expérience utilisateur.

# Créez une liste contenant les adresses IP privées de tous les nœuds. output_ips = [] pour i dans nodes_list: output_ips.append (GetAtt (i, "PrivateIp"))

Dans cette section, nous saisissons chaque adresse IP privée de l'instance EC2 et l'ajoutons à une liste pour plus tard. Les sections de sortie suivantes insèrent du texte et des liens dans l'onglet Sortie de CloudFormation pour que le client puisse terminer la configuration et accéder à son tout nouveau cluster. Actuellement, après la création d'un cluster, le client accède à la page de gestion de n'importe quel nœud, répond à une question de défi concernant son compte AWS (dans ce cas, nous demandons l'ID du nœud) et fournit une liste séparée par des virgules. de tous les noeuds IP privés. Les sorties placent ici un lien vers l'adresse IP de gestion du premier noeud, son ID d'instance et une liste séparée par des virgules de toutes les adresses IP privées. Tout ce dont vous avez besoin pour mettre la grappe en place, le tout au même endroit.

Articles Similaires

Remonter en haut