Marionnette + Hiera. Pressez le maximum


Dans cet article, je voudrais parler de la façon dont nous utilisons Puppet et Hiera pour configurer les serveurs de fer et virtuels. Fondamentalement, il s'agira de l'architecture et de la hiérarchie que nous avons inventées, ce qui facilite et systématise la configuration des serveurs.


J'ai été invité à écrire cet article par le fait que sur Internet, je n'ai pas trouvé de bons exemples vraiment efficaces de la façon dont vous pouvez travailler avec hiera et à quoi il sert. Fondamentalement, ce sont des tutoriels avec des exemples pour entrer dans le sujet. Mais la véritable application pratique de hiera n'y est pas écrite. Je n'ai peut-être pas bien regardé, mais voici un exemple réel qui vous aidera probablement à mettre tous les points sur i, comme je l'ai fait une fois.


Pour qui cet article serait utile


Si:


  • Vous savez ce que sont Puppet et Hiera, mais vous ne les utilisez pas vraiment ensemble, car on ne sait pas comment le faire et pourquoi
  • Vous avez beaucoup d'équipes dans votre entreprise et vous devez en quelque sorte différencier la configuration du serveur au niveau des commandes
  • Vous utilisez un pappet et les fichiers de noeud que vous avez développés à des tailles incroyables
  • Aimez-vous lire la configuration du serveur au format divine yaml :)
  • Vous êtes essentiellement intéressé par le sujet de la gestion de la configuration et de l'administration système.

Cet article est fait pour vous.


Avant de commencer


Je vous préviens tout de suite, l'article s'est avéré long, mais, je l'espère, utile. De plus, il est entendu que vous avez déjà connecté hiera à marionnette, et vous êtes au moins en quelque sorte familier avec la marionnette. Si hiera n'est pas connecté, ce n'est pas difficile à faire.



Entrer les données


  • Nous avons environ 30 équipes de développement chez SEMrush, chacune ayant ses propres serveurs
  • Chaque équipe travaille avec son propre ensemble de technologies (PL, SGBD, etc.)
  • Les équipes peuvent et doivent (idéalement) utiliser une configuration commune pour des projets spécifiques (réutilisation du code)
  • Les équipes gèrent elles-mêmes le déploiement des applications sur leurs serveurs (cela ne se fait pas via le pappet)

Un peu d'histoire


Initialement, nous avions tout dans le pappet de la version 3, puis nous avons décidé d'implémenter le 4e pappet, et tous les nouveaux serveurs ont commencé à y être placés, et les anciens ont été lentement portés sur le 4e.


Dans le troisième pappet, nous utilisions le système classique de fichiers et modules de nœuds. Les modules ont été créés dans un groupe spécial de projets dans Gitlab, ils ont été clonés sur un serveur pappet (en utilisant r10k ), puis les agents pappet sont venus à l'assistant et ont reçu un répertoire pour l'appliquer au serveur.


Ensuite, ils ont commencé à essayer de ne pas le faire et à ne pas utiliser les modules locaux, mais à mettre des liens vers les modules nécessaires et leurs référentiels dans le Puppetfile. Pourquoi? Parce que ces modules sont constamment pris en charge et améliorés (enfin, idéalement) par la communauté et les développeurs, et nos modules locaux ne le sont pas. Plus tard, ils ont introduit hiera et y sont complètement passés, et les fichiers de nœuds (tels que nœuds.pp) sont tombés dans l'oubli.


Dans le quatrième pappet, nous avons essayé d'abandonner complètement les modules locaux et d'utiliser uniquement des modules distants. Malheureusement, une réservation doit être insérée à nouveau ici, car cela «n'a pas fonctionné complètement», parfois vous devez encore incliner et terminer quelque chose vous-même. Bien sûr, il n'y a que des fichiers hiera et aucun nœud.


Lorsque vous avez 30 équipes avec un zoo technologique, le problème de la conservation de cette ménagerie avec> 1000 serveurs devient particulièrement aigu. De plus, je dirai comment hiera nous aide dans ce domaine.


Hiérarchie


