Introduction à Chef Infra
Mise à jour :
Chef Infra est un gestionnaire de configuration qui fonctionne
principalement soit en mode client-serveur, soit en mode autonome. Je me
limiterai dans cette présentation au mode autonome qui utilise la commande
chef-solo
.
Chef Infra prend en charge la configuration des serveurs Linux, Windows, MacOS mais aussi Unix.
Chef ne cesse d’évoluer et c’est ce qui m’a poussé à écrire ce billet. En effet, la plupart des ressources en français datent et font référence à des commandes qui ont été dépréciées ou renommées.
Faire ses premiers pas avec Chef Infra
Terminologie
Dans un premier temps il faut que je définisse le vocabulaire que l’on rencontre, tout tourne autour de la cuisine :
- cookbook : Les cookbooks, livres de recettes, sont des packages qui regroupent plus recipes qui permettent de configurer un composant spécifique sur les nœuds cibles.
- recipe : Ce sont les actions qui vont être executées sur les noeuds cibles écrit en Ruby.
- databags : à définir
- kitchen : Outils de test.
Installation de Chef-Workstation
Auparavant, on installait le ChefDK
mais il a été remplacé par
Chef-Workstation
qui inclut la plupart des outils nécessaires pour développer
des cookbooks.
Pour installer Chef-Workstation
, il suffit de se rendre sur le site de
Chef ↗ pour récupérer les
packages à destination de vos machines.
Voilà comment l’installer sur une Ubuntu, une fois le lien récupéré :
wget https://packages.chef.io/files/stable/chef-workstation/21.10.640/ubuntu/20.04/chef-workstation_21.10.640-1_amd64.debsudo dpkg -i chef-workstation_21.10.640-1_amd64.deb
On vérifie que tout est bien installé :
chef -vChef Workstation version: 21.10.640Chef Infra Client version: 17.6.18Chef InSpec version: 4.46.13Chef CLI version: 5.4.2Chef Habitat version: 1.6.351Test Kitchen version: 3.1.0Cookstyle version: 7.25.6
Passons aux choses sérieuses en écrivant notre premier cookbook.
Générer la structure de notre premier cookbook
Pour ne pas perdre de temps et surtout pour partir sur de bonnes bases, nous
allons utiliser la commande chef
pour générer notre premier cookbook.
Dans un répertoire vierge, créez un dossier cookbooks et lancez la commande
chef generate cookbook
dedans.
mkdir cookbooks;cd cookbooks
chef generate cookbook my_first_cookbookGenerating cookbook my_first_cookbookLoading Chef InSpec profile files:Loading Chef InSpec input files:Loading Chef InSpec waiver files:- Ensuring correct cookbook content- Committing cookbook files to git
Your cookbook is ready. Type `cd my_first_cookbook` to enter it....
Affichons le contenu pour identifier les principaux éléments :
tree ..└── my_first_cookbook ├── CHANGELOG.md ├── chefignore ├── kitchen.yml ├── LICENSE ├── metadata.rb ├── Policyfile.rb ├── README.md ├── recipes │ └── default.rb └── test └── integration └── default └── default_test.rb
C’est dans le fichier recipes/default.rb
que nous allons décrire les actions
que notre recette va exécuter.
Ces actions sont déclarées en ruby et contiennent des ressources fournies par chef. Une ressource est décrite de cette manière :
type 'name' do attribute 'value' action :type_of_actionend
Par exemple, nous allons utiliser la ressource package
qui installe des
packages sur toutes les distributions prises en charge par Chef.
Dans notre fichier de recette recipes/default.rb
, ajoutez ces lignes :
package 'nmap' do action :installend
Comment tester notre Cookbook ?
Mise en place du terrain de test avec Vagrant
Plutôt que de tester nos cookbooks sur notre machine de développement, nous
allons utiliser une machine virtuelle instanciée avec Vagrant. Ça tombe bien
puisque Vagrant mets à disposition un provisionner
chef-solo
↗ qui se
charge d’installer chef-solo
, de copier les cookooks sur la machine cible
avant de lancer leurs exécutions.
Vagrant.configure("2") do |config| config.vm.box = "generic/ubuntu2204" config.vm.provision :chef_solo do |chef| chef.arguments = "--chef-license accept" chef.cookbooks_path = "./cookbooks" chef.add_recipe = 'my_first_cookbook' endend
Tester notre premier cookbook sur notre machine cible
Maintenant que notre machine est prête, nous allons lancer sa première exécution :
vagrant upBringing machine 'default' up with 'libvirt' provider...==> default: Checking if box 'generic/ubuntu2204' version '4.1.6' is up to date...==> default: Auto-generating node name for Chef...
...
==> default: Waiting for machine to boot. This may take a few minutes... default: SSH address: 192.168.121.243:22 default: SSH username: vagrant default: SSH auth method: private key default: default: Vagrant insecure key detected. Vagrant will automatically replace default: this with a newly generated keypair for better security. default: default: Inserting generated public key within guest... default: Removing insecure key from the guest if it's present... default: Key inserted! Disconnecting and reconnecting using new SSH key...==> default: Machine booted and ready!==> default: Rsyncing folder: /tmp/test/cookbooks/ => /tmp/vagrant-chef/21e67ad2b7e7c1c72838d8a9db2ffe90/cookbooks==> default: Running provisioner: chef_solo... default: Installing Chef (latest)...==> default: Generating chef JSON and uploading...==> default: Running chef-solo...==> default: [2022-08-25T08:47:14+00:00] INFO: Persisting a license for Chef Infra Client at path /etc/chef/accepted_licenses/chef_infra_client==> default: [2022-08-25T08:47:14+00:00] INFO: Persisting a license for Chef InSpec at path /etc/chef/accepted_licenses/inspec==> default: +---------------------------------------------+==> default: ✔ 2 product licenses accepted.==> default: +---------------------------------------------+==> default: [2022-08-25T08:47:14+00:00] INFO: Started Chef Infra Zero at chefzero://localhost:1 with repository at /tmp/vagrant-chef/21e67ad2b7e7c1c72838d8a9db2ffe90 (One version per cookbook)==> default: Chef Infra Client, version 17.10.3==> default: Patents: https://www.chef.io/patents==> default: Infra Phase starting==> default: [2022-08-25T08:47:14+00:00] INFO: *** Chef Infra Client 17.10.3 ***==> default: [2022-08-25T08:47:14+00:00] INFO: Platform: x86_64-linux==> default: [2022-08-25T08:47:14+00:00] INFO: Chef-client pid: 2193==> default: [2022-08-25T08:47:22+00:00] INFO: Setting the run_list to ["recipe[my_first_cookbook]"] from CLI options==> default: [2022-08-25T08:47:22+00:00] INFO: Run List is [recipe[my_first_cookbook]]==> default: [2022-08-25T08:47:22+00:00] INFO: Run List expands to [my_first_cookbook]==> default: [2022-08-25T08:47:22+00:00] INFO: Starting Chef Infra Client Run for vagrant-d6b95fb9==> default: [2022-08-25T08:47:22+00:00] INFO: Running start handlers==> default: [2022-08-25T08:47:22+00:00] INFO: Start handlers complete.==> default: Resolving cookbooks for run list: ["my_first_cookbook"]==> default: [2022-08-25T08:47:22+00:00] INFO: Loading cookbooks [my_first_cookbook@0.1.0]==> default: Synchronizing cookbooks:==> default: [2022-08-25T08:47:22+00:00] INFO: Storing updated cookbooks/my_first_cookbook/README.md in the cache.==> default: [2022-08-25T08:47:22+00:00] INFO: Storing updated cookbooks/my_first_cookbook/chefignore in the cache.==> default: [2022-08-25T08:47:22+00:00] INFO: Storing updated cookbooks/my_first_cookbook/LICENSE in the cache.==> default: [2022-08-25T08:47:22+00:00] INFO: Storing updated cookbooks/my_first_cookbook/metadata.rb in the cache.==> default: [2022-08-25T08:47:22+00:00] INFO: Storing updated cookbooks/my_first_cookbook/CHANGELOG.md in the cache.==> default: [2022-08-25T08:47:22+00:00] INFO: Storing updated cookbooks/my_first_cookbook/recipes/default.rb in the cache.==> default:==> default: - my_first_cookbook (0.1.0)==> default: Installing cookbook gem dependencies:==> default: Compiling cookbooks...==> default: Loading Chef InSpec profile files:==> default: Loading Chef InSpec input files:==> default: Loading Chef InSpec waiver files:==> default: Converging 0 resources==> default: [2022-08-25T08:47:22+00:00] INFO: Chef Infra Client Run complete in 0.339408708 seconds==> default: Running handlers:==> default: [2022-08-25T08:47:22+00:00] INFO: Running report handlers==> default: Running handlers complete==> default: [2022-08-25T08:47:22+00:00] INFO: Report handlers complete==> default: Infra Phase complete, 0/0 resources updated in 08 seconds
Vous voyez Vagrant s’est bien chargé d’installer chef-solo
et de copier notre
cookbook
avant de l’exécuter.
Vérifions que nmap
a bien été installé sur notre machine :
vagrant sshvagrant@ubuntu2204:~$ which nmap/usr/bin/nmapnmap -VNmap version 7.80 ( https://nmap.org )Platform: x86_64-pc-linux-gnuCompiled with: liblua-5.3.6 openssl-3.0.0 nmap-libssh2-1.8.2 libz-1.2.11 libpcre-8.39 libpcap-1.10.1 nmap-libdnet-1.12 ipv6Compiled without:Available nsock engines: epoll poll select
Super. Nous pouvons continuer à développer notre recette en piochant dans les ressources mises à notre disposition. La liste se trouve ici ↗
Ajoutons la création d’un user sur notre machine :
package 'nmap' do action :installend
user 'toto' do comment 'User toto' uid 1234 gid 'kvm' home '/home/toto' shell '/bin/bash' password '$1$JJsvHslasdfjVEroftprNn4JHtDi'end
Relançons notre cookbook
, mais attention pour que nos modifications soient
prises en compte il faut recharger notre machine :
vagrant reload --provision
=> default: Attempting graceful shutdown of VM...==> default: Creating shared folders metadata...==> default: Starting domain.==> default: Waiting for domain to get an IP address...==> default: Waiting for machine to boot. This may take a few minutes... default: SSH address: 192.168.121.243:22 default: SSH username: vagrant default: SSH auth method: private key default: Warning: Host unreachable. Retrying......==> default: Machine booted and ready!==> default: Rsyncing folder: /tmp/test/cookbooks/ => /tmp/vagrant-chef/21e67ad2b7e7c1c72838d8a9db2ffe90/cookbooks==> default: Running provisioner: chef_solo...==> default: Detected Chef (latest) is already installed==> default: Generating chef JSON and uploading...==> default: Running chef-solo...==> default: [2022-08-25T09:01:31+00:00] INFO: Started Chef Infra Zero at chefzero://localhost:1 with repository at /tmp/vagrant-chef/21e67ad2b7e7c1c72838d8a9db2ffe90 (One version per cookbook)==> default: Chef Infra Client, version 17.10.3...
Vérifions que notre utilisateur a bien été créé sur la machine cible :
vagrant sshid totouid=1234(toto) gid=108(kvm) groups=108(kvm)
Utiliser des cookbooks de la communauté
Plutôt que de réinventer la roue, nous allons utiliser les cookbooks mis à disposition par la communauté. Il suffit de faire ses courses dans le supermarket chef ↗.
Attention : Attention vérifier que le cookbook prend en charge votre
distribution et ne soit pas trop VIEUX. Je vais tester le cookbook
pyenv
.
Pour télécharger des cookbooks il faut créer un fichier Berksfile
, dans
lequel nous allons mettre notre liste de courses :
source 'https://supermarket.chef.io'
cookbook 'pyenv'
Maintenant, nous pouvons le récupérer sur notre machine, pour cela nous allons
utiliser l’outil berks
:
Resolving cookbook dependencies...Fetching cookbook index from https://supermarket.chef.io...Using pyenv (4.1.0)Vendoring pyenv (4.1.0) to cookbooks/pyenv
Si vous regardez dans le répertoire cookbooks, vous y trouverez le cookbook.
Il faut maintenant y ajouter notre recette. Créer un dossier recipes
avec le
fichier default.rb
:
mkdir -p cookbooks/my_first_cookbook/recipes/
Mettez-y ce contenu (exemple récupéré dans le projet source) :
# Install Python system wide# and make it the global default
version = '3.7.7'local_folder = '/opt/pyenv_test'
directory local_folder
pyenv_install 'system'
# pyenv_rehash 'for-new-python'
pyenv_python version
pyenv_local version do path local_folder user 'root'end
pyenv_global version
pyenv_plugin 'virtualenv' do git_url 'https://github.com/pyenv/pyenv-virtualenv'end
pyenv_pip 'requests' do version '2.18.3'end
En quelques mots, nous demandons à installer pyenv
au niveau system et
python dans sa version 3.7.7
. On installe également le plugin
pyenv-virtualenv
et le package requests
avec pyenv_pip
.
Avant de le lancer il faut ajouter la recette pyenv
à notre le Vagrantfile
:
Vagrant.configure("2") do |config| config.vm.box = "generic/ubuntu2204" config.vm.provision :chef_solo do |chef| chef.arguments = "--chef-license accept" chef.cookbooks_path = "./cookbooks" chef.add_recipe "my_first_cookbook" chef.add_recipe "pyenv" endend
On lance le tout :
vagrant reload --provision
Plus d’infos
- Site Officiel: chef.io ↗