initial commit
Some checks reported errors
continuous-integration/drone/push Build was killed

This commit is contained in:
Robert Kaussow 2022-08-06 22:17:14 +02:00
commit 352601029b
Signed by: xoxys
GPG Key ID: 4E692A2EAECC03C0
11 changed files with 639 additions and 0 deletions

4
.dictionary Normal file
View File

@ -0,0 +1,4 @@
packer-proxmox
(P|p)roxmox
HashiCorp
ISOs

40
.drone.yml Normal file
View File

@ -0,0 +1,40 @@
---
kind: pipeline
name: check
platform:
os: linux
arch: amd64
steps:
- name: whitespace
image: thegeeklab/alpine-tools
commands:
- git diff-tree --check $(git hash-object -t tree /dev/null) HEAD
- name: packer
image: hashicorp/packer
commands:
- packer fmt -recursive -check -diff .
- name: markdownlint
image: thegeeklab/markdownlint-cli
commands:
- markdownlint 'README.md'
- name: spellcheck
image: thegeeklab/alpine-tools
commands:
- spellchecker --files 'README.md' -d .dictionary -p spell indefinite-article syntax-urls --no-suggestions
environment:
FORCE_COLOR: true
trigger:
ref:
- refs/heads/main
- refs/tags/**
- refs/pull/**
---
kind: signature
hmac: 198cfa135666f3da049d67fb619d2438a9770b2ecad822bb040b47ac228c518b

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.envrc

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 Robert Kaussow <mail@thegeeklab.de>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

48
README.md Normal file
View File

@ -0,0 +1,48 @@
# packer-proxmox
[![Build Status](https://img.shields.io/drone/build/ansible/packer-proxmox?logo=drone&server=https%3A%2F%2Fdrone.rknet.org)](https://drone.rknet.org/ansible/packer-proxmox)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg?label=license)](LICENSE)
This repository provides infrastructure-as-code examples to automate the creation of virtual machine images on Proxmox using [HashiCorp Packer](https://www.packer.io) and the [Packer Plugin for Proxmox](https://www.packer.io/plugins/builders/proxmox/iso). All examples are written in the HashiCorp Configuration Language `HCL2`.
## Requirements
**Packer**:
- HashiCorp [Packer](packer-install) v1.7.7 or higher.
- HashiCorp [Packer Plugin for Proxmox](https://www.packer.io/plugins/builders/proxmox/iso) (`proxmox-iso`) v1.0.8 or higher.
Required plugins are automatically downloaded during the `packer init` phase. These plugins are placed in the same directory as your Packer executable `/usr/local/bin` or `$HOME/.packer.d/plugins`.
## Configuration
### Step 1 - Download the release
Download the **latest** release.
### Step 2 - Download the Guest Operating Systems ISOs
1. Download the required guest operating system ISO images (e.g. `Rocky-9.0-x86_64-minimal.iso`).
2. Obtain the checksum type (e.g. `sha256`, `md5`, etc.) and checksum value for each guest operating system `.iso` image. This will be used in the build input variables.
3. Upload the guest operating system `.iso` images to your Proxmox server.
### Step 3 - Configure the Variables
All available [variables](https://www.packer.io/docs/templates/hcl_templates/variables) are defined in the `variables.pkr.hcl` files. They can be overwritten using environment variables or in the `server.auto.pkrvars.hcl` file.
### Step 4 - Modify the Configurations and Scripts (Optional)
If required, modify the configuration and scripts files.
## Build
Initialize packer and start a build.
```Shell
packer init rocky-9.0/
packer build rocky-9.0/
```
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

33
renovate.json Normal file
View File

@ -0,0 +1,33 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["github>thegeeklab/renovate-presets:ansible"],
"extractVersion": "^v?(?<version>.*)$",
"packageRules": [
{
"groupName": "vaultwarden stack",
"matchPackagePatterns": ["^thegeeklab/vaultwarden"]
},
{
"groupName": "drone stack",
"matchPackagePatterns": ["^drone"]
},
{
"matchPackagePatterns": ["^minio"],
"versioning": "regex:^(RELEASE\\.)?(?<major>\\d{4})-(?<minor>\\d{2})-(?<patch>\\d{2})T\\S*?Z$",
"extractVersion": "^RELEASE\\.(?<version>.*)$"
},
{
"matchPackagePatterns": ["rpmbuild/cups"],
"versioning": "regex:^(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)(-(?<build>\\d+))?$"
},
{
"matchPackagePatterns": ["renovate/renovate"],
"schedule": ["before 3am on Monday"]
},
{
"matchPackagePatterns": ["renovate/renovate"],
"matchUpdateTypes": ["minor", "patch"],
"automerge": true
}
]
}

View File

@ -0,0 +1,146 @@
### Installs from the first attached CD-ROM/DVD on the system.
cdrom
### Performs the kickstart installation in text mode.
### By default, kickstart installations are performed in graphical mode.
text
### Accepts the End User License Agreement.
eula --agreed
### Sets the language to use during installation and the default language to use on the installed system.
lang ${vm_guest_os_language}
### Sets the default keyboard type for the system.
keyboard ${vm_guest_os_keyboard}
### Configure network information for target system and activate network devices in the installer environment (optional)
### --onboot enable device at a boot time
### --device device to be activated and / or configured with the network command
### --bootproto method to obtain networking configuration for device (default dhcp)
### --noipv6 disable IPv6 on this device
###
### network --bootproto=static --ip=172.16.11.200 --netmask=255.255.255.0 --gateway=172.16.11.200 --nameserver=172.16.11.4 --hostname centos-linux-8
network --bootproto=dhcp
### The selected profile will restrict root login.
### Add a user that can login and escalate privileges.
user --name=${build_username} --iscrypted --password=${build_password_encrypted} --groups=wheel
### Configure firewall settings for the system.
### --enabled reject incoming connections that are not in response to outbound requests
### --ssh allow sshd service through the firewall
firewall --enabled --ssh
### Sets up the authentication options for the system.
### The SSDD profile sets sha512 to hash passwords. Passwords are shadowed by default
### See the manual page for authselect-profile for a complete list of possible options.
authselect select sssd
### Sets the state of SELinux on the installed system.
### Defaults to enforcing.
selinux --enforcing
### Sets the system time zone.
timezone ${vm_guest_os_timezone} --utc
### Sets how the boot loader should be installed.
bootloader --location=mbr
### Initialize any invalid partition tables found on disks.
zerombr
### Removes partitions from the system, prior to creation of new partitions.
### By default, no partitions are removed.
### --linux erases all Linux partitions.
### --initlabel Initializes a disk (or disks) by creating a default disk label for all disks in their respective architecture.
clearpart --all --initlabel
### Modify partition sizes for the virtual machine hardware.
### Create primary system partitions.
part /boot --fstype xfs --size=1024 --label=BOOTFS
part /boot/efi --fstype vfat --size=1024 --label=EFIFS
part pv.01 --size=25 --grow
### Create a logical volume management (LVM) group.
volgroup vg00 --pesize=4096 pv.01
### Modify logical volume sizes for the virtual machine hardware.
### Create logical volumes.
logvol swap --fstype swap --name=lv_swap --vgname=vg00 --size=2048 --label=SWAPFS
logvol / --fstype xfs --name=lv_root --vgname=vg00 --size=8000 --label=ROOTFS
logvol /home --fstype xfs --name=lv_home --vgname=vg00 --size=4000 --label=HOMEFS
logvol /opt --fstype xfs --name=lv_opt --vgname=vg00 --size=1000 --label=OPTFS
logvol /tmp --fstype xfs --name=lv_tmp --vgname=vg00 --size=1000 --label=TMPFS --fsoptions="nosuid,noexec,nodev"
logvol /var --fstype xfs --name=lv_var --vgname=vg00 --size=2000 --label=VARFS --fsoptions="nosuid"
logvol /var/tmp --fstype xfs --name=lv_vartmp --vgname=vg00 --size=1000 --label=LOGFS --fsoptions="nosuid,noexec,nodev"
logvol /var/www --fstype xfs --name=lv_www --vgname=vg00 --size=2000 --label=LOGFS --fsoptions="nosuid,noexec,nodev"
logvol /var/log --fstype xfs --name=lv_log --vgname=vg00 --size=1000 --label=LOGFS --fsoptions="nosuid,noexec,nodev"
logvol /var/log/audit --fstype xfs --name=lv_audit --vgname=vg00 --size=1024 --label=AUDITFS --fsoptions="nosuid,noexec,nodev"
### Modifies the default set of services that will run under the default runlevel.
services --enabled=NetworkManager,sshd
### Do not configure X on the installed system.
skipx
### Disable firstboot.
firstboot --disable
### Packages selection.
%packages
@^minimal-environment
kexec-tools
openssh-server
openssh-clients
sudo
curl
python3
python3-libselinux
qemu-guest-agent
-aic94xx-firmware
-atmel-firmware
-b43-openfwwf
-bfa-firmware
-ipw2100-firmware
-ipw2200-firmware
-ivtv-firmware
-iwl100-firmware
-iwl1000-firmware
-iwl3945-firmware
-iwl4965-firmware
-iwl5000-firmware
-iwl5150-firmware
-iwl6000-firmware
-iwl6000g2a-firmware
-iwl6050-firmware
-libertas-usb8388-firmware
-ql2100-firmware
-ql2200-firmware
-ql23xx-firmware
-ql2400-firmware
-ql2500-firmware
-rt61pci-firmware
-rt73usb-firmware
-xorg-x11-drv-ati-firmware
-zd1211-firmware
%end
### Post-installation commands.
%post
dnf makecache
dnf install -y epel-release
dnf makecache
dnf install -y cloud-init
dnf clean all
touch /etc/cloud/cloud-init.disabled
echo "Completed cloud-init step!"
echo "${build_username} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/${build_username}
sed -i "s/^.*requiretty/#Defaults requiretty/" /etc/sudoers
%end
### Reboot after the installation is complete.
### --eject attempt to eject the media before rebooting.
reboot --eject

View File

@ -0,0 +1,19 @@
// Virtual Machine Settings
vm_id = 910
vm_guest_os_keyboard = de(nodeadkeys)
vm_guest_os_timezone = "Europe/Berlin"
// Proxmox Settings
proxmox_iso_pool = "local:iso"
proxmox_iso_file = "Rocky-9.0-x86_64-minimal.iso"
template_description = "Rocky Linux 9.0 Template"
template_name = "rocky-90-cloud"
// Communicator Settings
communicator_port = 22
communicator_timeout = "30m"
// Provisioner Settings
scripts = ["scripts/rocky-9.x.sh"]

86
rocky-9.0/server.pkr.hcl Normal file
View File

@ -0,0 +1,86 @@
packer {
required_version = ">= 1.8.3"
required_plugins {
proxmox = {
version = ">= 1.0.8"
source = "github.com/hashicorp/proxmox"
}
}
}
locals {
buildtime = formatdate("YYYY-MM-DD hh:mm ZZZ", timestamp())
data_source_content = {
"/ks.cfg" = templatefile("${abspath(path.root)}/data/init.ks.pkrtpl.hcl", {
build_username = var.build_username
build_password_encrypted = var.build_password_encrypted
vm_guest_os_language = var.vm_guest_os_language
vm_guest_os_keyboard = var.vm_guest_os_keyboard
vm_guest_os_timezone = var.vm_guest_os_timezone
})
}
data_source_command = "inst.ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ks.cfg"
}
source "proxmox-iso" "rocky-linux-90" {
// Proxmox Settings
proxmox_url = "${var.proxmox_url}"
node = "${var.proxmox_node}"
username = "${var.proxmox_username}"
password = "${var.proxmox_password}"
// Virtual Machine Settings
vm_id = "${var.vm_id}"
cores = "${var.vm_cpu_cores}"
sockets = "${var.vm_cpu_sockets}"
cpu_type = "${var.vm_cpu_type}"
memory = "${var.vm_mem_size}"
os = "${var.vm_os_type}"
network_adapters {
bridge = "${var.vm_network_adapter_bridge}"
model = "${var.vm_network_adapter_model}"
vlan_tag = "${var.vm_network_adapter_vlan_tag}"
}
disks {
disk_size = "${var.vm_disk_size}"
format = "${var.proxmox_storage_format}"
storage_pool = "${var.proxmox_storage_pool}"
storage_pool_type = "${var.proxmox_storage_pool_type}"
type = "scsi"
}
scsi_controller = "virtio-scsi-pci"
// Removable Media Settings
iso_file = "${var.proxmox_iso_pool}/${var.proxmox_iso_file}"
http_content = "${local.data_source_content}"
// Boot and Provisioning Settings
boot_wait = "10s"
boot_command = [
"up",
"<tab><wait>",
" ${local.data_source_command}<wait><enter>"
]
// Communicator Settings and Credentials
communicator = "ssh"
ssh_username = "${var.build_username}"
ssh_password = "${var.build_password}"
ssh_port = "${var.communicator_port}"
ssh_timeout = "${var.communicator_timeout}"
template_description = "${var.template_description} on ${local.buildtime}"
template_name = "${var.template_name}"
unmount_iso = true
}
build {
sources = ["source.proxmox-iso.rocky-linux-90"]
provisioner "shell" {
execute_command = "echo '${var.build_password}' | {{.Vars}} sudo -E -S sh -eux '{{.Path}}'"
scripts = formatlist("${path.cwd}/%s", var.scripts)
remote_folder = "/home/${var.build_username}"
}
}

181
rocky-9.0/variables.pkr.hcl Normal file
View File

@ -0,0 +1,181 @@
// Proxmox Settings
variable "proxmox_iso_file" {
type = string
}
variable "proxmox_iso_pool" {
type = string
default = "local:iso"
}
variable "proxmox_url" {
type = string
default = ""
}
variable "proxmox_node" {
type = string
default = ""
}
variable "proxmox_username" {
type = string
default = ""
}
variable "proxmox_password" {
type = string
default = ""
}
variable "proxmox_storage_format" {
type = string
default = "raw"
}
variable "proxmox_storage_pool" {
type = string
default = "local-lvm"
}
variable "proxmox_storage_pool_type" {
type = string
default = "lvm-thin"
}
variable "template_description" {
type = string
}
variable "template_name" {
type = string
}
// Virtual Machine Settings
variable "vm_id" {
type = number
description = "The ID used to reference the virtual machine."
default = 0
}
variable "vm_guest_os_language" {
type = string
description = "The guest operating system lanugage."
default = "en_US"
}
variable "vm_guest_os_keyboard" {
type = string
description = "The guest operating system keyboard input."
default = "us"
}
variable "vm_guest_os_timezone" {
type = string
description = "The guest operating system timezone."
default = "America/New_York"
}
variable "vm_os_type" {
type = string
description = "The operating system."
default = "l26"
}
variable "vm_cpu_sockets" {
type = number
description = "The number of virtual CPUs sockets. (e.g. '2')"
default = 1
}
variable "vm_cpu_cores" {
type = number
description = "The number of virtual CPUs cores per socket. (e.g. '1')"
default = 1
}
variable "vm_cpu_type" {
type = string
description = "The CPU type to emulate."
default = "host"
}
variable "vm_mem_size" {
type = number
description = "The size for the virtual memory in MB. (e.g. '2048')"
default = 1024
}
variable "vm_disk_size" {
type = string
description = "The size for the virtual disk in MB. (e.g. '8G')"
default = "32G"
}
variable "vm_disk_controller_type" {
type = list(string)
description = "The virtual disk controller types in sequence. (e.g. 'pvscsi')"
default = ["pvscsi"]
}
variable "vm_disk_thin_provisioned" {
type = bool
description = "Thin provision the virtual disk."
default = true
}
variable "vm_network_adapter_model" {
type = string
description = "Model of the virtual network adapter. (e.g. 'vmxnet3' or 'e1000e')"
default = "e1000"
}
variable "vm_network_adapter_bridge" {
type = string
description = "Which Proxmox bridge to attach the adapter to."
default = "vmbr0"
}
variable "vm_network_adapter_vlan_tag" {
type = string
description = "If the adapter should tag packets."
default = ""
}
// Communicator Settings and Credentials
variable "build_username" {
type = string
description = "The username to login to the guest operating system. (e.g. rainpole)"
sensitive = true
}
variable "build_password" {
type = string
description = "The password to login to the guest operating system."
sensitive = true
}
variable "build_password_encrypted" {
type = string
description = "The encrypted password to login the guest operating system."
sensitive = true
}
variable "communicator_port" {
type = number
description = "The port for the communicator protocol."
default = 22
}
variable "communicator_timeout" {
type = string
description = "The timeout for the communicator protocol."
default = "30m"
}
// Provisioner Settings
variable "scripts" {
type = list(string)
description = "A list of scripts and their relative paths to transfer and execute."
default = []
}

60
scripts/rocky-9.x.sh Normal file
View File

@ -0,0 +1,60 @@
#!/bin/bash
set -eo pipefail
#### Update system
echo '> Update packages ...'
dnf update -y
dnf clean all
### Cleans all audit logs. ###
echo '> Cleaning all audit logs ...'
if [ -f /var/log/audit/audit.log ]; then
cat /dev/null >/var/log/audit/audit.log
fi
if [ -f /var/log/wtmp ]; then
cat /dev/null >/var/log/wtmp
fi
if [ -f /var/log/lastlog ]; then
cat /dev/null >/var/log/lastlog
fi
### Cleans persistent udev rules. ###
echo '> Cleaning persistent udev rules ...'
if [ -f /etc/udev/rules.d/70-persistent-net.rules ]; then
rm /etc/udev/rules.d/70-persistent-net.rules
fi
### Clean the /tmp directories. ###
echo '> Cleaning /tmp directories ...'
rm -rf /tmp/*
rm -rf /var/tmp/*
rm -rf /var/cache/dnf/*
### Clean the SSH keys. ###
echo '> Cleaning the SSH keys ...'
shred -u /etc/ssh/*_key /etc/ssh/*_key.pub
rm -f /etc/ssh/ssh_config.d/allow-root-ssh.conf
### Clean the machine-id. ###
echo '> Cleaning the machine-id ...'
truncate -s 0 /etc/machine-id
rm -f /var/lib/dbus/machine-id
mkdir -p /var/lib/dbus
ln -s /etc/machine-id /var/lib/dbus/machine-id
### Clean the shell history. ###
echo '> Cleaning the shell history ...'
unset HISTFILE
history -cw
echo >~/.bash_history
rm -f /root/.bash_history
### Prepare cloud-init ###
echo '> Preparing cloud-init ...'
rm -f /etc/cloud/cloud-init.disabled
### Done. ###
echo '> Done.'