Hiera (en fait, d'où il tire son nom) établit une hiérarchie. Chez nous, ça ressemble à ça:


--- :hierarchy: - "nodes/%{::fqdn}" - "teams/%{::team}_team/nodes/%{::fqdn}" - "teams/%{::team}_team/projects/%{::project}/tiers/%{::tier}" - "teams/%{::team}_team/projects/%{::project}/%{::role}" - "teams/%{::team}_team/projects/%{::project}" - "teams/%{::team}_team/roles/%{::role}" - "teams/%{::team}_team/%{::team}" - "projects/%{::project}/tiers/%{::tier}/%{::role}" - "projects/%{::project}/tiers/%{::tier}" - "projects/%{::project}/%{::role}" - "projects/%{::project}" - "tiers/%{::tier}" - "virtual/%{::virtual}" - "os/%{::operatingsystem}/%{::operatingsystemmajrelease}" - "os/%{::operatingsystem}" - users - common 

Voyons d'abord les variables obscures (faits).


Chaque serveur dans SEMrush devrait idéalement avoir 4 faits spéciaux exposés décrivant son affiliation:


  • fait d' team - à quelle équipe appartient-il
  • project - à quel projet se rapporte-t-il
  • role fait - quel rôle ce projet a-t-il
  • fait de tier - quel type de mise en scène a-t-il (prod, test, dev)

Comment ça marche? L'agent Pappet vient au maître Pappet et, sur la base de ces faits, recherche des fichiers pour lui-même, en parcourant les dossiers conformément à notre hiérarchie. Pas besoin d'indiquer que les fichiers de configuration appartiennent aux serveurs. Au lieu de cela, les serveurs eux-mêmes savent quels fichiers leur appartiennent, ne regardant que leur chemin et leurs faits.


Lors de la configuration du serveur, les administrateurs contactent les développeurs et spécifient ces paramètres (souvent, au contraire, des personnes bien informées contactent les administrateurs eux-mêmes) afin de construire une hiérarchie dans hiera à l'avenir, sur la base de laquelle décrire ensuite la configuration du serveur. Un tel système permet de réutiliser le code et d'être plus flexible en termes de configuration du serveur.


Par exemple, nous avons un projet spécial . Dans ce projet, il peut y avoir un serveur frontal avec nginx, un serveur principal avec python, un cluster db avec mysql, un serveur redis pour la mise en cache. Tous ces serveurs doivent être placés dans un projet appelé spécial , puis attribuer des rôles aux serveurs.


Dans le fichier projet, nous décrivons les paramètres communs à l'ensemble du projet. La première chose qui me vient à l'esprit est la création sur tous les serveurs de l'utilisateur pour le déploiement avec la délivrance des droits nécessaires à lui et le déploiement de ses clés ssh.


Dans le rôle de chaque serveur, le service est généralement décrit et personnalisé - pour ce à quoi ce serveur est destiné (nginx, python, mysql, etc.). Dans ce cas, nous aurons certainement besoin si nous devons également déployer une copie de l'environnement de production sur la plate-forme de développement, mais changez-y quelque chose (mots de passe, par exemple). Dans ce cas, le serveur de développement et le serveur de production ne différeront que par le fait que le niveau est défini sur la «position» souhaitée (prod ou dev). Et puis un peu de magie et d'Hiera fera l'affaire.


Si nous devons déployer deux serveurs identiques dans le même rôle, mais que quelque chose en eux devrait différer, par exemple, certaines lignes de la configuration, alors une autre partie de la hiérarchie viendra à la rescousse. Nous plaçons les fichiers avec le nom du format {fqdn }.yaml au bon endroit (par exemple, nodes/myserver.domain.net ), définissons les valeurs nécessaires des variables au niveau d'un serveur spécifique, et le pappet appliquera la même configuration pour les deux serveurs pour le rôle, et unique pour chacun des serveurs.


Exemple: deux backends avec du code php ont le même rôle et sont complètement identiques. Il est clair que nous ne voulons pas sauvegarder les deux serveurs - cela n'a aucun sens. Nous pouvons créer un rôle dans lequel décrire la même configuration pour les deux serveurs, puis créer un autre fichier nodes/backend1.semrush.net dans lequel placer la configuration pour la sauvegarde.


Le fichier de commandes teams/team-name.yaml indique la configuration de tous les serveurs qui appartiennent à l'équipe. Le plus souvent, il décrit les utilisateurs qui peuvent interagir avec ces serveurs, ainsi que leurs droits d'accès.


Sur la base de ces variables, nous avons construit cette hiérarchie . Plus le fichier trouvé dans la hiérarchie est élevé, plus la priorité de la configuration qui y est spécifiée est élevée.


Il s'ensuit que les variables peuvent remplacer en fonction de cette hiérarchie. C'est-à-dire que la variable dans le fichier de rôle " projects/%{::project}/%{::role} " a priorité sur la variable dans le fichier de projet " projects/%{::project} ". Les variables peuvent également fusionner à tous les niveaux de la hiérarchie si vous avez un module et / ou un profil / rôle écrit de manière à vous permettre de le faire. En spécifiant la partie commune de la configuration mysql pour tous les serveurs de projet, vous pouvez ajouter des parties spéciales qui ont du poids pour ce rôle à la même variable à d'autres niveaux de la hiérarchie (il y aura une section supplémentaire dans la configuration pour l'esclave).


