Comment créer des images personnalisées sur Azure avec Packer
Sommaire
Dans un article précèdent, nous avons exploré le processus de création d’une image machine personnalisée sur Google Cloud.
Lien vers l’article:
Dans celui-ci, nous allons faire la même chose sur Azure. Le scénario reste le même.
Vous travaillez dans une entreprise où chaque machine virtuelle lancée doit contenir votre version à vous de certains logiciels par exemple java, python, un logiciel de monitoring et logging système. Afin de s’assurer que les images créées soient preconfiguré, vous décidez de créer des images personnalisées pour les utiliser sur vos diffèrents Cloud provider.
Vous avez bien sûr vos playbook ansible qui vous permettent déjà de faire ces configurations sur vos machines.
C’est le moment d’utiliser un outil comme Packer pour automatiser la création et la configuration de vos images personnalisées.
Je vous invite à lire, l'article precedent pour vous familiariser avec les concepts de images personnalisées/ image de référence / golden image / master image / baseline image
Nous allons utiliser Azure CLI pour nos actions.
Assez simple avec az group create.
az group create --name "lab-resource-group" --location francecentral
{
"id": "/subscriptions/xxx/resourceGroups/lab-resource-group",
"location": "francecentral",
"managedBy": null,
"name": "lab-resource-group",
"properties": {
"provisioningState": "Succeeded"
},
"tags": null,
"type": "Microsoft.Resources/resourceGroups"
}
Déjà, c’est quoi une Shared Image Gallery ? Le nom est explicite, c'est un répertoire d’image machine bien définie et versionner qui permet de stocker et de gérer les différentes images personnalisées qu’on crée.
Voici à quoi ressemble l’arborescence des ressources inclus dans le shared image gallery
Galerie d'images partagées (SIG)
│
├── Galerie
│ ├── Définition d'image
│ │ └── Version d'image
│ │ ├── Réplication
│ │ └── Contrôle d'accès
│ │
│ └── Définition d'image
│ └── Version d'image
│ ├── Réplication
│ └── Contrôle d'accès
│
└── Contrôle d'accès
Shared Image Gallery
Nous allons utiliser la commande az sig create pour créer la galerie.
az sig create \
--resource-group lab-resource-group \
--gallery-name loopbin_linux_image_gallery
Définition de l’image
Nous allons utiliser la commande az sig image-definition create pour créer la galerie.
az sig image-definition create \
--resource-group lab-resource-group \
--gallery-name loopbin_linux_image_gallery \
--gallery-image-definition loopbin-ubuntu-server-2204 \
--publisher "Loopbin" \
--offer "basic" \
--sku "standard" \
--os-type linux \
--os-state Generalized \
--hyper-v-generation V2
Nous allons créer un service principal (service account sur Google Cloud) afin de nous authentifie sur Azure. Nous donnerons aussi des rôles à ce service pour qu’il puisse faire les actions nécessaires.
Avant de créer notre service principal, pour ne pas utiliser le rôle Contributor
nous allons créer un rôle spécialement pour packer
Voici la définition de notre rôle
{
"Name": "PackerDeployRole",
"Description": "Role pour Packer",
"Actions": [
"Microsoft.Compute/*/write",
"Microsoft.Compute/*/read",
"Microsoft.Compute/*/delete",
"Microsoft.Compute/virtualMachines/*",
"Microsoft.Compute/images/write",
"Microsoft.Storage/*/read",
"Microsoft.Storage/storageAccounts/listKeys/action",
"Microsoft.Resources/subscriptions/resourceGroups/read",
"Microsoft.Resources/subscriptions/resourceGroups/resources/read",
"Microsoft.Resources/deployments/*",
"Microsoft.Network/virtualNetworks/*",
"Microsoft.Network/networkInterfaces/*",
"Microsoft.Network/publicIPAddresses/*"
],
"AssignableScopes": [
"/subscriptions/XXX/resourceGroups/lab-resource-group"
]
}
Et la commande suivant pour la création du rôle
az role definition create --role-definition PackerDeployRole.json
Nous allons utiliser la commande az ad sp create-for-rbac
az ad sp create-for-rbac \
--display-name "packer-service-principal" \
--role PackerDeployRole \
--scopes "/subscriptions/XXX/resourceGroups/lab-resource-group" \
--query "{ ClientId: appId, ClientSecret: password, TenantId: tenant }"
En précisant l’option —qeury
, cette commande ne nous retournera que l'appId (ClientId), password (ClientSecret) et tenant (TenantId) que nous utiliserions pour authentifier Packer dans notre script HCL.
Notre script sera le suivant :
azure-ubuntu-2204.pkr.hcl
packer {
required_plugins {
azure = {
source = "github.com/hashicorp/azure"
version = "~> 2"
}
}
}
variable "subscription_id" {
type = string
description = "ID d'abonnement Azure"
}
variable "client_id" {
type = string
description = "ID client Azure (ID du principal de service)"
}
variable "client_secret" {
type = string
description = "Secret client Azure (mot de passe du principal de service)"
}
variable "tenant_id" {
type = string
description = "ID du locataire Azure"
}
variable "resource_group" {
type = string
description = "Groupe de ressources Azure"
}
variable "gallery_name" {
type = string
description = "Nom de la galerie d'images partagées"
default = "linux_image_gallery"
}
variable "image_name" {
type = string
description = "Nom de l'image"
default = "ubuntu-server-2204"
}
variable "image_version" {
type = string
description = "Version de l'image"
default = "1.0.0"
}
source "azure-arm" "ubuntu-base" {
client_id = var.client_id
client_secret = var.client_secret
subscription_id = var.subscription_id
tenant_id = var.tenant_id
os_type = "Linux"
image_offer = "0001-com-ubuntu-server-jammy"
image_publisher = "Canonical"
image_sku = "22_04-lts-gen2"
vm_size = "Standard_DS2_v2"
build_resource_group_name = var.resource_group
managed_image_name = "${var.image_name}-${var.image_version}"
managed_image_resource_group_name = var.resource_group
shared_image_gallery_destination {
subscription = var.subscription_id
resource_group = var.resource_group
gallery_name = var.gallery_name
image_name = var.image_name
image_version = var.image_version
replication_regions = ["westeurope"]
storage_account_type = "Standard_LRS"
}
communicator = "ssh"
}
build {
sources = ["source.azure-arm.ubuntu-base"]
provisioner "shell" {
inline = [
"sudo apt-get update && sudo apt-get upgrade -y"
]
}
}
Les différentes parties
plugins
: nous spécifions le plugin Azure à utiliser pour cette configuration Packer.variables
: déclaration de diverses variables qui seront utilisées tout au long de la configuration de Packer. Certains ont des valeurs par défaut et d'autres seront spécifiés dans la commande packer buildsource "azure-arm" "ubuntu-base"
:Le bloc source spécifie le générateur de sources dans Packer, ici spécifiquement pour Azure ARM. Dans ce bloc, des configurations spécifiques liées à Azure ARM sont définies, telles que les détails d'authentification (ID client, secret client, ID d'abonnement, ID de locataire), le type de système d'exploitation, les détails de l'image comme l'offre, l'éditeur et le SKU, la taille de la VM, et des détails sur l'image gérée et la galerie d'images partagées où l'image sera stockée.build
: Définit ce qui doit être construit par Packer. Ici, il utilise la source source.azure-arm.ubuntu-base
précédemment définie.provisioner
: fournisseur (de type shell dans ce cas) qui exécutera un ensemble de commandes pendant le processus de création d'images. Dans notre cas, il exécute un script shell pour mettre à jour et mettre à niveau les packages dans l'image en cours de création.Revenons sur quelques attributs de notre source :
shared_image_gallery_destination
: Cela nous aidera à spécifier les propriétés de la galerie d'images partagées sous lesquelles l'image gérée sera publiée en tant que version d'image de la galerie partagée.image_offer
, image_publisher
, image_sku
sont des informations à propos de votre image de base qui peuvent être récupéré de plusieurs façons différentesaz vm image list --offer Ubuntu --all --output table
--offer
spécifiant la distribution Linux. On peut remplacer Ubuntu par d'autres distributions Linux telles que Debian, CentOS, RedHat, etc.Notre fichier de variable vars.pkrvars.hcl
ressemble a ceci
subscription_id = "XXXX"
client_id = "XXXX"
client_secret = "XXXX"
tenant_id = "XXXX"
resource_group = "XXXX"
client_id
, client_secret
et tenant_id
nous ont été donné comme résultat après la création du service principal pour packer.
Valider notre fichier packer est assez simple, il suffit d’utiliser la commande
packer validate -var-file="vars.pkrvars.hcl" azure-ubuntu-2204.pkr.hcl
Pour build
notre image, nous allons utiliser la commande suivante
packer build -var-file="vars.pkrvars.hcl" azure-ubuntu-2204.pkr.hcl
Après le build terminé, nous pourrons avoir des infos à propos de notre image avec la commande
az image show --resource-group lab-resource-group \
--name loopbin-ubuntu-server-2204-1.0.0 \
--output yamlc
On peut utiliser une commande simple pour la création de la VM
az vm create \
--resource-group lab-resource-group \
--name test-loopbin-ubuntu-server-2204-1.0.0 \
--image loopbin-ubuntu-server-2204-1.0.0 \
--admin-username looper \
--generate-ssh-keys
On peut aussi sélectionner l’image durant la création de la VM par Azure Portal.