Lors de ce tuto, je vous propose de mettre en oeuvre 3 outils opensource sur une plateforme VMware VSphere :
Packer est un outil de construction automatique d’image de machine virtuelle. La création de templates, avec Packer va permettre de déployer dans le template des stratégies de sécurité, du hardening de l’OS, des créations d’utilisateurs, clés ssh, …
Astuce : si vous déclenchez plusieurs fois le script de création, ssh va créer une entrée dans le fichier ~/.ssh/known_hosts qui va générer une erreur de connexion ssh, afin de l’éviter je supprime systématiquement l’entrée avec la commande ssh-keygen.
ssh-keygen -f "/home/demo/.ssh/known_hosts" -R "192.168.1.2"
Afin de définir notre image cible, nous allons fournir à Packer ce fichier de définition json. Ce fichier comporte 4 zones :
{
"builders" : [
{
"type" : "vsphere-iso",
"vcenter_server" : "192.168.1.201",
"username" : "administrator@phy-cluster.apps.local",
"password" : "superpassword",
"insecure_connection" : "true",
"notes": "Build via Packer",
"datacenter" : "APPS",
"cluster":"Cluster-Apps",
"datastore":"NFS",
"network": "Net",
"guest_os_type": "centos7_64Guest",
"boot_wait":"10s",
"boot_order":"disk,cdrom,floppy",
"vm_name" : "CENTOS-8.x",
"ssh_username": "demo",
"ssh_password":"superpassword",
"CPUs":"8",
"RAM":"8192",
"RAM_reserve_all": "false",
"convert_to_template": "true",
"folder": "Templates-VM",
"disk_controller_type": "pvscsi",
"disk_size":"25000",
"disk_thin_provisioned": "true",
"network_card": "vmxnet3",
"iso_paths": [
"[NFS] ISO/CentOS8.iso"
],
"floppy_files": [
"ks.cfg"
],
"boot_command": [
"<esc><wait>",
"linux ks=hd:fd0:/ks.cfg<enter>"
]
}
],
"provisioners" : [
{
"type":"shell",
"inline":[
"touch done.txt"]
},
{
"type":"ansible",
"extra_arguments": ["--inventory-file=hosts.ini"],
"playbook_file":"site.yml",
"user":"demo"
}
]
}
En fonction de la distribution Linux, le fichier de démarrage sera spécifique à chaque distribution Linux. Dans mon cas il s’agit d’une distribution Linux Centos qui a besoin d’un fichier kickstart (ks.cfg dans mon fichier json ci-dessus) :
install
cdrom
lang fr_FR.UTF-8
keyboard fr
unsupported_hardware
network --bootproto=static --device=ens192 --gateway=192.168.1.254 --ip=192.168.1.2 --netmask=255.255.255.0 --nameserver=8.8.8.8 --hostname=Centos8Template
rootpw superpassword
firewall --enable
selinux --permissive
timezone Europe/Paris
unsupported_hardware
bootloader --location=mbr
text
skipx
zerombr
clearpart --all --initlabel
autopart
auth --enableshadow --passalgo=sha512 --kickstart
firstboot --disabled
eula --agreed
services --enabled=NetworkManager,sshd
reboot
user --name=demo --plaintext --password superpassword --groups=demo,wheel
sshkey --username=demo "ssh-rsa ******** demo@"
%packages --ignoremissing --excludedocs
@Base
@Core
openssh-clients
sudo
net-tools
wget
curl
%end
%post
yum update -y
echo "demo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/demo
sed -i "s/^.*requiretty/#Defaults requiretty/" /etc/sudoers
%end
On y retrouve les paramètres de l’OS, la création de compte (ici demo), le passage de clé ssh. Dans la partie post, je fais une mise à jour complète et l’utilisateur demo est promu sudoer.
Maintenant que les 2 fichiers ont été créés, nous allons lancer le build avec la commande suivante :
Le build Packer peut prendre un certain temps a ce réaliser en fonction des actions à exécuter.
> packer build centos.json
La sortie d’écran suivante s’afficher alors :
> ssh-keygen -f ~/.ssh/known_hosts -R 192.168.1.2; packer build centos8.json
# Host 192.168.1.2 found: line 9
/home/demo/.ssh/known_hosts updated.
Original contents retained as /home/demo/.ssh/known_hosts.old
vsphere-iso: output will be in this color.
==> vsphere-iso: Creating VM...
==> vsphere-iso: Customizing hardware...
==> vsphere-iso: Mounting ISO images...
==> vsphere-iso: Creating floppy disk...
vsphere-iso: Copying files flatly from floppy_files
vsphere-iso: Copying file: ks.cfg
vsphere-iso: Done copying files from floppy_files
vsphere-iso: Collecting paths from floppy_dirs
vsphere-iso: Resulting paths from floppy_dirs : []
vsphere-iso: Done copying paths from floppy_dirs
==> vsphere-iso: Uploading created floppy image
==> vsphere-iso: Adding generated Floppy...
==> vsphere-iso: Set boot order...
==> vsphere-iso: Power on VM...
==> vsphere-iso: Waiting 10s for boot...
==> vsphere-iso: Typing boot command...
==> vsphere-iso: Waiting for IP...
Une fois l’opération de création de la VM terminée, elle est transformée en template. Dans le client VMware Vsphere on voit le template CentOS-8.x dans le répertoire Templates-VM :
Terraform est un outil d’infra as code qui permet de provisionner et d’administrer des infrastructures on premise ou cloud de façon simple.
Dans le fichier Terraform, on retrouve des zones équivalentes à celle de Packer
terraform {
required_version = ">=0.12"
}
provider "vsphere" {
user = "administrator@phy-cluster.apps.local"
password = "superpassword"
vsphere_server = "192.168.1.201"
allow_unverified_ssl = true
}
data "vsphere_datacenter" "dc" {
name = "APPS"
}
data "vsphere_datastore" "datastore" {
name = "NFS"
datacenter_id = data.vsphere_datacenter.dc.id
}
data "vsphere_resource_pool" "pool" {
name = "Cluster-Apps/Resources"
datacenter_id = data.vsphere_datacenter.dc.id
}
data "vsphere_network" "network" {
name = "Net"
datacenter_id = data.vsphere_datacenter.dc.id
}
data "vsphere_virtual_machine" "template" {
name = "CENTOS-8.x"
datacenter_id = data.vsphere_datacenter.dc.id
}
resource "vsphere_virtual_machine" "vm" {
name = "terraform-test"
resource_pool_id = data.vsphere_resource_pool.pool.id
datastore_id = data.vsphere_datastore.datastore.id
num_cpus = 2
memory = 2048
guest_id = "centos7_64Guest"
network_interface {
network_id = data.vsphere_network.network.id
}
disk {
label = "disk0"
size = 24
}
clone {
template_uuid = data.vsphere_virtual_machine.template.id
customize {
linux_options {
host_name = "vincent"
domain = "test.com"
}
network_interface {
ipv4_address = "192.168.1.3"
ipv4_netmask = "24"
}
ipv4_gateway = "192.168.1.254"
dns_server_list = ["8.8.8.8"]
}
}
provisioner "local-exec" {
command = "ansible-playbook -i ../../new-roles/hosts.ini ../../new-roles/site.yml --tags linux"
}
}
Terraform propose plusieurs jeux de commandes, les plus utilisées sont les suivantes :
Pour initialiser l’environnement et downloader les plugins nécessaires au fichier de définition du déploiement Terraform :
> terraform init
Pour générer et visualiser le plan de déploiement :
> terraform plan
Pour construire ou modifier l’infrastructure :
> terraform apply
Voyons ce que ça donne quand on exécute la commande :
> terraform apply
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
vsphere_virtual_machine.vm: Creating...
vsphere_virtual_machine.vm: Still creating... [10s elapsed]
vsphere_virtual_machine.vm: Still creating... [20s elapsed]
vsphere_virtual_machine.vm: Still creating... [30s elapsed]
vsphere_virtual_machine.vm: Still creating... [40s elapsed]
vsphere_virtual_machine.vm: Still creating... [50s elapsed]
vsphere_virtual_machine.vm: Still creating... [1m0s elapsed]
vsphere_virtual_machine.vm: Still creating... [1m10s elapsed]
vsphere_virtual_machine.vm: Still creating... [1m20s elapsed]
vsphere_virtual_machine.vm: Provisioning with 'local-exec'...
vsphere_virtual_machine.vm (local-exec): Executing: ["/bin/sh" "-c" "ansible-playbook -i ../../new-roles/hosts.ini ../../new-roles/site.yml --tags linux"]
vsphere_virtual_machine.vm (local-exec): PLAY [centos] ******************************************************************
Quand le provisonning de la VM Vmware est effectué, dans l’interface du VCenter, on voit la VM.
Et voilà tout fonctionne à merveille !
Dans un futur article, je présenterai comment faire la même chose avec le système de virtualisation natif de Linux : kvm.