Il s'avère que le fichier du nœud spécifique situé le long du chemin " hieradata/nodes/%{::fqdn} " a la priorité la plus élevée. Vient ensuite le fichier de noeud, mais déjà au niveau de la commande. Voici le bloc qui décrit d'autres faits plus généraux:


  - "virtual/%{::virtual}" - "os/%{::operatingsystem}/%{::operatingsystemmajrelease}" - "os/%{::operatingsystem}" - users - common 

Par conséquent, dans le fichier common.yaml nous avons une configuration qui devrait définitivement arriver à tous les serveurs, dans le fichier users.yaml tous les utilisateurs sont décrits (mais tous ne sont pas créés sur les serveurs, bien sûr), dans os/%{::operatingsystem} configuration générale typique pour les serveurs avec un OS spécifique (fact ::operatingsystem ) et ainsi de suite.


Je pense qu'en regardant cette hiérarchie, tout devient clair. Ci-dessous, je considérerai un exemple d'utilisation d'une telle hiérarchie. Mais vous devez d'abord parler des profils.


Profils


Un point important dans la configuration des serveurs à l'aide de modules est l'utilisation de profils. Ils sont situés sur le site/profiles chemin d'accès et constituent les points d'entrée des modules. Grâce à eux, vous pouvez configurer plus finement les modules suspendus sur le serveur et créer les ressources nécessaires.


Prenons un exemple simple. Il existe un module qui installe et configure redis. Et nous voulons également mettre le paramètre vm.overcommit_memory à 1 lors de la connexion de ce module, car ici . Ensuite, nous écrivons un petit profil qui fournit cette fonctionnalité:


 # standalone redis server class profiles::db::redis ( Hash $config = {}, String $output_buffer_limit_slave = '256mb 64mb 60', ) { # https://redis.io/topics/faq#background-saving-fails-with-a-fork-error-under-linux-even-if-i-have-a-lot-of-free-ram sysctl { 'vm.overcommit_memory': ensure => present, value => '1', } class { '::redis': * => $config, } } 

Comme mentionné ci-dessus, les profils sont un outil qui vous permet de changer / améliorer le comportement du module, ainsi que de réduire le nombre de configurations dans hiera. Si vous utilisez des modules distants, vous pouvez souvent rencontrer le problème que les modules «approuvés» n'ont souvent pas les fonctionnalités dont vous avez besoin, ou ont des bugs / défauts. Ensuite, en principe, vous pouvez cloner ce module et corriger / ajouter des fonctionnalités. Mais la bonne décision serait, si possible, d'écrire un bon profil qui peut «préparer» le module de la manière dont vous avez besoin. Vous trouverez ci-dessous quelques exemples de profils et vous comprendrez mieux pourquoi ils sont nécessaires.


Cacher des secrets à Hiera


Un des avantages importants de hiera par rapport au pappet nu est sa capacité à stocker des données sensibles dans des fichiers de configuration sous forme cryptée dans le référentiel. Vos mots de passe seront en sécurité.


En bref, vous utilisez la clé publique pour crypter les informations dont vous avez besoin et les placez avec une telle ligne dans le fichier hiera. La partie privée de la clé est stockée sur le maître Pappet, ce qui vous permet de décrypter ces données. Plus de détails peuvent être trouvés sur la page du projet .


