Init repo

This commit is contained in:
Ghislain
2025-12-18 21:26:22 +01:00
commit 853a7234a4
11 changed files with 586 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
ssh/*.pub

5
.pre-commit-config.yaml Normal file
View File

@@ -0,0 +1,5 @@
repos:
- repo: https://github.com/sirosen/fix-smartquotes
rev: 0.1.1
hooks:
- id: fix-smartquotes

58
README.md Normal file
View File

@@ -0,0 +1,58 @@
![Proxmox](https://img.shields.io/static/v1?style=for-the-badge&message=Proxmox&color=E57000&logo=Proxmox&logoColor=FFFFFF&label=) ![Packer](https://img.shields.io/badge/packer-%23E7EEF0.svg?style=for-the-badge&logo=packer&logoColor=%2302A8EF)
# Déploiement Packer d'une machine Debian sur Proxmox
## Qu'est ce que Packer ?
> Packer est une solution opensource permettant de construire des images machine pour de multiples plateformes cloud. Il est utilisé dans une approche « d'infrastructure as code » afin de pouvoir maintenir facilement les logiciels déployés sur les serveurs. - Syloe
L'objectif de ce dépôt est de déployer une template de machine virtuelle Debian pré-configurée. *(Authentification par clé SSH, ou installation d'un agent de supervision à la fin de l'installation)*
## Démarrer le projet
Pré-requis:
- [j2cli](https://pypi.org/project/j2cli/)
- [Packer](https://packer.io)
Editez le fichier `build.sh` pour y mettre les identifiants de votre Proxmox :
```bash
export proxmox_url="https://IP_PROXMOX:8006/api2/json"
export proxmox_node="NOM_NOEUD"
export proxmox_username="root@pam" # packer@pve si vous créez un utilisateur "packer".
export proxmox_password="Password"
```
*Pensez à vérifier que les noms des pools de stockages sont les mêmes que vous (local, local-zfs)*.
Il sera **obligatoire** de fournir une clé ssh qui sera ajoutée à l'utilisateur *root* de la machine.
```bash
export vm_keys=$(echo "$(cat ~/.ssh/id_ed25519.pub)")
```
Il est possible d'ajouter plusieurs clés de cette manière :
```bash
export vm_keys=$(echo "$(cat ./KeyDEPLOY.id_rsa.pub)\n$(cat ./KeyINFRA.id_rsa.pub)\n$(cat ~/.ssh/id_rsa.pub)")
```
Valider la config :
```bash
packer validate *.pkr.hcl
```
Commande de démarrage :
```bash
source ./build.sh
```
# TroubleShooting
## No matching host key type found
Si vous êtes sur Ubuntu, vous devrez ajouter le ssh-rsa en algorithme de chiffrement compatible.
Voici l'erreur sur laquelle vous tomberez :
```
proxmox: fatal: [default]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: Unable to negotiate with 127.0.0.1 port 32985: no matching host key type found. Their offer: ssh-rsa", "unreachable": true}
```
La solution est d'accepter cet algorithme dans votre fichier `~/.ssh/config`.
```
Host 127.0.0.1
HostKeyAlgorithms +ssh-rsa
PubkeyAcceptedAlgorithms +ssh-rsa
```

19
ansible/add-ssh.yml Executable file
View File

@@ -0,0 +1,19 @@
---
- hosts: all
gather_facts: true
vars:
ansible_python_interpreter: /usr/bin/python3
tasks:
- name: Show keys to add
debug:
msg: "{{ item }}"
loop: "{{ lookup('fileglob', '../ssh/*.pub', wantlist=True) }}"
- name: Set authorized key took from file
authorized_key:
user: root
state: present
key: "{{ lookup('pipe','cat ../ssh/*.pub') }}"

51
ansible/install-docker.yml Executable file
View File

@@ -0,0 +1,51 @@
- hosts: all
remote_user: deploy
become: yes
become_user: root
become_method: sudo
tasks:
- name: Update all packages to the latest version
apt:
upgrade: dist
autoremove: true
become: true
- name: Ensure old versions of Docker are not installed.
ansible.builtin.package:
name:
- docker
- docker-engine
- docker.io
- containerd
- runc
state: absent
- name: Ensure dependencies are installed.
ansible.builtin.package:
name:
- apt-transport-https
- ca-certificates
- curl
- gnupg
- lsb-release
state: present
- name: Add Docker apt key.
ansible.builtin.apt_key:
url: https://download.docker.com/linux/{{ ansible_distribution | lower }}/gpg
id: 9DC858229FC7DD38854AE2D88D81803C0EBFCD88
state: present
- name: Add Docker repository.
ansible.builtin.apt_repository:
repo: deb [arch=amd64] https://download.docker.com/linux/{{ ansible_distribution | lower }} {{ ansible_distribution_release }} stable
state: present
update_cache: true
- name: Install docker
ansible.builtin.package:
name:
- docker-ce
- docker-ce-cli
- containerd.io
state: present

149
ansible/install-tools.yml Executable file
View File

@@ -0,0 +1,149 @@
---
- hosts: all
gather_facts: true
vars:
ansible_python_interpreter: /usr/bin/python3
tasks:
- name: "Install packages"
apt:
state: present
name:
- vim
- exa
- grc
- most
- highlight
- source-highlight
- python3-pygments
- gawk
- python3-apt
- tmux
- htop
- fdisk
- name: configure .vimrc
copy:
content: 'set mouse=r'
dest: "/root/.vimrc"
owner: root
group: root
mode: '0644'
- name: config /etc/vim/vimrc syntax on
lineinfile:
path: /etc/vim/vimrc
regexp: '^"syntax on'
line: syntax on
- name: config /etc/vim/vimrc set background=dark
lineinfile:
path: /etc/vim/vimrc
regexp: '^"set background=dark'
line: set background=dark
- name: config .bashrc add cat color alias
lineinfile:
path: /root/.bashrc
line: 'alias cat="highlight -O ansi --force --syntax=bash"'
create: no
- name: config .bashrc set alias ll
lineinfile:
path: /root/.bashrc
regexp: '^# alias ll(.*)'
line: 'alias ll\1'
backrefs: yes
- name: config .bashrc set alias ls
lineinfile:
path: /root/.bashrc
regexp: '^# alias ls(.*)'
line: 'alias ls\1'
backrefs: yes
- name: config .bashrc set alias l
lineinfile:
path: /root/.bashrc
regexp: '^# alias l(.*)'
line: 'alias l\1'
backrefs: yes
- name: config .bashrc set export LSOPTIONS
lineinfile:
path: /root/.bashrc
regexp: '^# export LS_OPTIONS(.*)'
line: 'export LS_OPTIONS\1'
backrefs: yes
- name: config .bashrc set eval OPTIONS
lineinfile:
path: /root/.bashrc
regexp: '^# eval(.*)'
line: '# eval\1'
backrefs: yes
- name: config .bashrc add vim alias
lineinfile:
path: /root/.bashrc
line: "alias vi='vim'"
create: no
- name: config .bashrc add export LESS Color1
lineinfile:
path: /root/.bashrc
line: 'export LESSOPEN="| /usr/share/source-highlight/src-hilite-lesspipe.sh %s"'
create: no
- name: config .bashrc add export LESS Color2
lineinfile:
path: /root/.bashrc
line: "export LESS=' -R'"
create: no
- name: config .bashrc add export pager
lineinfile:
path: /root/.bashrc
line: 'export PAGER="most"'
create: no
- name: config .bashrc alias grep color
lineinfile:
path: /root/.bashrc
line: "alias grep='grep --color=auto'"
create: no
- name: configure yaml color syntax
copy:
dest: "/usr/share/source-highlight/yaml.lang"
owner: root
group: root
mode: '0644'
content: |
include "script_comment.lang"
include "number.lang"
keyword = "true|false|null"
section start '^---'
(symbol,name,symbol) = `(^[[:blank:]-]*)([[:alnum:]_]+)(:)`
symbol = '^[[:blank:]]*-'
string delim "\"" "\"" escape "\\"
string delim "'" "'" escape "\\"
- name: config lang.map yaml
lineinfile:
path: /usr/share/source-highlight/lang.map
line: 'yaml = yaml.lang'
create: no
- name: config lang.map yaml
lineinfile:
path: /usr/share/source-highlight/lang.map
line: 'yml = yaml.lang'
create: no
- name: config .bashrc set Prompt
lineinfile:
path: /root/.bashrc
line: "export PS1='\\[\\033[1;31m\\]\\u\\[\\033[0;37m\\]@\\[\\033[1;32m\\]\\h\\[\\033[00m\\]:\\[\\033[1;34m\\]\\w\\[\\033[00m\\] (\\d - \\t)\\n\\$ '"
create: no

5
ansible/provisioning.yml Executable file
View File

@@ -0,0 +1,5 @@
- import_playbook: install-tools.yml
# - import_playbook: add-ssh.yml
- import_playbook: postinstall-vm.yml
- import_playbook: install-docker.yml

52
build.sh Executable file
View File

@@ -0,0 +1,52 @@
#!/bin/bash
packerfile="debian-amd64-proxmox.pkr.hcl"
# Paramètres du Proxmox
export proxmox_url="https://192.168.1.57:8006/api2/json"
export proxmox_node="BETELGEUSE"
export proxmox_username="packer@pve"
export proxmox_password="Koc89qo!R2UfXR*t" # Il est préférable d'utiliser un utilisateur dédié à Proxmox
export proxmox_vm_storage="Haumea"
export proxmox_iso_url="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-13.2.0-amd64-netinst.iso"
export proxmox_iso_checksum="sha256:677c4d57aa034dc192b5191870141057574c1b05df2b9569c0ee08aa4e32125d"
export proxmox_iso_storage="local"
export proxmox_network="vmbr0"
# Ressources attribuées à la VM
export vm_id="9000"
export vm_name="debian-13-tf"
export template_description="VM debian"
export vm_default_user="root"
export vm_cpu="4"
export vm_disk="16G"
export vm_memory="2048"
# Paramètres de la VM Template
export prefix_disk="vd"
export ssh_username="root"
export ssh_password="8s6pcD7hdIwbaALrBqtPp7WVAmVdHtls1ORij1BcOkuIdxpCXrKA5O2tejKmHkaZ"
export userdeploy_password="8s6pcD7hdIwbaALrBqtPp7WVAmVdHtls1ORij1BcOkuIdxpCXrKA5O2tejKmHkaZ"
export vm_keys=$(echo "$(cat ~/.ssh/id_ed25519.pub)")
#export vm_keys=$(echo "$(cat ./KeyDEPLOY.id_rsa.pub)\n$(cat ./KeyINFRA.id_rsa.pub)\n$(cat ~/.ssh/id_rsa.pub)")
# set variables
python3 << 'EOF'
from jinja2 import Environment, FileSystemLoader
import os
env = Environment(loader=FileSystemLoader('.'))
template = env.get_template('http/preseed.cfg.j2')
output = template.render(os.environ)
with open('http/preseed.cfg', 'w') as f:
f.write(output)
EOF
#PACKER_LOG=1 packer build $packerfile
packer init $packerfile
packer build $packerfile
rm -f http/preseed.cfg

View File

@@ -0,0 +1,153 @@
packer {
required_plugins {
proxmox = {
version = ">= 1.1.2"
source = "github.com/hashicorp/proxmox"
}
}
}
variable "proxmox_iso_checksum" {
type = string
default = "${env("proxmox_iso_checksum")}"
}
variable "proxmox_iso_storage" {
type = string
default = "${env("proxmox_iso_storage")}"
}
variable "proxmox_iso_url" {
type = string
default = "${env("proxmox_iso_url")}"
}
variable "proxmox_network" {
type = string
default = "${env("proxmox_network")}"
}
variable "proxmox_node" {
type = string
default = "${env("proxmox_node")}"
}
variable "proxmox_password" {
type = string
default = "${env("proxmox_password")}"
sensitive = true
}
variable "proxmox_storage" {
type = string
default = "${env("proxmox_storage")}"
}
variable "proxmox_url" {
type = string
default = "${env("proxmox_url")}"
}
variable "proxmox_username" {
type = string
default = "${env("proxmox_username")}"
}
variable "proxmox_vm_storage" {
type = string
default = "${env("proxmox_vm_storage")}"
}
variable "ssh_password" {
type = string
default = "${env("ssh_password")}"
sensitive = true
}
variable "ssh_username" {
type = string
default = "root"
}
variable "template_description" {
type = string
default = "${env("template_description")}"
}
variable "vm_default_user" {
type = string
default = "${env("vm_default_user")}"
}
variable "vm_disk" {
type = string
default = "${env("vm_disk")}"
}
variable "vm_id" {
type = number
default = 9000
}
variable "vm_memory" {
type = number
default = 2048
}
variable "vm_cpu" {
type = number
default = 4
}
variable "vm_name" {
type = string
default = "${env("vm_name")}"
}
source "proxmox" "build-template" {
boot_command = ["<esc><wait>", "auto <wait>", "console-keymaps-at/keymap=fr <wait>", "console-setup/ask_detect=false <wait>", "debconf/frontend=noninteractive <wait>", "debian-installer=fr_FR <wait>", "fb=false <wait>", "install <wait>", "packer_host={{ .HTTPIP }} <wait>", "packer_port={{ .HTTPPort }} <wait>", "kbd-chooser/method=fr <wait>", "keyboard-configuration/xkb-keymap=fr <wait>", "locale=fr_FR <wait>", "netcfg/get_hostname=${var.vm_name} <wait>", "preseed/url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/preseed.cfg <wait>", "<enter><wait>"]
boot_wait = "10s"
disks {
disk_size = "${var.vm_disk}"
format = "raw"
storage_pool = "${var.proxmox_vm_storage}"
storage_pool_type = "directory"
type = "virtio"
}
http_directory = "http"
insecure_skip_tls_verify = true
iso_checksum = "${var.proxmox_iso_checksum}"
iso_storage_pool = "${var.proxmox_iso_storage}"
iso_url = "${var.proxmox_iso_url}"
network_adapters {
bridge = "${var.proxmox_network}"
model = "virtio"
}
node = "${var.proxmox_node}"
os = "l26"
password = "${var.proxmox_password}"
proxmox_url = "${var.proxmox_url}"
qemu_agent = "true"
ssh_password = "${var.ssh_password}"
ssh_timeout = "30m"
ssh_username = "${var.ssh_username}"
template_description = "${var.template_description}"
unmount_iso = true
username = "${var.proxmox_username}"
vm_name = "${var.vm_name}"
cores = var.vm_cpu
memory = var.vm_memory
vm_id = var.vm_id
}
build {
description = "Debian 13 (Bookworm)"
sources = ["source.proxmox.build-template"]
provisioner "ansible" {
ansible_env_vars = ["ANSIBLE_FORCE_COLOR=1", "ANSIBLE_HOST_KEY_CHECKING=False"]
playbook_file = "ansible/provisioning.yml"
}
}

89
http/preseed.cfg.j2 Executable file
View File

@@ -0,0 +1,89 @@
debconf debconf/language string fr
d-i debconf/language string fr
d-i debian-installer/language string fr
d-i debian-installer/locale string fr_FR.UTF-8
d-i debian-installer/splash boolean false
d-i debian-installer/language string fr
d-i debian-installer/country string FR
d-i console-setup/ask_detect boolean false
d-i console-setup/layoutcode string fr
d-i keyboard-configuration/xkb-keymap select fr
d-i keyboard-configuration/layoutcode string fr
d-i preseed/early_command string anna-install parted-udeb cryptsetup-udeb crypto-dm-modules lvm2-udeb mdadm-udeb md-modules
d-i mirror/country string manual
d-i mirror/http/hostname string deb.debian.org
d-i mirror/http/directory string /debian
d-i mirror/http/proxy string
d-i netcfg/get_hostname string {{ vm_name }}
d-i netcfg/choose_interface select auto
d-i netcfg/get_ipaddress string 192.168.1.90
d-i netcfg/get_netmask string 255.255.255.0
d-i netcfg/get_gateway string 192.168.1.254
d-i netcfg/get_nameservers string 192.168.1.25 9.9.9.9
d-i netcfg/confirm_static boolean true
d-i netcfg/get_hostname string debian-13-tf
d-i netcfg/get_domain string local
d-i netcfg/wireless_wep string
d-i apt-setup/non-free boolean true
d-i apt-setup/contrib boolean true
d-i apt-setup/use_mirror boolean true
d-i partman-auto/disk string /dev/{{ prefix_disk }}a
d-i partman-auto/method string lvm
d-i partman-lvm/device_remove_lvm boolean true
d-i partman-lvm/device_remove_lvm_span boolean true
d-i partman-auto/purge_lvm_from_device boolean true
d-i partman-auto-lvm/new_vg_name string vg00
d-i partman-auto/choose_recipe select boot-root
d-i partman-lvm/confirm boolean true
d-i partman-lvm/confirm_nooverwrite boolean true
d-i partman/confirm_write_new_label boolean true
d-i partman/choose_partition select Finish partitioning and write changes to disk
d-i partman/confirm boolean true
d-i partman/confirm_nooverwrite boolean true
d-i partman/mount_style select uuid
d-i clock-setup/utc boolean true
d-i clock-setup/ntp boolean true
d-i clock-setup/ntp-server string ntp.ubuntu.com
d-i time/zone string Europe/Paris
d-i passwd/root-login boolean true
d-i passwd/root-password password {{ ssh_password }}
d-i passwd/root-password-again password {{ ssh_password }}
d-i passwd/make-user boolean true
d-i passwd/user-fullname string ansible deploy
d-i passwd/username string deploy
d-i passwd/user-password password {{ userdeploy_password }}
d-i passwd/user-password-again password {{ userdeploy_password }}
d-i grub-installer/only_debian boolean true
d-i grub-installer/with_other_os boolean false
d-i grub-installer/choose_bootdev string /dev/{{ prefix_disk }}a
d-i partman/mount_style select uuid
d-i clock-setup/utc boolean true
d-i clock-setup/ntp boolean true
d-i clock-setup/ntp-server string ntp.ubuntu.com
d-i time/zone string Europe/Paris
d-i pkgsel/upgrade select safe-upgrade
d-i pkgsel/language-packs multiselect
d-i pkgsel/update-policy select none
d-i pkgsel/updatedb boolean true
tasksel tasksel/first multiselect standard, openssh-server
d-i grub-installer/only_debian boolean true
d-i finish-install/keep-consoles boolean true
d-i finish-install/reboot_in_progress note
d-i cdrom-detect/eject boolean true
d-i debian-installer/exit/halt boolean false
d-i debian-installer/exit/poweroff boolean false
d-i ebian-installer/add-kernel-opts string net.ifnames=0 biosdevname=0
d-i pkgsel/include string vim openssh-server sudo htop iotop rsync mc curl python3 python3-pip python3-apt dnsutils net-tools net-tools gnupg2 wget hostname ansible qemu-guest-agent parted
d-i preseed/late_command string \
in-target sed -i '/^#PermitRootLogin/c\PermitRootLogin yes' /etc/ssh/sshd_config; \
in-target mkdir -p /root/.ssh; \
in-target /bin/sh -c "echo '{{ vm_keys }}' > /root/.ssh/authorized_keys"; \
in-target chmod -R go-rwx /root/.ssh/authorized_keys; \
in-target sed -i 's/# alias ll/alias ll/g' /root/.bashrc; \
in-target sed -i 's/# alias ls/alias ls/g' /root/.bashrc; \
in-target sed -i 's/# alias l/alias l/g' /root/.bashrc; \
in-target sed -i 's/# export LS_OPTIONS/export LS_OPTIONS/g' /root/.bashrc; \
in-target sed -i 's/# eval/eval/g' /root/.bashrc;

4
vars.json Normal file
View File

@@ -0,0 +1,4 @@
{
"proxy_host": "",
"proxy_port": ""
}