Chef - Introduction à l'outil de Gestion de Configuration Chef Infra
Publié le : 25 août 2022 | Mis à jour le : 27 juin 2023Vous savez que j’affectionne Ansible comme
outil de gestion de configuration, mais voilà pourquoi ne pas découvrir ce
qui se fait dans les autres outils ? Aujourd’hui, je vais démarrer la série avec
Chef Infra. Par la suite nous verrons
Puppet et Salt. Bien sûr, je ne suis pas
spécialiste du sujet, mais je vous propose de partager mes avancées sur
l’utilisation de Chef Infra. Laissez-moi vos remarques et vos tips
en
commentaires.
Table des matières
Présentation de Chef
Chef Infra est donc 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é soit dépréciés, soit renommés.
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.deb
sudo dpkg -i chef-workstation_21.10.640-1_amd64.deb
On vérifie que tout est bien installé :
chef -v
Chef Workstation version: 21.10.640
Chef Infra Client version: 17.6.18
Chef InSpec version: 4.46.13
Chef CLI version: 5.4.2
Chef Habitat version: 1.6.351
Test Kitchen version: 3.1.0
Cookstyle 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_cookbook
Generating cookbook my_first_cookbook
Loading 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_action
end
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 :install
end
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'
end
end
Tester notre premier cookbook sur notre machine cible
Maintenant que notre machine est prête, nous allons lancer sa première exécution :
vagrant up
Bringing 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 ssh
vagrant@ubuntu2204:~$ which nmap
/usr/bin/nmap
nmap -V
Nmap version 7.80 ( https://nmap.org )
Platform: x86_64-pc-linux-gnu
Compiled 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 ipv6
Compiled 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 :install
end
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 ssh
id toto
uid=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"
end
end
On lance le tout :
vagrant reload --provision
Je vais en rester là pour aujourd’hui.
Plus loin
Il s’agit de la première version de ce billet que je complèterai avec la suite de mes découvertes. Donc, revenez de temps en temps si le sujet vous intéresse.
La documentation en ligne de ‘Chef Infra’ est plutôt complète alors je vous conseille de la parcourir. De plus pour progresser n’hésitez pas à parcourir le code source des recettes du supermarket chef. C’est comme cela que je procède …
À bientôt.