Sur le client (ordinateur de travail), l'outil est installé simplement en utilisant gem install hiera-eyaml . De plus, en utilisant une commande de la forme eyaml encrypt --pkcs7-public-key=/path/to/public_key.pkcs7.pem -s 'hello' vous pouvez crypter les données et les coller dans un fichier avec l'extension eyaml ou simplement yaml, selon la façon dont vous configurer, puis le pappet le découvrira. Vous obtenez quelque chose comme:


 roles::postrgresql::password: 'ENC[PKCS7,MIIBeQYJKoZIhvcNAQcDoIIBajCCAWYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAbIz1ihQlThMWa9T+Lq194Y6QdElMD1XTev5y+VPSHtkPTu6Al6TJaSrXF+7phJIjue+NF4ZVtJCLkHxUR6nJJqks0fcGS1vF2+6mmM9cy69sIU1A3HqpOHZLuqHAc7jUqljYxpwWSIGOK6I2FygdAp5FfOTewqfcVVmXj97EJdcv3DKrbAlSrIMO2iZRYwQvyv+qnptnZ7pilR2veOCPW2UMm6zagDLutX9Ft5vERbdaiCiEfTOpVa9Qx0GqveNRVJLV/5lfcL5ajdNBJXkvKqDbx8d3ZBtEVAAqeKlw0LqzScgmCbWQx2kUzukX5LSxbTpT0Th984Vp1sl7iPk7UTA8BgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBCp5GcwidcEMA+0wjAMblkKgBCR/f9KGXUgLh3/Ok60OIT5]' 

Ou une chaîne multi-lignes:


 roles::postgresql::password: > ENC[PKCS7,MIIBeQYJKoZIhvcNAQcDoIIBajCCAWYCAQAxggEhMIIBHQIBADAFMAACAQEw DQYJKoZIhvcNAQEBBQAEggEAbIz1ihQlThMWa9T+Lq194Y6QdElMD1XTev5y +VPSHtkPTu6Al6TJaSrXF+7phJIjue+NF4ZVtJCLkHxUR6nJJqks0fcGS1vF 2+6mmM9cy69sIU1A3HqpOHZLuqHAc7jUqljYxpwWSIGOK6I2FygdAp5FfOTe wqfcVVmXj97EJdcv3DKrbAlSrIMO2iZRYwQvyv+qnptnZ7pilR2veOCPW2UM m6zagDLutX9Ft5vERbdaiCiEfTOpVa9Qx0GqveNRVJLV/5lfcL5ajdNBJXkv KqDbx8d3ZBtEVAAqeKlw0LqzScgmCbWQx2kUzukX5LSxbTpT0Th984Vp1sl7 iPk7UTA8BgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBCp5GcwidcEMA+0wjAM blkKgBCR/f9KGXUgLh3/Ok60OIT5] 

Il semble que nous ayons terminé la préparation, maintenant nous pouvons considérer un exemple.


Exemple de doigt


Spoiler : il y aura beaucoup plus de configurations, donc ceux qui sont intéressés par cet article d'intérêt purement théorique peuvent sauter cette section et aller à la fin.


Voyons maintenant un exemple de configuration d'un serveur utilisant hiera dans puppet4. Je ne publierai pas le code pour tous les profils, car sinon le message s'avérera assez volumineux. Je vais me concentrer sur la hiérarchie et la configuration de hiera.


La tâche est la suivante: nous devons déployer:


  • Deux serveurs DB identiques sur lesquels postgresql est déployé
  • Deux autres serveurs - frontend avec nginx
  • Cinquième et sixième serveur - backends python dans docker
  • Tout est identique dans l'environnement de développement, à l'exception d'une certaine configuration de serveur

Nous allons créer notre hiérarchie dans l'ordre et nous allons commencer par le fichier projet.


Projet


Créez le fichier de projet projects/kicker.yaml . Nous y mettons ce qui est commun à tous les serveurs: nous avons besoin de certains référentiels et dossiers pour le déploiement, ainsi que de l'utilisateur de déploiement lui-même.


 --- classes: - apt::debian::semrush files: "/srv/data": ensure: 'directory' owner: 'deploy' group: 'www-data' mode: '0755' '/srv/data/shared_temp': ensure: 'directory' owner: 'deploy' group: 'www-data' mode: '0775' user_management::present: - deploy 

Rôle Db


