Webapp now creates Deploy/Control/Media.tag after every image import. Cron updated to create (not just touch) Media.tag for any image directory that has Deploy/Control/. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
655 lines
21 KiB
YAML
655 lines
21 KiB
YAML
---
|
|
- name: PXE Server Setup (Ubuntu with dnsmasq)
|
|
hosts: localhost
|
|
connection: local
|
|
become: yes
|
|
gather_facts: yes
|
|
|
|
pre_tasks:
|
|
- name: "Verify required packages are installed (pre-installed from offline .debs)"
|
|
command: dpkg -s {{ item }}
|
|
loop:
|
|
- dnsmasq
|
|
- apache2
|
|
- samba
|
|
- unzip
|
|
- ufw
|
|
- cron
|
|
- ansible
|
|
- wimtools
|
|
register: pkg_check
|
|
failed_when: false
|
|
changed_when: false
|
|
|
|
- name: "Warn about missing packages"
|
|
debug:
|
|
msg: "WARNING: {{ item.item }} is not installed! Install offline .debs first."
|
|
loop: "{{ pkg_check.results }}"
|
|
when: item.rc != 0
|
|
|
|
vars:
|
|
tftp_dir: "/srv/tftp"
|
|
web_root: "/var/www/html"
|
|
samba_share: "/srv/samba/winpeapps"
|
|
usb_mount: "/mnt/usb/playbook" # playbook location on USB
|
|
usb_root: "/mnt/usb" # CIDATA partition root
|
|
image_types:
|
|
- gea-standard
|
|
- gea-engineer
|
|
- gea-shopfloor
|
|
- gea-shopfloor-mce
|
|
- ge-standard
|
|
- ge-engineer
|
|
- ge-shopfloor-lockdown
|
|
- ge-shopfloor-mce
|
|
deploy_subdirs:
|
|
- Applications
|
|
- Control
|
|
- "Operating Systems"
|
|
- "Out-of-box Drivers"
|
|
- Packages
|
|
- Tools
|
|
|
|
tasks:
|
|
- name: "Gather minimal network facts"
|
|
ansible.builtin.setup:
|
|
filter:
|
|
- ansible_interfaces
|
|
- ansible_default_ipv4
|
|
|
|
- name: "Bring up all ethernet-like interfaces"
|
|
command: ip link set dev {{ item }} up
|
|
loop: "{{ ansible_interfaces | select('match','^e(th|n)') | list }}"
|
|
ignore_errors: yes
|
|
|
|
- name: "Find interface with 10.9.100.1 already configured"
|
|
set_fact:
|
|
preconfigured_iface: >-
|
|
{{ ansible_interfaces
|
|
| select('match','^e(th|n)')
|
|
| map('regex_replace','^(.*)$','ansible_\1')
|
|
| map('extract', hostvars[inventory_hostname])
|
|
| selectattr('ipv4','defined')
|
|
| selectattr('ipv4.address','equalto','10.9.100.1')
|
|
| map(attribute='device')
|
|
| list
|
|
| first
|
|
| default('') }}
|
|
ignore_errors: yes
|
|
|
|
- name: "Determine PXE interface"
|
|
set_fact:
|
|
pxe_iface: >-
|
|
{{ preconfigured_iface | default('',true)
|
|
or (ansible_interfaces
|
|
| select('match','^e(th|n)')
|
|
| reject('equalto','lo')
|
|
| reject('equalto', ansible_default_ipv4.interface | default(''))
|
|
| list
|
|
)
|
|
| first
|
|
| default(ansible_default_ipv4.interface | default(
|
|
ansible_interfaces | select('match','^e(th|n)') | first | default('eth0')
|
|
)) }}
|
|
|
|
- name: "Debug: final pxe_iface choice"
|
|
debug:
|
|
msg: "Using {{ pxe_iface }} for DHCP/TFTP"
|
|
|
|
- name: "Expand root partition and filesystem to use full disk"
|
|
args:
|
|
executable: /bin/bash
|
|
shell: |
|
|
# Find the root LV device
|
|
ROOT_DEV=$(findmnt -n -o SOURCE /)
|
|
ROOT_DISK=$(lsblk -n -o PKNAME $(readlink -f "$ROOT_DEV") | tail -1)
|
|
if [ -z "$ROOT_DISK" ]; then
|
|
echo "Could not determine root disk, skipping"
|
|
exit 0
|
|
fi
|
|
# Find the partition number for the LVM PV
|
|
PV_PART=$(pvs --noheadings -o pv_name | tr -d ' ' | head -1)
|
|
if [ -z "$PV_PART" ]; then
|
|
echo "No LVM PV found, skipping"
|
|
exit 0
|
|
fi
|
|
PART_NUM=$(echo "$PV_PART" | grep -o '[0-9]*$')
|
|
echo "Expanding /dev/${ROOT_DISK} partition ${PART_NUM} (${PV_PART})..."
|
|
growpart "/dev/${ROOT_DISK}" "${PART_NUM}" 2>&1 || true
|
|
pvresize "$PV_PART" 2>&1
|
|
lvextend -l +100%FREE "$ROOT_DEV" 2>&1 || true
|
|
resize2fs "$ROOT_DEV" 2>&1
|
|
echo "Disk: $(df -h / | tail -1)"
|
|
register: disk_expand
|
|
changed_when: "'CHANGED' in disk_expand.stdout or 'resized' in disk_expand.stdout"
|
|
|
|
- name: "Configure dnsmasq for DHCP and TFTP"
|
|
copy:
|
|
dest: /etc/dnsmasq.conf
|
|
backup: yes
|
|
content: |
|
|
port=0
|
|
interface={{ pxe_iface }}
|
|
bind-interfaces
|
|
dhcp-range=10.9.100.10,10.9.100.100,12h
|
|
dhcp-option=3,10.9.100.1
|
|
dhcp-option=6,8.8.8.8
|
|
enable-tftp
|
|
tftp-root={{ tftp_dir }}
|
|
dhcp-boot=ipxe.efi
|
|
|
|
- name: "Create TFTP directory"
|
|
file:
|
|
path: "{{ tftp_dir }}"
|
|
state: directory
|
|
mode: '0755'
|
|
owner: nobody
|
|
group: nogroup
|
|
|
|
- name: "Create Win11 directory structure"
|
|
file:
|
|
path: "{{ web_root }}/win11/{{ item }}"
|
|
state: directory
|
|
mode: '0755'
|
|
loop:
|
|
- "EFI/Boot"
|
|
- "EFI/Microsoft/Boot"
|
|
- "Boot"
|
|
- "sources"
|
|
|
|
- name: "Create Altiris iPXE directory"
|
|
file:
|
|
path: "{{ web_root }}/Altiris/iPXE"
|
|
state: directory
|
|
mode: '0755'
|
|
|
|
- name: "Create boot tool directories"
|
|
file:
|
|
path: "{{ web_root }}/{{ item }}"
|
|
state: directory
|
|
mode: '0755'
|
|
loop:
|
|
- clonezilla
|
|
- blancco
|
|
- memtest
|
|
|
|
- name: "Create GetPxeScript.aspx (iPXE boot menu)"
|
|
copy:
|
|
dest: "{{ web_root }}/Altiris/iPXE/GetPxeScript.aspx"
|
|
backup: yes
|
|
content: |
|
|
#!ipxe
|
|
|
|
set server 10.9.100.1
|
|
|
|
:menu
|
|
menu GE Aerospace PXE Boot Menu
|
|
item --gap -- ---- Windows Deployment ----
|
|
item winpe Windows PE (Image Deployment)
|
|
item --gap -- ---- Utilities (Secure Boot must be DISABLED) ----
|
|
item blancco Blancco Drive Eraser
|
|
item clonezilla Clonezilla Live (Disk Imaging)
|
|
item memtest Memtest86+ (Memory Diagnostics)
|
|
item --gap -- ----
|
|
item reboot Reboot
|
|
item exit Exit to BIOS
|
|
choose --default winpe --timeout 30000 target && goto ${target}
|
|
|
|
:winpe
|
|
echo
|
|
echo Windows deployment requires Secure Boot to be ENABLED.
|
|
echo If you disabled it for Blancco/Clonezilla, re-enable it now.
|
|
echo
|
|
prompt --timeout 5000 Press any key to continue (auto-boot in 5s)... && goto winpe_boot || goto winpe_boot
|
|
|
|
:winpe_boot
|
|
kernel http://${server}/win11/wimboot gui
|
|
initrd http://${server}/win11/EFI/Microsoft/Boot/boot.stl EFI/Microsoft/Boot/Boot.stl
|
|
initrd http://${server}/win11/EFI/Microsoft/Boot/BCD EFI/Microsoft/Boot/BCD
|
|
initrd http://${server}/win11/EFI/Boot/bootx64.efi EFI/Boot/bootx64.efi
|
|
initrd http://${server}/win11/Boot/boot.sdi Boot/boot.sdi
|
|
initrd http://${server}/win11/sources/boot.wim sources/boot.wim
|
|
boot
|
|
|
|
:clonezilla
|
|
set base http://${server}/clonezilla
|
|
kernel ${base}/vmlinuz boot=live username=user union=overlay config components noswap edd=on nomodeset nodmraid locales= keyboard-layouts= ocs_live_run="ocs-live-general" ocs_live_extra_param="" ocs_live_batch=no net.ifnames=0 nosplash noprompt fetch=${base}/filesystem.squashfs || goto secureboot_warn
|
|
initrd ${base}/initrd.img
|
|
boot
|
|
|
|
:blancco
|
|
chain http://${server}/blancco/grubx64.efi || goto secureboot_warn
|
|
|
|
:memtest
|
|
kernel http://${server}/memtest/memtest.efi || goto secureboot_warn
|
|
boot
|
|
|
|
:secureboot_warn
|
|
echo
|
|
echo ======================================================
|
|
echo This option requires Secure Boot to be DISABLED.
|
|
echo
|
|
echo 1. Reboot this machine
|
|
echo 2. Press F2 / Del to enter BIOS Setup
|
|
echo 3. Disable Secure Boot
|
|
echo 4. Save and exit BIOS
|
|
echo 5. PXE boot again and select this option
|
|
echo
|
|
echo Re-enable Secure Boot after completing the task.
|
|
echo ======================================================
|
|
echo
|
|
prompt Press any key to return to menu...
|
|
goto menu
|
|
|
|
:reboot
|
|
reboot
|
|
|
|
:exit
|
|
exit
|
|
|
|
- name: "Ensure Apache listens on port 4433"
|
|
lineinfile:
|
|
path: /etc/apache2/ports.conf
|
|
line: "Listen 4433"
|
|
backup: yes
|
|
state: present
|
|
|
|
- name: "Create VirtualHost for Altiris iPXE on 4433"
|
|
copy:
|
|
dest: /etc/apache2/sites-available/altiris-ipxe.conf
|
|
backup: yes
|
|
content: |
|
|
<VirtualHost *:4433>
|
|
DocumentRoot {{ web_root }}
|
|
<Directory "{{ web_root }}/Altiris/iPXE">
|
|
Options Indexes FollowSymLinks
|
|
AllowOverride None
|
|
Require all granted
|
|
AddType text/plain .aspx
|
|
</Directory>
|
|
</VirtualHost>
|
|
|
|
- name: "Enable Altiris iPXE site"
|
|
command: a2ensite altiris-ipxe.conf
|
|
args:
|
|
creates: /etc/apache2/sites-enabled/altiris-ipxe.conf
|
|
|
|
- name: "Reload Apache to apply changes"
|
|
systemd:
|
|
name: apache2
|
|
state: reloaded
|
|
|
|
- name: "Create Samba share root"
|
|
file:
|
|
path: "{{ samba_share }}"
|
|
state: directory
|
|
mode: '0777'
|
|
|
|
- name: "Create Clonezilla backup share directory"
|
|
file:
|
|
path: /srv/samba/clonezilla
|
|
state: directory
|
|
mode: '0777'
|
|
|
|
- name: "Create Blancco reports share directory"
|
|
file:
|
|
path: /srv/samba/blancco-reports
|
|
state: directory
|
|
mode: '0777'
|
|
|
|
- name: "Create image upload staging directory"
|
|
file:
|
|
path: /home/pxe/image-upload
|
|
state: directory
|
|
mode: '0777'
|
|
owner: pxe
|
|
group: pxe
|
|
|
|
- name: "Enable Samba symlink following (shared image dirs)"
|
|
blockinfile:
|
|
path: /etc/samba/smb.conf
|
|
backup: yes
|
|
marker: "# {mark} MANAGED - GLOBAL SYMLINKS"
|
|
insertafter: '\[global\]'
|
|
block: |
|
|
follow symlinks = yes
|
|
wide links = yes
|
|
unix extensions = no
|
|
|
|
- name: "Configure Samba shares"
|
|
blockinfile:
|
|
path: /etc/samba/smb.conf
|
|
backup: yes
|
|
block: |
|
|
[winpeapps]
|
|
path = {{ samba_share }}
|
|
browseable = yes
|
|
read only = no
|
|
guest ok = no
|
|
valid users = pxe-upload
|
|
force user = root
|
|
|
|
[clonezilla]
|
|
path = /srv/samba/clonezilla
|
|
browseable = yes
|
|
read only = no
|
|
guest ok = no
|
|
valid users = pxe-upload
|
|
force user = root
|
|
comment = Clonezilla backup images
|
|
|
|
[blancco-reports]
|
|
path = /srv/samba/blancco-reports
|
|
browseable = yes
|
|
read only = no
|
|
guest ok = no
|
|
valid users = pxe-upload blancco
|
|
force user = root
|
|
comment = Blancco Drive Eraser reports
|
|
|
|
[image-upload]
|
|
path = /home/pxe/image-upload
|
|
browseable = yes
|
|
read only = no
|
|
guest ok = no
|
|
valid users = pxe-upload
|
|
force user = pxe
|
|
force group = pxe
|
|
comment = PXE image upload staging area
|
|
|
|
- name: "Create Samba users (pxe-upload and blancco)"
|
|
shell: |
|
|
id pxe-upload >/dev/null 2>&1 || useradd -M -s /usr/sbin/nologin pxe-upload
|
|
echo -e 'pxe\npxe' | smbpasswd -a pxe-upload -s
|
|
id blancco >/dev/null 2>&1 || useradd -M -s /usr/sbin/nologin blancco
|
|
echo -e 'blancco\nblancco' | smbpasswd -a blancco -s
|
|
args:
|
|
executable: /bin/bash
|
|
changed_when: false
|
|
|
|
- name: "Create image-type top-level directories"
|
|
file:
|
|
path: "{{ samba_share }}/{{ item }}"
|
|
state: directory
|
|
mode: '0777'
|
|
loop: "{{ image_types }}"
|
|
|
|
- name: "Create Deploy subdirectories for each image type"
|
|
file:
|
|
path: "{{ samba_share }}/{{ item.0 }}/Deploy/{{ item.1 }}"
|
|
state: directory
|
|
mode: '0777'
|
|
with_nested:
|
|
- "{{ image_types }}"
|
|
- "{{ deploy_subdirs }}"
|
|
|
|
- name: "Create Media.tag for FlatSetupLoader.exe drive detection"
|
|
copy:
|
|
content: ""
|
|
dest: "{{ samba_share }}/{{ item }}/Deploy/Control/Media.tag"
|
|
mode: '0644'
|
|
force: no
|
|
loop: "{{ image_types }}"
|
|
|
|
- name: "Daily cron to create/refresh Media.tag for all images"
|
|
copy:
|
|
content: |
|
|
# Create Media.tag in any image with Deploy/Control/ and refresh existing ones
|
|
@reboot root for d in {{ samba_share }}/*/Deploy/Control; do [ -d "$d" ] && touch "$d/Media.tag"; done
|
|
0 0 * * * root for d in {{ samba_share }}/*/Deploy/Control; do [ -d "$d" ] && touch "$d/Media.tag"; done
|
|
dest: /etc/cron.d/media-tag-refresh
|
|
mode: '0644'
|
|
|
|
- name: "Copy WinPE & boot files from USB (skipped if not present)"
|
|
copy:
|
|
src: "{{ usb_root }}/{{ item.src }}"
|
|
dest: "{{ web_root }}/win11/{{ item.dest }}"
|
|
mode: '0644'
|
|
loop:
|
|
- { src: "wimboot", dest: "wimboot" }
|
|
- { src: "boot.stl", dest: "EFI/Microsoft/Boot/boot.stl" }
|
|
- { src: "BCD", dest: "EFI/Microsoft/Boot/BCD" }
|
|
- { src: "bootx64.efi", dest: "EFI/Boot/bootx64.efi" }
|
|
- { src: "boot.sdi", dest: "Boot/boot.sdi" }
|
|
- { src: "boot.wim", dest: "sources/boot.wim" }
|
|
ignore_errors: yes
|
|
|
|
- name: "Inject startnet.cmd into boot.wim (virtual BOOT/MEDIA volumes)"
|
|
shell: |
|
|
WIM="{{ web_root }}/win11/sources/boot.wim"
|
|
STARTNET="{{ usb_mount }}/startnet.cmd"
|
|
if [ -f "$WIM" ] && [ -f "$STARTNET" ]; then
|
|
echo "add $STARTNET /Windows/System32/startnet.cmd" | wimupdate "$WIM" 1
|
|
echo "Updated startnet.cmd in boot.wim"
|
|
else
|
|
echo "Skipped: boot.wim or startnet.cmd not found"
|
|
fi
|
|
args:
|
|
executable: /bin/bash
|
|
ignore_errors: yes
|
|
|
|
- name: "Copy iPXE binaries from USB (skipped if not present)"
|
|
copy:
|
|
src: "{{ usb_root }}/{{ item }}"
|
|
dest: "{{ tftp_dir }}/{{ item }}"
|
|
mode: '0755'
|
|
loop:
|
|
- ipxe.efi
|
|
ignore_errors: yes
|
|
|
|
- name: "Copy boot tool files from USB (Clonezilla, Blancco, Memtest)"
|
|
shell: >
|
|
cp -r "{{ usb_root }}/boot-tools/{{ item }}/"* "{{ web_root }}/{{ item }}/" 2>/dev/null || true
|
|
loop:
|
|
- clonezilla
|
|
- blancco
|
|
- memtest
|
|
|
|
- name: "Create TFTP blancco directory for GRUB boot"
|
|
file:
|
|
path: "{{ tftp_dir }}/blancco"
|
|
state: directory
|
|
mode: '0755'
|
|
|
|
- name: "Symlink Blancco boot files to TFTP (GRUB loads via TFTP)"
|
|
file:
|
|
src: "{{ web_root }}/blancco/{{ item }}"
|
|
dest: "{{ tftp_dir }}/blancco/{{ item }}"
|
|
state: link
|
|
force: yes
|
|
loop:
|
|
- vmlinuz-bde-linux
|
|
- intel-ucode.img
|
|
- amd-ucode.img
|
|
- config.img
|
|
- initramfs-bde-linux.img
|
|
|
|
- name: "Check for WinPE deployment content on USB"
|
|
stat:
|
|
path: "{{ usb_root }}/images"
|
|
register: usb_images_dir
|
|
|
|
- name: "Import WinPE deployment content from USB (if present)"
|
|
shell: >
|
|
cp -rn "{{ usb_root }}/images/{{ item }}/"* "{{ samba_share }}/{{ item }}/" 2>/dev/null || true
|
|
loop: "{{ image_types }}"
|
|
when: usb_images_dir.stat.exists
|
|
|
|
- name: "Restart and enable services"
|
|
systemd:
|
|
name: "{{ item }}"
|
|
state: restarted
|
|
enabled: yes
|
|
loop:
|
|
- dnsmasq
|
|
- apache2
|
|
- smbd
|
|
|
|
- name: "Allow necessary firewall ports (UFW)"
|
|
ufw:
|
|
rule: allow
|
|
port: "{{ item }}"
|
|
proto: "{{ 'udp' if item in ['67','69'] else 'tcp' }}"
|
|
loop:
|
|
- "22"
|
|
- "67"
|
|
- "69"
|
|
- "80"
|
|
- "4433"
|
|
- "445"
|
|
- "9009"
|
|
|
|
- name: "Enable UFW firewall"
|
|
ufw:
|
|
state: enabled
|
|
policy: deny
|
|
|
|
- name: "Schedule dnsmasq restart 15s after reboot"
|
|
cron:
|
|
name: "Restart dnsmasq after reboot"
|
|
user: root
|
|
special_time: "reboot"
|
|
job: "/bin/sleep 15 && /usr/bin/systemctl restart dnsmasq.service"
|
|
|
|
# --- Web Management App (Flask) ---
|
|
- name: "Create webapp directory"
|
|
file:
|
|
path: /opt/pxe-webapp
|
|
state: directory
|
|
mode: '0755'
|
|
|
|
- name: "Copy webapp from USB"
|
|
shell: >
|
|
cp -r "{{ usb_root }}/webapp/"* /opt/pxe-webapp/ 2>/dev/null || true
|
|
args:
|
|
creates: /opt/pxe-webapp/app.py
|
|
|
|
- name: "Install webapp Python dependencies (offline wheels)"
|
|
args:
|
|
executable: /bin/bash
|
|
shell: |
|
|
# Find the pip-wheels directory on the CIDATA mount
|
|
export WHEEL_DIR=""
|
|
for d in "{{ usb_root }}/pip-wheels" "{{ usb_mount }}/pip-wheels"; do
|
|
if [ -d "$d" ] && compgen -G "$d/*.whl" > /dev/null; then
|
|
export WHEEL_DIR="$(cd "$d" && pwd)"
|
|
break
|
|
fi
|
|
done
|
|
if [ -n "$WHEEL_DIR" ]; then
|
|
# Install wheels directly using Python zipfile (bypasses pip entirely)
|
|
# This avoids the pip3/distutils incompatibility between Ubuntu 22.04 debs and Python 3.12
|
|
python3 << 'PYEOF'
|
|
import zipfile, sysconfig, glob, os
|
|
site = sysconfig.get_path('platlib')
|
|
wheel_dir = os.environ['WHEEL_DIR']
|
|
for whl in sorted(glob.glob(os.path.join(wheel_dir, '*.whl'))):
|
|
name = os.path.basename(whl)
|
|
print(f' Installing {name}')
|
|
with zipfile.ZipFile(whl) as z:
|
|
z.extractall(site)
|
|
print('All wheels installed to ' + site)
|
|
PYEOF
|
|
else
|
|
# Fallback: try system pip (works if system has internet and compatible pip)
|
|
python3 -m pip install --break-system-packages flask lxml 2>/dev/null ||
|
|
pip3 install --break-system-packages flask lxml
|
|
fi
|
|
|
|
- name: "Create systemd service for PXE webapp"
|
|
copy:
|
|
dest: /etc/systemd/system/pxe-webapp.service
|
|
content: |
|
|
[Unit]
|
|
Description=PXE Server Web Management
|
|
After=network.target apache2.service
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=root
|
|
WorkingDirectory=/opt/pxe-webapp
|
|
Environment=SAMBA_SHARE={{ samba_share }}
|
|
Environment=CLONEZILLA_SHARE=/srv/samba/clonezilla
|
|
Environment=WEB_ROOT={{ web_root }}
|
|
Environment=BLANCCO_REPORTS=/srv/samba/blancco-reports
|
|
Environment=AUDIT_LOG=/var/log/pxe-webapp-audit.log
|
|
ExecStart=/usr/bin/python3 app.py
|
|
Restart=always
|
|
RestartSec=5
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
|
|
- name: "Enable and start PXE webapp service"
|
|
systemd:
|
|
name: pxe-webapp
|
|
state: started
|
|
enabled: yes
|
|
daemon_reload: yes
|
|
|
|
- name: "Configure unified Apache site (static files + webapp proxy)"
|
|
copy:
|
|
dest: /etc/apache2/sites-available/pxe-server.conf
|
|
content: |
|
|
Listen 9009
|
|
<VirtualHost *:80>
|
|
DocumentRoot {{ web_root }}
|
|
<Directory "{{ web_root }}">
|
|
Options Indexes FollowSymLinks
|
|
AllowOverride None
|
|
Require all granted
|
|
</Directory>
|
|
ProxyPreserveHost On
|
|
ProxyPass /manage http://127.0.0.1:9010/
|
|
ProxyPassReverse /manage http://127.0.0.1:9010/
|
|
</VirtualHost>
|
|
<VirtualHost *:9009>
|
|
Alias /static /opt/pxe-webapp/static
|
|
<Directory "/opt/pxe-webapp/static">
|
|
Require all granted
|
|
Options -Indexes
|
|
</Directory>
|
|
ProxyPreserveHost On
|
|
ProxyPass /static !
|
|
ProxyPass / http://127.0.0.1:9010/
|
|
ProxyPassReverse / http://127.0.0.1:9010/
|
|
</VirtualHost>
|
|
|
|
- name: "Enable Apache proxy modules"
|
|
command: a2enmod proxy proxy_http
|
|
args:
|
|
creates: /etc/apache2/mods-enabled/proxy.load
|
|
|
|
- name: "Disable default Apache site"
|
|
command: a2dissite 000-default.conf
|
|
args:
|
|
removes: /etc/apache2/sites-enabled/000-default.conf
|
|
|
|
- name: "Enable unified PXE server site"
|
|
command: a2ensite pxe-server.conf
|
|
args:
|
|
creates: /etc/apache2/sites-enabled/pxe-server.conf
|
|
|
|
- name: "Reload Apache after site changes"
|
|
systemd:
|
|
name: apache2
|
|
state: reloaded
|
|
|
|
- name: "Configure static IP for PXE interface"
|
|
copy:
|
|
dest: /etc/netplan/50-cloud-init.yaml
|
|
backup: yes
|
|
content: |
|
|
network:
|
|
version: 2
|
|
renderer: networkd
|
|
ethernets:
|
|
{{ pxe_iface }}:
|
|
dhcp4: no
|
|
addresses: [10.9.100.1/24]
|
|
notify: "Apply netplan"
|
|
|
|
handlers:
|
|
- name: "Apply netplan"
|
|
command: netplan apply
|