
Je voudrais parler du nouvel outil CLI que j'ai écrit pour résoudre un ancien problème.
Le problème
Terraform est depuis longtemps la référence dans la communauté Devops / Cloud / IT. La chose est très pratique et utile pour faire de l'infrastructure en tant que code. Il existe de nombreux charmes dans Terraform ainsi que de nombreuses fourchettes, couteaux tranchants et râteaux.
Avec Terraform, il est très pratique de faire de nouvelles choses, puis de les gérer, les modifier ou les supprimer. Et qu'en est-il de ceux qui ont une énorme infrastructure dans le cloud et qui ne sont pas créés via Terraform? Réécrire et recréer l'ensemble du cloud est en quelque sorte coûteux et dangereux.
J'ai rencontré un tel problème dans 2 œuvres, l'exemple le plus simple est lorsque vous voulez que tout soit sous forme de fichiers terraform, et que vous avez plus de 250 seaux et que vous en écrivez beaucoup pour terraform avec vos mains.
Il y a un
problème depuis 2014 dans terrafom qui a été fermé en 2016 avec l'espoir qu'il y aura importation.
En général, tout est comme sur l'image uniquement de droite à gauche
Avertissements: L'auteur ne vit pas en Russie pendant la moitié de sa vie et écrit peu en russe. Attention aux fautes d'orthographe.
Des solutions
1. Il existe des solutions clé en main et anciennes pour la
terraformation AWS. Quand j'ai essayé de faire passer mon seau 250+, j'ai réalisé que tout était mauvais là-bas. AWS a déjà lancé de nombreuses nouvelles options depuis longtemps et la terraformation ne les connaît pas et, en général, elle a un
modèle rubis
qui semble médiocre . Après 2 heures du soir, j'ai envoyé une
demande Pull pour y ajouter plus de fonctionnalités et j'ai réalisé qu'une telle solution ne convenait pas du tout.
Comment fonctionne la terraformation, elle prend les données du kit AWS SDK et génère tf et tfstate via le modèle.
Il y a 3 problèmes:
1. Il y aura toujours des retards dans les mises à jour
2. les fichiers tf sortent parfois cassés
3. tfstate est collecté séparément de tf et ne converge pas toujours
En général, il est difficile d'obtenir un résultat dans lequel le «plan terraform» dira qu'il n'y a pas de changement
2. `terraform import` - une commande intégrée dans terraform. Comment ça marche?
Vous écrivez un fichier TF vide avec le nom et le type de la ressource, puis exécutez `terraform import` et passez l'ID de la ressource. terraform appelle le fournisseur qui reçoit les données et crée un fichier tfstate.
Il y a 3 problèmes:
1. Nous obtenons uniquement le fichier tfstate et le tf vide doit être écrit ou converti avec tfstate
2. Capable de travailler avec une seule ressource à chaque fois et ne prend pas en charge toutes les ressources. Et que dois-je faire à nouveau avec plus de 250 seaux
3. Vous devez connaître l'ID de la ressource - c'est-à-dire que vous devez l'envelopper dans du code qui extrait une liste de ressources
En général, le résultat est partiel et n'évolue pas bien
Mes décisions
Prérequis:
1. Possibilité de créer des fichiers tf et tfstate par ressources. Par exemple, téléchargez tous les compartiments / groupe de sécurité / équilibreur de charge et que le `plan terraform` a renvoyé qu'il n'y a pas de changements
2. Il faut 2 nuages de GCP + AWS
3. Une solution globale facile à mettre à jour à chaque fois et qui ne perd pas de temps sur chaque ressource pendant 3 jours de travail
4. Faites de l'Open source - tout le monde a un tel problème
Go language - c'est pourquoi je l'adore, et il a une bibliothèque pour créer des fichiers HCL qui est utilisé dans terraform + beaucoup de code dans terraform qui peut être utile
Le chemin
Première tentative
Commencé une option simple. Accès au cloud via le SDK pour la ressource souhaitée et conversion en champs pour terraform. La tentative est morte tout de suite sur le groupe de sécurité parce que je n'ai pas aimé 1,5 jour pour convertir uniquement le groupe de sécurité (et il y a beaucoup de ressources). Les champs longs, puis peuvent être modifiés / ajoutés
Deuxième tentative
Basé sur l'idée décrite
ici . Prenez et convertissez simplement tfstate en tf. Toutes les données sont là et les champs sont les mêmes. Comment obtenir le tfstate complet pour de nombreuses ressources ?? Ensuite, la commande «terraform refresh» est venue à la rescousse. terraform prend toutes les ressources dans tfstate et extrait les données par ID et écrit tout dans tfstate. Autrement dit, créez un tfstate vide avec uniquement des noms et des ID, exécutez `terraform refresh`, nous obtenons le tfstate complet. Hourra!
Faisons maintenant la
pornographie récursive de l' écriture d'un convertisseur pour tfstate en tf. Pour ceux qui n'ont jamais lu tfstate, c'est JSON, mais spécial.
Voici ses attributs importants
"attributes": { "id": "default/backend-logging-load-deployment", "metadata.#": "1", "metadata.0.annotations.%": "0", "metadata.0.generate_name": "", "metadata.0.generation": "24", "metadata.0.labels.%": "1", "metadata.0.labels.app": "backend-logging", "metadata.0.name": "backend-logging-load-deployment", "metadata.0.namespace": "default", "metadata.0.resource_version": "109317427", "metadata.0.self_link": "/apis/apps/v1/namespaces/default/deployments/backend-logging-load-deployment", "metadata.0.uid": "300ecda1-4138-11e9-9d5d-42010a8400b5", "spec.#": "1", "spec.0.min_ready_seconds": "0", "spec.0.paused": "false", "spec.0.progress_deadline_seconds": "600", "spec.0.replicas": "1", "spec.0.revision_history_limit": "10", "spec.0.selector.#": "1",
Il y a:
1. id - chaîne
2. métadonnées - un tableau de taille 1 et en lui un objet avec des champs qui est décrit ci-dessous
3. spec - hachage de taille 1 et dans cette clé, valeur
Bref, un format ludique, tout peut être approfondi aussi à plusieurs niveaux
"spec.#": "1", "spec.0.min_ready_seconds": "0", "spec.0.paused": "false", "spec.0.progress_deadline_seconds": "600", "spec.0.replicas": "1", "spec.0.revision_history_limit": "10", "spec.0.selector.#": "1", "spec.0.selector.0.match_expressions.#": "0", "spec.0.selector.0.match_labels.%": "1", "spec.0.selector.0.match_labels.app": "backend-logging-load", "spec.0.strategy.#": "0", "spec.0.template.#": "1", "spec.0.template.0.metadata.#": "1", "spec.0.template.0.metadata.0.annotations.%": "0", "spec.0.template.0.metadata.0.generate_name": "", "spec.0.template.0.metadata.0.generation": "0", "spec.0.template.0.metadata.0.labels.%": "1", "spec.0.template.0.metadata.0.labels.app": "backend-logging-load", "spec.0.template.0.metadata.0.name": "", "spec.0.template.0.metadata.0.namespace": "", "spec.0.template.0.metadata.0.resource_version": "", "spec.0.template.0.metadata.0.self_link": "", "spec.0.template.0.metadata.0.uid": "", "spec.0.template.0.spec.#": "1", "spec.0.template.0.spec.0.active_deadline_seconds": "0", "spec.0.template.0.spec.0.container.#": "1", "spec.0.template.0.spec.0.container.0.args.#": "3",
En général, qui veut une tâche de programmation pour une interview, il suffit de demander à écrire un analyseur à ce sujet :)
Après de longues tentatives pour écrire un analyseur sans bogues, j'en ai trouvé une partie dans le code terraform, et la partie la plus importante. Et tout semblait bien fonctionner
Tentez trois
terraform provider est un binaire dans lequel il existe un code avec toutes les ressources et la logique pour travailler avec l'API cloud. Chaque cloud a son propre fournisseur et la terraformation ne les appelle que via son protocole RPC entre deux processus.
Maintenant, j'ai décidé d'accéder aux fournisseurs de terraform directement via les appels RPC. Cela s'est avéré magnifiquement et a permis de changer les fournisseurs de terraform pour les plus récents et d'obtenir de nouvelles opportunités sans changer le code. Il s'est avéré que tous les champs de tfstate ne devraient pas l'être en tf, mais comment savoir? Il suffit de demander au fournisseur à ce sujet. Puis une autre
pornographie récursive sur l'assemblage d'expressions régulières a commencé par la recherche avec la recherche de champs à l'intérieur de tfstate à tous les niveaux en profondeur.
En fin de compte, nous avons obtenu un outil CLI utile qui a une infrastructure commune pour tous les fournisseurs de terraform et vous pouvez facilement en ajouter un nouveau. L'ajout de ressources prend également peu de code. Plus toutes sortes de goodies comme la connexion entre les ressources. Bien sûr, il y avait de nombreux problèmes différents qui ne peuvent pas tous être décrits.
Il a appelé le petit animal Terrafomer.
Finale
En utilisant Terrafomer, nous avons généré 500 à 700 milliers de lignes de code tf + tfstate à partir de deux nuages. Ils pouvaient prendre des objets hérités et commencer à les toucher uniquement par le biais de la terraforme, comme dans les meilleures idées d'infrastructure sous forme de code. C'est juste magique quand vous prenez un énorme nuage et que vous le faites passer par la commande sous la forme de fichiers de travail terraform. Et puis grep / replace / git et ainsi de suite.
Il a ratissé et mis en ordre, a reçu la permission. Sorti sur github pour tous jeudi (05/02/19).
github.com/GoogleCloudPlatform/terraformerDéjà reçu 600 étoiles, 2 pull demandes ajoutant le support pour openstack et kubernetes. Bonnes critiques. En général, le projet est utile pour les personnes
Je conseille à tous ceux qui souhaitent commencer à travailler avec Terraform et de ne pas tout réécrire pour cela.
Je serais heureux de tirer des demandes, des problèmes, des étoiles.
Démo

Mises à jour: le support minimal d'Openstack vissé et le support de kubernetes est presque prêt, grâce aux personnes pour les relations publiques