Créez un fichier de rôle pour les serveurs de base de données projects/kicker/db.yaml . Jusqu'à présent, nous nous passerons de diviser les serveurs en environnements:


 --- classes: - profiles::db::postgresql profiles::db::postgresql::globals: manage_package_repo: true version: '10' profiles::db::postgresql::db_configs: 'listen_addresses': value: '*' profiles::db::postgresql::databases: kicker: {} profiles::db::postgresql::hba_rules: 'local connect to kicker': type: 'local' database: 'kicker' user: 'kicker' auth_method: 'md5' order: '001' 'allow connect from 192.168.1.100': type: 'host' database: 'kicker' user: 'kicker' auth_method: 'md5' address: '192.168.1.100/32' order: '002' 

Ici, nous connectons un profil écrit pour une utilisation générale par tous ceux qui souhaitent installer postgres sur leur serveur. Nous configurons le profil et vous permettons de configurer le module de manière flexible avant de l'appliquer.


Pour les plus curieux, en dessous du code cat de ce profil:


Profil :: db :: postgresql
 class profiles::db::postgresql ( Hash $globals = {}, Hash $params = {}, Hash $recovery = {}, Hash[String, Hash[String, Variant[String, Boolean, Integer]]] $roles = {}, Hash[String, Hash[String, Variant[String, Boolean]]] $db_configs = {}, Hash[String, Hash[String, Variant[String, Boolean]]] $databases = {}, Hash[String, String] $db_grants = {}, Hash[String, Hash[String, String]] $extensions = {}, Hash[String, String] $table_grants = {}, Hash[String, Hash[String, String]] $hba_rules = {}, Hash[String, String] $indent_rules = {}, Optional[String] $role = undef, # 'master', 'slave' Optional[String] $master_host = undef, Optional[String] $replication_password = undef, Integer $master_port = 5432, String $replication_user = 'repl', String $trigger_file = '/tmp/pg_trigger.file', ){ case $role { 'slave': { $_params = { manage_recovery_conf => true, } if $globals['datadir'] { file { "${globals['datadir']}/recovery.done": ensure => absent, } } $_recovery = { 'recovery config' => { standby_mode => 'on', primary_conninfo => "host=${master_host} port=${master_port} user=${replication_user} password=${replication_password}", trigger_file => $trigger_file, } } $_conf = { 'hot_standby' => { value => 'on', }, } file { $trigger_file: ensure => absent, } } 'master': { $_conf = { 'wal_level' => { value => 'replica', }, 'max_wal_senders' => { value => 5, }, 'wal_keep_segments' => { value => 32, }, } file { $trigger_file: ensure => present, } } default: { $_params = {} $_recovery = {} $_conf = {} } } class { '::postgresql::globals': * => $globals, } class { '::postgresql::server': * => deep_merge($_params, $params), } create_resources('::postgresql::server::config_entry', deep_merge($_conf, $db_configs)) create_resources('::postgresql::server::role', $roles) create_resources('::postgresql::server::database', $databases) create_resources('::postgresql::server::database_grant', $db_grants) create_resources('::postgresql::server::extension', $extensions) create_resources('::postgresql::server::table_grant', $table_grants) create_resources('::postgresql::server::pg_hba_rule', $hba_rules) create_resources('::postgresql::server::pg_indent_rule', $indent_rules) create_resources('::postgresql::server::recovery', deep_merge($_recovery, $recovery)) } 

Ainsi, nous installons Postgresql 10 un seul coup, configurons la configuration ( listen ), créons la base de données kicker et écrivons également deux règles d'accès à cette base de données dans pg_hba.conf . Cool!


Rôle frontal


Nous prenons la tête. Créez le fichier projects/kicker/frontend.yaml avec le contenu suivant:


 --- classes: - profiles::webserver::nginx profiles::webserver::nginx::servers: 'kicker.semrush.com': use_default_location: false listen_port: 80 server_name: - 'kicker.semrush.com' profiles::webserver::nginx::locations: 'kicker-root': location: '/' server: 'kicker.semrush.com' proxy: 'http://kicker-backend.semrush.com:8080' proxy_set_header: - 'X-Real-IP $remote_addr' - 'X-Forwarded-for $remote_addr' - 'Host kicker.semrush.com' location_cfg_append: 'proxy_next_upstream': 'error timeout invalid_header http_500 http_502 http_503 http_504' proxy_connect_timeout: '5' 

Ici, tout est simple. Nous connectons le profiles::webserver::nginx , qui prépare l'entrée dans le module nginx, et définissons également les variables, en particulier le server et l' location de ce site.


Un lecteur attentif remarquera qu'il serait plus approprié de placer la description du site plus haut dans la hiérarchie, car nous aurons toujours un environnement de développement, et d'autres variables ( server_name , proxy ) y seront utilisées, mais ce n'est pas trop important. En décrivant le rôle de cette manière, nous pouvons voir comment ces variables ne sont redéfinies que par la hiérarchie.


Rôle Docker


Le rôle des projects/kicker/docker.yaml docker projects/kicker/docker.yaml :


 --- classes: - profiles::docker profiles::docker::params: version: '17.05.0~ce-0~debian-stretch' packages: 'python3-pip': provider: apt 'Fabric3': provider: pip3 ensure: 1.12.post1 user_management::users: deploy: groups: - docker 

Le profiles/docker.pp très simple et élégant. Je donnerai son code:


Profil :: docker
 class profiles::docker ( Hash $params = {}, Boolean $install_kernel = false, ){ class { 'docker': * => $params, } if ($install_kernel) { include profiles::docker::kernel } } 

Tout est prêt. Cela suffit déjà pour déployer le produit dont nous avons besoin sur de nombreux serveurs, en leur attribuant simplement un projet et un rôle spécifiques (par exemple, en plaçant le fichier au format souhaité dans le répertoire facts.d, dont l'emplacement dépend de la méthode d'installation de la marionnette).


Nous avons maintenant la structure de fichiers suivante:


 . ├── kicker │ ├── db.yaml │ ├── docker.yaml │ └── frontend.yaml └── kicker.yaml 1 directory, 4 files 

Nous allons maintenant traiter des environnements et de la définition d'une configuration unique à un rôle sur un site particulier.


Environnement et dérogation


Créons la configuration générale pour toutes les ventes. Le fichier projects/kicker/tiers/prod.yaml contient une indication que nous devons connecter une classe avec un pare-feu à cet environnement (enfin, prod tout de même), ainsi qu'une certaine classe qui offre un niveau de sécurité accru:


 --- classes: - semrush_firewall - strict_security_level 

Pour un environnement de développement, si nous devons décrire quelque chose de spécifique, le même fichier est créé et la configuration nécessaire y est entrée.


Ensuite, vous devez encore redéfinir les variables pour la configuration nginx du rôle frontend dans l'environnement de développement. Pour ce faire, vous devez créer le fichier projects/kicker/tiers/dev/frontend.yaml . Faites attention à un nouveau niveau de hiérarchie.


 --- profiles::webserver::nginx::servers: 'kicker-dev.semrush.com': use_default_location: false listen_port: 80 server_name: - 'kicker-dev.semrush.com' profiles::webserver::nginx::locations: 'kicker-root': location: '/' server: 'kicker-dev.semrush.com' proxy: 'http://kicker-backend-dev.semrush.com:8080' proxy_set_header: - 'X-Real-IP $remote_addr' - 'X-Forwarded-for $remote_addr' - 'Host kicker-dev.semrush.com' location_cfg_append: 'proxy_next_upstream': 'error timeout invalid_header http_500 http_502 http_503 http_504' proxy_connect_timeout: '5' 

Vous n'avez plus besoin de spécifier une classe, elle est héritée des niveaux précédents de la hiérarchie. Ici, nous avons changé server_name et proxy_pass . Un serveur qui a les faits role = frontend et tier = dev trouvera d'abord le fichier projects/kicker/frontend.yaml pour lui-même, mais ensuite les variables de ce fichier seront remplacées par le fichier projects/kicker/tiers/dev/frontend.yaml avec une priorité plus élevée .


Masquage du mot de passe pour PostgreSQL


Et nous avons donc le dernier point à l'ordre du jour - définir des mots de passe pour PostgreSQL.


Les mots de passe doivent varier dans les environnements. Nous utiliserons eyaml pour stocker en toute sécurité les mots de passe. Créez des mots de passe:


 eyaml encrypt -s 'verysecretpassword' eyaml encrypt -s 'testpassword' 

Nous collons les lignes reçues dans les fichiers **projects/kicker/tiers/prod/db.yaml** et **projects/kicker/tiers/dev/db.yaml** (ou vous pouvez utiliser l'extension eyaml, c'est personnalisable), respectivement. Voici un exemple:


 --- profiles::db::postgresql::roles: 'kicker': password_hash: > 'ENC[PKCS7,MIIBeQYJKoZIhvcNAQcDoIIBajCCAWYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAsdpb2P0axUJzyWr2duRKAjh0WooGYUmoQ5gw0nO9Ym5ftv6uZXv25DRMKh7vsbzrrOR5/lLesx/pAVmcs2qbhd/y0Vr1oc2ohHlZBBKtCSEYwem5VN+kTMhWPvlt93x/S9ERoBp8LrrsIvicSYZByNfpS2DXCFbogSXCfEPxTTmCOtlOnxdjidIc9Q1vfAXv7FRQanYIspr2UytScm56H/ueeAc/8RYK51/nXDMtdPOiAP5VARioUKyTDSk8FqNvdUZRqA3cl+hA+xD5PiBHn5T09pnH8HyE/39q09gE0pXRe5+mOnU/4qfqFPc/EvAgAq5mVawlCR6c/cCKln5wJTA8BgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBDNKijGHBLPCth0sfwAjfl/gBAaPsfvzZQ/Umgjy1n+im0s]' 

Ensuite, le mot de passe pour le rôle kicker viendra, sera déchiffré et appliqué sur le serveur de base de données dans PostgreSQL.


En fait, c'est tout. Oui, l'exemple s'est avéré énorme, mais, je l'espère, fonctionnel, ne laissant pas de questions, clair et utile. La hiérarchie résultante dans hiera est la suivante:


 . ├── db.yaml ├── docker.yaml ├── frontend.yaml └── tiers ├── dev │ ├── db.yaml │ └── frontend.yaml ├── prod │ └── db.yaml └── prod.yaml 3 directories, 7 files 

Vous pouvez regarder ces fichiers en direct en clonant un référentiel spécialement créé


Conclusion


La marionnette est bonne et facile à utiliser avec hiera. Je ne dirais pas que c'est un outil de configuration idéal dans le monde moderne, pas du tout, mais il mérite l'attention. Il gère très bien certaines tâches, et sa «philosophie» de maintien d'un état de ressources et de configuration constamment identique peut jouer un rôle important pour garantir la sécurité et l'uniformité des configurations.


Le monde moderne se synergise et se développe progressivement. Peu de gens utilisent désormais un seul système de configuration, souvent dans l'arsenal des développeurs et des administrateurs, il existe plusieurs systèmes à la fois. Et c'est bien, car il y a beaucoup de choix. L'essentiel est que tout soit logique et compréhensible, comment et où il peut être configuré.


En conséquence, notre objectif en tant qu'administrateurs est de ne rien configurer nous-mêmes. Tout cela devrait idéalement être fait par les équipes elles-mêmes. Et nous devons leur donner un outil ou un produit qui nous permet de le faire en toute sécurité, facilement et, surtout, avec un résultat précis. Eh bien, et aidez à résoudre des problèmes architecturaux et plus graves que "Vous devez installer PostgreSQL sur le serveur et créer un utilisateur." Camon, 2018 est dans la cour! Alors lancez marionnette et ansible et passez à un avenir sans serveur.


Avec le développement des systèmes de cloud, de conteneurisation et d'orchestration des conteneurs, les systèmes de gestion de configuration reculent lentement en arrière-plan pour les utilisateurs et les clients. Vous pouvez également créer un cluster de conteneurs à sécurité intégrée dans le cloud et conserver vos applications dans des conteneurs avec auto-skelling, sauvegarde, réplication, découverte automatique, etc., sans écrire une seule ligne pour ansible, marionnette, chef, etc. Vous n'avez rien à faire (enfin, presque). En revanche, il y a moins de serveurs de fer à cause des nuages. C'est juste que vous n'avez plus besoin de les configurer, cette action est de la responsabilité du fournisseur de cloud. Mais il est peu probable qu'ils utilisent les mêmes systèmes que les mortels ordinaires.


Crédits


Merci:


  • Dmitry Tupitsin, Dmitry Loginov, Stepan Fedorov et toute l'équipe d'administrateurs système pour leur aide dans la préparation de cet article
  • Vladimir Legkostupov pour la photo
  • Yana Tabakova pour avoir organisé tout cela et aidé à passer par toutes les étapes de la pré-publication
  • Nikita Zakharov pour son assistance en matière de licences

Source: https://habr.com/ru/post/fr412587/


All Articles