Nous allons voir dans cet article comment automatiser la création d’AMIs avec Packer. Le but étant d’avoir à disposition un bac à sable Ansible sur des instances EC2. Nous pourrons ainsi tester nos scripts et rôles dans un environnement éphémère et reproductible.
Qu’est-ce que Packer
Packer est un outil open-source développé par HashiCorp. Il permet de créer facilement des images de système d’exploitation pour des machines virtuelles ou des conteneurs docker en s’appuyant sur un template.
Cet outil fonctionne sur différents environnements, cloud, on-premise, en local sur votre poste de travail.
Voici la liste de tous les plugins disponibles (https://developer.hashicorp.com/packer/plugins).
Maintenant que le décor est posé, plongeons nous dans le vif du sujet avec l’écriture de ce fameux template. 🖋️
Le template Packer
Avant tout, il faut installer Packer. Je vous laisse consulter la documentation ici.
Le template Packer va nous permettre de définir les images que nous souhaitons construire et les étapes pour y arriver. Dans notre cas, nous aurons deux images :
- Ansible controller : pour lancer nos playbooks et rôles sur les machines cibles
- Ansible host : ce seront nos cibles pour valider la bonne exécution et les résultats des scripts Ansible
Voici ce que nous allons réaliser :
- Création d’un utilisateur ansible sur toutes les images
- Installation de python sur toutes les images
- Ajouter cet utilisateur avec les droits d’administrateur sans mot de passe (on omettra la partie sécurité dans le cadre de nos tests).
- Génération d’une paire de clés SSH
- Ajout de la clé publique dans l’image ansible host et de clé privée dans l’image ansible controller
- Installation d’ansible sur l’image controller
Voyons à présent comment retranscrire toutes ces étapes dans le template.
Ecriture du template Packer
Commençons par créer un nouveau répertoire packer-ansible-sandbox
pour y placer notre template que l’on nommera lab-ansible-aws.pkr.hcl
Packer
Déclarons un bloc packer {}
qui contiendra les plugins et les versions requises pour notre projet :
packer {
required_plugins {
amazon = {
version = ">= 1.1.5"
source = "github.com/hashicorp/amazon"
}
}
}
Ici, nous renseignons le plugin amazon pour être en mesure de construire nos AMIs et utiliser le cloud provider AWS.
Variables
Afin de rendre dynamique la construction de nos images, nous utilisons des variables. Celles-ci vont nous être utiles pour renseigner le chemin vers les clés ssh à pousser dans nos images.
Ajoutons nos blocs variable {}
:
variable "ssh_key_public_path" {
type = string
default = "/tmp/ansible.pub"
}
variable "ssh_key_private_path" {
type = string
default = "/tmp/ansible"
}
Ce bloc déclare deux variables ssh_key_public_path
et ssh_key_private_path
avec une valeur par défaut (que vous pouvez modifier à votre guise). On y retrouve l’emplacement des clés ssh à pousser sur les instances afin de faire communiquer le controller avec les hosts.
Source
Maintenant, déclarons nos blocs source {}
. Ils vont nous permettre de configurer quel type de virtualisation utiliser, comment lancer nos images et comment nous y connecter.
Les blocs source
comportent deux labels :
- un type de builder
- un nom
Dans notre cas, nous déclarons deux sources de type, amazon-ebs (si vous voulez plus de détails voici la documentation) avec les noms ansible-controller et ansible-host.
data "amazon-ami" "debian11" {
filters = {
name = "debian-11-amd64-*"
root-device-type = "ebs"
virtualization-type = "hvm"
}
max_retries = "2"
most_recent = true
owners = ["136693071363"]
}
source "amazon-ebs" "ansible-controller" {
ami_name = "ansible-controller"
instance_type = "t2.micro"
region = "eu-west-3"
source_ami = "${data.amazon-ami.debian11.id}"
ssh_username = "admin"
}
source "amazon-ebs" "ansible-host" {
ami_name = "ansible-host"
instance_type = "t2.micro"
region = "eu-west-3"
source_ami = "${data.amazon-ami.debian11.id}"
ssh_username = "admin"
}
Nous avons déclaré un bloc data qui nous permet de spécifier le système d’exploitation à utiliser. J’ai fait le choix de debian 11, libre à vous de le modifier.
Si nous reprenons nos blocs, nous spécifions :
- le nom de l’AMI qui va être créée :
ami_name
- le type d’instance :
t2.micro
- la région où va être créée l’AMI :
eu-west-3
- la source de l’ami :
${data.amazon-ami.debian11.id}
- l’utilisateur SSH pour le provisionning :
admin
(attention, l’utilisateur dépend de l’AMI utilisée dans le bloc data)
Build
À présent, intéressons-nous au bloc build
. Celui-ci définit les opérations à faire sur les instances EC2.
Les blocs de type provisionner {}
nous permettent d’automatiser les modifications que l’on souhaite apporter à notre image.
build {
name = "lab-ansible"
sources = [
"source.amazon-ebs.ansible-controller",
"source.amazon-ebs.ansible-host"
]
provisioner "file" {
source = "${var.ssh_key_private_path}"
destination = "/tmp/ansible"
only = ["amazon-ebs.ansible-controller"]
}
provisioner "file" {
source = "${var.ssh_key_public_path}"
destination = "/tmp/ansible.pub"
only = ["amazon-ebs.ansible-host"]
}
provisioner "shell" {
only = ["amazon-ebs.ansible-controller"]
scripts = [
"scripts/common.sh",
"scripts/controller.sh"
]
}
provisioner "shell" {
only = ["amazon-ebs.ansible-host"]
scripts = [
"scripts/common.sh",
"scripts/host.sh"
]
}
}
Ici, nous indiquons nos 2 sources source.amazon-ebs.ansible-controller
et source.amazon-ebs.ansible-host
.
Nos deux premiers provisionner
sont de type “file”, pour transférer nos clés SSH sur les instances EC2. Suivi de deux autres provisionner “shell” servant à exécuter des commandes sur les instances.
L’argument scripts indique quels fichiers bash il va falloir exécuter sur l’instance. Ces scripts reprennent les étapes de création définies précédemment (ils sont sur mon GitLab ). Notons également l’argument only
qui nous permet de cibler une source particulière pour une action donnée.
Vous pouvez retrouver l’entièreté de ce template ainsi que les scripts associés sur mon GitLab.
Construction des AMIs
Avant de construire vos AMIs, assurez-vous d’avoir vos credentials AWS. Ansi Packer pourra les utiliser, soit en alimentant votre fichier de configuration, soit en utilisant des variables d’environnement.
Concernant les permissions IAM, vous devez pouvoir créer, modifier et supprimer des instances EC2. Vous retrouverez en detail les permissions requises ici.
Initialisons notre configuration avec la commande packer init .
. Veillez à être dans le répertoire packer-ansible-sandbox
.
Afin de formater et de valider notre code, nous pouvons réaliser ces deux commandes :
$ packer fmt .
$ packer validate .
Enfin, voici le moment tant attendu ! 🥳
Lançons le build de nos images avec la commande packer build .
Si le build s’est bien passé, vous devriez avoir cet output :
==> Wait completed after 5 minutes 23 seconds
==> Builds finished. The artifacts of successful builds are:
--> lab-ansible.amazon-ebs.ansible-controller: AMIs were created:
eu-west-3: ami-433731c882d9c8c08
--> lab-ansible.amazon-ebs.ansible-host: AMIs were created:
eu-west-3: ami-339a654436ae50c02
Nous pouvons nous rendre sur la console AWS et confirmer que nous retrouvons nos AMI.
Il vous suffit à présent, de lancer vos instances EC2 en sélectionnant nos AMI. On se connecte au controller en ssh et enjoy !
Vous pouvez concevoir et tester vos scripts Ansible 🥳.
Conclusion
Dans cet article, nous avons vu comment créer des AMI pour automatiser la mise en place d’un environnement Ansible avec Packer.
Bien entendu, vous pouvez adapter les étapes et le contenu du template à vos besoins.
Packer ne fait que construire des images, c’est à vous de les lancer ou de les détruire comme bon vous semble.
Il est tout à fait possible de poursuivre avec Terraform, pour automatiser le lancement de machines EC2, la mise en place des security group etc.
Attention toutefois à la facture Amazon 💰. Après avoir exécuté les étapes ci-dessus, les AMI sont associées à votre compte AWS et stockées dans S3. Elles peuvent vous être facturées.
Vous pouvez supprimer l’AMI en commençant par la désenregistrer depuis la console AWS, puis supprimer le snapshot associé sur la page de gestion des snapshots AWS.
J’espère que cet article vous aura été utile. Si vous avez des remarques ou des axes d’amélioration n’hésitez pas à m’en faire part. Je suis disponible via Linkedin ou Twitter. 😀
Comments are closed.