Proxmox lancelot : compte API dédié, VLAN 200 LAB en DHCP
Clonage par l'API (community.proxmox) avec bwpoc@pve limité au pool bwpoc ; modèle créé une fois en root avec l'agent QEMU, qui sert à lire les IP DHCP écrites dans inventory/host_vars/<vm>/dhcp.yml. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
099584c95c
commit
5846487f07
15 files changed
+502
-348
No files matched your search
@@ -6,6 +6,13 @@
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
||||
- name: Créer le pool {{ pve_pool }} (délégation au compte dédié)
|
||||
ansible.builtin.shell: |
|
||||
pveum pool list --output-format json | grep -q '"poolid":"{{ pve_pool }}"' && exit 0
|
||||
pveum pool add {{ pve_pool }} --comment "PoC BunkerWeb" && echo created
|
||||
register: pool_add
|
||||
changed_when: "'created' in pool_add.stdout"
|
||||
|
||||
- name: Créer le modèle
|
||||
when: tpl_status.rc != 0
|
||||
block:
|
||||
@@ -14,6 +21,20 @@
|
||||
url: "{{ pve_image_url }}"
|
||||
dest: "{{ pve_image_path }}"
|
||||
mode: "0644"
|
||||
force: true # image vierge à chaque création du modèle
|
||||
|
||||
- name: Installer libguestfs-tools (personnalisation de l'image)
|
||||
ansible.builtin.apt:
|
||||
name: libguestfs-tools
|
||||
state: present
|
||||
update_cache: true
|
||||
|
||||
- name: Ajouter l'agent QEMU à l'image (indispensable pour lire l'IP DHCP)
|
||||
ansible.builtin.command: >-
|
||||
virt-customize -a {{ pve_image_path }}
|
||||
--install qemu-guest-agent
|
||||
--truncate /etc/machine-id
|
||||
changed_when: true
|
||||
|
||||
- name: Créer la VM modèle
|
||||
ansible.builtin.command: >-
|
||||
@@ -43,3 +64,10 @@
|
||||
- name: Convertir en modèle
|
||||
ansible.builtin.command: qm template {{ pve_template_vmid }}
|
||||
changed_when: true
|
||||
|
||||
- name: Placer le modèle dans le pool (le compte dédié peut le cloner)
|
||||
ansible.builtin.shell: |
|
||||
pvesh get /pools/{{ pve_pool }} --output-format json | grep -q '"vmid":{{ pve_template_vmid }}[,}]' && exit 0
|
||||
pveum pool modify {{ pve_pool }} --vms {{ pve_template_vmid }} && echo added
|
||||
register: pool_tpl
|
||||
changed_when: "'added' in pool_tpl.stdout"
|
||||
@@ -1,13 +1,24 @@
|
||||
---
|
||||
# Clone et configure les VM du PoC à partir du modèle (exécuté sur le nœud Proxmox).
|
||||
- name: Déposer la clé SSH publique pour cloud-init
|
||||
ansible.builtin.copy:
|
||||
content: "{{ lookup('ansible.builtin.file', poc_ssh_pubkey_file) }}\n"
|
||||
dest: /root/bwpoc_authorized_keys
|
||||
mode: "0600"
|
||||
# Clone et configure les VM du PoC par l'API Proxmox (compte dédié, voir README).
|
||||
# Exécuté sur le contrôleur Ansible : connection local dans le playbook.
|
||||
- name: Contrôler la présence du jeton API
|
||||
ansible.builtin.assert:
|
||||
that: pve_api_token_secret | length > 0
|
||||
fail_msg: "Exportez PVE_TOKEN_SECRET (secret du jeton {{ pve_api_user }}!{{ pve_api_token_id }})"
|
||||
quiet: true
|
||||
|
||||
- name: Créer le répertoire des host_vars par VM
|
||||
ansible.builtin.file:
|
||||
path: "{{ inventory_dir }}/host_vars/{{ item }}"
|
||||
state: directory
|
||||
mode: "0755"
|
||||
loop: "{{ groups['poc_vms'] | unique }}"
|
||||
|
||||
- name: Créer chaque VM
|
||||
ansible.builtin.include_tasks: vm.yml
|
||||
loop: "{{ groups['poc_vms'] | unique }}"
|
||||
loop_control:
|
||||
loop_var: vm_name
|
||||
|
||||
- name: Recharger l'inventaire avec les IP DHCP
|
||||
ansible.builtin.meta: refresh_inventory
|
||||
@@ -4,53 +4,86 @@
|
||||
vm: "{{ hostvars[vm_name] }}"
|
||||
|
||||
- name: "{{ vm_name }} : la VM existe-t-elle ?"
|
||||
ansible.builtin.command: qm status {{ vm.vm_id }}
|
||||
register: vm_status
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
community.proxmox.proxmox_vm_info:
|
||||
vmid: "{{ vm.vm_id }}"
|
||||
node: "{{ pve_node }}"
|
||||
config: none
|
||||
register: vm_info
|
||||
|
||||
- name: "{{ vm_name }} : création"
|
||||
when: vm_status.rc != 0
|
||||
when: vm_info.proxmox_vms | length == 0
|
||||
block:
|
||||
- name: "{{ vm_name }} : l'IP {{ vm.ansible_host }} doit être libre"
|
||||
ansible.builtin.command: ping -c 2 -W 1 {{ vm.ansible_host }}
|
||||
register: ip_ping
|
||||
changed_when: false
|
||||
failed_when: ip_ping.rc == 0
|
||||
|
||||
- name: "{{ vm_name }} : clonage du modèle"
|
||||
ansible.builtin.command: >-
|
||||
qm clone {{ pve_template_vmid }} {{ vm.vm_id }}
|
||||
--name {{ vm_name }} --full 1 --storage {{ pve_storage }}
|
||||
changed_when: true
|
||||
|
||||
- name: "{{ vm_name }} : ressources et cloud-init"
|
||||
ansible.builtin.command: >-
|
||||
qm set {{ vm.vm_id }}
|
||||
--cores {{ vm.vm_cores }} --memory {{ vm.vm_memory }}
|
||||
--onboot 1 --tags bwpoc
|
||||
--ciuser {{ poc_vm_user }}
|
||||
--sshkeys /root/bwpoc_authorized_keys
|
||||
--ipconfig0 ip={{ vm.ansible_host }}/{{ poc_net_prefix }},gw={{ poc_net_gateway }}
|
||||
--nameserver "{{ poc_net_dns | join(' ') }}"
|
||||
--searchdomain {{ poc_net_searchdomain }}
|
||||
--ciupgrade 0
|
||||
changed_when: true
|
||||
- name: "{{ vm_name }} : clonage du modèle {{ pve_template_vmid }}"
|
||||
community.proxmox.proxmox_kvm:
|
||||
node: "{{ pve_node }}"
|
||||
vmid: "{{ pve_template_vmid }}"
|
||||
clone: "{{ pve_template_name }}"
|
||||
newid: "{{ vm.vm_id }}"
|
||||
name: "{{ vm_name }}"
|
||||
full: true
|
||||
storage: "{{ pve_storage }}"
|
||||
pool: "{{ pve_pool }}"
|
||||
timeout: 600
|
||||
|
||||
- name: "{{ vm_name }} : agrandissement du disque à {{ vm.vm_disk_gb }} Go"
|
||||
ansible.builtin.command: qm resize {{ vm.vm_id }} scsi0 {{ vm.vm_disk_gb }}G
|
||||
changed_when: true
|
||||
community.proxmox.proxmox_disk:
|
||||
vmid: "{{ vm.vm_id }}"
|
||||
disk: scsi0
|
||||
state: resized
|
||||
size: "{{ vm.vm_disk_gb }}G"
|
||||
|
||||
- name: "{{ vm_name }} : ressources et cloud-init"
|
||||
community.proxmox.proxmox_kvm:
|
||||
node: "{{ pve_node }}"
|
||||
vmid: "{{ vm.vm_id }}"
|
||||
update: true
|
||||
cores: "{{ vm.vm_cores }}"
|
||||
memory: "{{ vm.vm_memory }}"
|
||||
onboot: true
|
||||
tags: [bwpoc]
|
||||
ciuser: "{{ poc_vm_user }}"
|
||||
sshkeys: "{{ lookup('ansible.builtin.file', poc_ssh_pubkey_file) }}"
|
||||
ipconfig:
|
||||
ipconfig0: "ip=dhcp" # passerelle et DNS fournis par le DHCP du VLAN LAB
|
||||
ciupgrade: false
|
||||
|
||||
- name: "{{ vm_name }} : démarrage"
|
||||
ansible.builtin.command: qm start {{ vm.vm_id }}
|
||||
register: vm_start
|
||||
changed_when: vm_start.rc == 0
|
||||
failed_when: vm_start.rc != 0 and 'already running' not in vm_start.stderr
|
||||
community.proxmox.proxmox_kvm:
|
||||
node: "{{ pve_node }}"
|
||||
vmid: "{{ vm.vm_id }}"
|
||||
state: started
|
||||
timeout: 120
|
||||
|
||||
- name: "{{ vm_name }} : attente du SSH"
|
||||
- name: "{{ vm_name }} : adresse DHCP remontée par l'agent QEMU"
|
||||
community.proxmox.proxmox_vm_info:
|
||||
node: "{{ pve_node }}"
|
||||
vmid: "{{ vm.vm_id }}"
|
||||
config: current
|
||||
network: true
|
||||
register: vm_net
|
||||
until: >-
|
||||
(vm_net.proxmox_vms[0].network | default([]) | rejectattr('name', 'equalto', 'lo')
|
||||
| map(attribute='ip-addresses') | flatten | selectattr('ip-address-type', 'equalto', 'ipv4') | list | length) > 0
|
||||
retries: 40
|
||||
delay: 10
|
||||
|
||||
- name: "{{ vm_name }} : mémoriser l'IP"
|
||||
ansible.builtin.set_fact:
|
||||
vm_ip: >-
|
||||
{{ vm_net.proxmox_vms[0].network | rejectattr('name', 'equalto', 'lo')
|
||||
| map(attribute='ip-addresses') | flatten | selectattr('ip-address-type', 'equalto', 'ipv4')
|
||||
| map(attribute='ip-address') | first }}
|
||||
|
||||
- name: "{{ vm_name }} : écrire l'IP dans inventory/host_vars (relu par les playbooks suivants)"
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ inventory_dir }}/host_vars/{{ vm_name }}/dhcp.yml"
|
||||
mode: "0644"
|
||||
content: |
|
||||
# Généré par 00-proxmox.yml : IP obtenue par DHCP (VMID {{ vm.vm_id }})
|
||||
ansible_host: {{ vm_ip }}
|
||||
|
||||
- name: "{{ vm_name }} : attente du SSH sur {{ vm_ip }}"
|
||||
ansible.builtin.wait_for:
|
||||
host: "{{ vm.ansible_host }}"
|
||||
host: "{{ vm_ip }}"
|
||||
port: 22
|
||||
timeout: 300
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
Reference in new issue
Block a user