History rewrite
This commit is contained in:
28
.github/CONTRIBUTING
vendored
Normal file
28
.github/CONTRIBUTING
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
# How to contribute
|
||||
|
||||
I'm really glad you're reading this, because community driven, open-source projects need volunteer developers.
|
||||
|
||||
## Testing
|
||||
|
||||
Until actual tests can be developed, I ask that you test any *major* changes to Packer builds. What's a major change? Anything other than changing CPU, RAM, disk size would be considered a major change to a build.
|
||||
|
||||
## Submitting changes
|
||||
|
||||
Please send a [GitHub Pull Request to proxmox-packer-examples](https://github.com/ajschroeder/proxmox-packer-examples/pull/new/main) with a clear list of what you've done (read more about [pull requests](http://help.github.com/pull-requests/)). Please follow our coding conventions (below) and make sure all of your commits are atomic (one feature per commit).
|
||||
|
||||
Always write a clear log message for your commits. One-line messages are fine for small changes, but bigger changes should look like this:
|
||||
|
||||
$ git commit -m "A brief summary of the commit
|
||||
>
|
||||
> A paragraph describing what changed and its impact."
|
||||
|
||||
## Coding conventions
|
||||
|
||||
Start reading the code and you'll get the hang of it. We optimize for readability:
|
||||
|
||||
* We indent using two spaces (soft tabs)
|
||||
* We ALWAYS put spaces after list items and method parameters (`[1, 2, 3]`, not `[1,2,3]`), around operators (`x += 1`, not `x+=1`), and around hash arrows.
|
||||
* This is open source software. Consider the people who will read your code, and make it look nice for them. It's sort of like driving a car: Perhaps you love doing donuts when you're alone, but with passengers the goal is to make the ride as smooth as possible.
|
||||
|
||||
Thanks,
|
||||
AJ Schroeder
|
||||
20
.gitignore
vendored
20
.gitignore
vendored
@@ -1,2 +1,22 @@
|
||||
!**/template_*
|
||||
**/credentials*
|
||||
|
||||
# Configurations
|
||||
## Ignore default config directory.
|
||||
config/
|
||||
|
||||
# Manifests
|
||||
## Ignore manifests directory.
|
||||
manifests/*.json
|
||||
|
||||
# MacOS
|
||||
## Ignore desktop services files.
|
||||
**/.DS_Store
|
||||
|
||||
# Certificates and Keys
|
||||
## Ignore certificates files.
|
||||
**/*.cer
|
||||
**/*.crt
|
||||
**/*.p7b
|
||||
## Ignore public key files
|
||||
**/*.pub
|
||||
|
||||
128
CODE_OF_CONDUCT.md
Normal file
128
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,128 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series
|
||||
of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or
|
||||
permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
||||
28
LICENSE
Normal file
28
LICENSE
Normal file
@@ -0,0 +1,28 @@
|
||||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2023, TheHitman1977
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
734
README.md
Normal file
734
README.md
Normal file
@@ -0,0 +1,734 @@
|
||||
# Packer Examples for Proxmox
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Introduction](#introduction)
|
||||
1. [Requirements](#requirements)
|
||||
1. [Download](#download)
|
||||
1. [Configuration](#configuration)
|
||||
1. [Build](#build)
|
||||
1. [Troubleshoot](#troubleshoot)
|
||||
1. [Known Issues](#known-issues)
|
||||
1. [Unsupported Features](#unsupported-features)
|
||||
1. [Contributing](#contributing)
|
||||
1. [Credits](#credits)
|
||||
|
||||
## Introduction
|
||||
|
||||
This repository provides opinionated infrastructure-as-code examples to automate the creation of virtual machine images and their guest operating systems on Proxmox using [HashiCorp Packer][packer] and the [Packer Plugin for Proxmox][packer-plugin-proxmox] (`proxmox-iso` builder). All examples are authored in the HashiCorp Configuration Language ("HCL2").
|
||||
|
||||
By default, the machine image artifacts are converted to templates within Proxmox after a virtual machine is built and configured according to the individual templates. With the Packer Plugin for Proxmox, a new template with a unique VMID gets created each time Packer runs successfully[^1]. This is unlike VMware, where if an item with the same name exists it will be overwritten.
|
||||
|
||||
The following builds are available:
|
||||
|
||||
## Linux Distributions
|
||||
|
||||
| Operating System | Version |
|
||||
| :--- | :--- |
|
||||
| CentOS Stream | 9 |
|
||||
| CentOS Stream | 8 |
|
||||
| Debian | 12 |
|
||||
| Debian | 11 |
|
||||
| Ubuntu Server | 22.04 LTS |
|
||||
| Ubuntu Server | 20.04 LTS |
|
||||
|
||||
## Requirements
|
||||
|
||||
**Operating Systems**:
|
||||
|
||||
Operating systems and versions tested with the project:
|
||||
|
||||
- Proxmox PVE Version 8
|
||||
- Ubuntu Server 22.04 LTS (`x86_64`)
|
||||
- CentOS Stream 9 (`x86_64`)
|
||||
|
||||
**Packer**:
|
||||
|
||||
- HashiCorp [Packer][packer-install] 1.9.4 or higher.
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> Click on the operating system name to display the installation steps.
|
||||
|
||||
- <details>
|
||||
<summary>Ubuntu</summary>
|
||||
|
||||
The Terraform packages are signed using a private key controlled by HashiCorp, so you must configure your system to trust that HashiCorp key for package authentication.
|
||||
|
||||
To configure your repository:
|
||||
|
||||
```shell
|
||||
sudo bash -c 'wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor > /usr/share/keyrings/hashicorp-archive-keyring.gpg'
|
||||
```
|
||||
|
||||
Verify the key's fingerprint:
|
||||
|
||||
```shell
|
||||
gpg --no-default-keyring --keyring /usr/share/keyrings/hashicorp-archive-keyring.gpg --fingerprint
|
||||
```
|
||||
|
||||
The fingerprint must match E8A0 32E0 94D8 EB4E A189 D270 DA41 8C88 A321 9F7B. You can also verify the key on [Security at HashiCorp][hcp-security] under Linux Package Checksum Verification.
|
||||
|
||||
Add the official HashiCorp repository to your system:
|
||||
|
||||
```shell
|
||||
sudo bash -c 'echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \
|
||||
https://apt.releases.hashicorp.com $(lsb_release -cs) main" > /etc/apt/sources.list.d/hashicorp.list'
|
||||
```
|
||||
|
||||
Install Packer from HashiCorp repository:
|
||||
|
||||
```shell
|
||||
sudo apt update && sudo apt install packer
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
- <details>
|
||||
<summary>CentOS Stream 9</summary>
|
||||
|
||||
Install `yum-config-manager` to manage your repositories.
|
||||
|
||||
```shell
|
||||
sudo yum install -y yum-utils
|
||||
```
|
||||
|
||||
Use `yum-config-manager` to add the official HashiCorp Linux repository:
|
||||
|
||||
```shell
|
||||
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
|
||||
```
|
||||
|
||||
Install.
|
||||
|
||||
```shell
|
||||
sudo yum -y install packer
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
- Packer plugins:
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> Required plugins are automatically downloaded and initialized when using `./build.sh`. For dark sites, you may download the plugins and place these same directory as your Packer executable `/usr/local/bin` or `$HOME/.packer.d/plugins`.
|
||||
|
||||
- HashiCorp [Packer Plugin for Proxmox][packer-plugin-proxmox] 1.1.3 or later.
|
||||
- [Packer Plugin for Git][packer-plugin-git] 0.4.2 or later - a community plugin for HashiCorp Packer.
|
||||
|
||||
**Ansible**:
|
||||
|
||||
- [Ansible][ansible] [Core][ansible-core] version 2.10 or higher.
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> Click on the operating system name to display the installation steps.
|
||||
|
||||
- <details>
|
||||
<summary>Ubuntu</summary>
|
||||
|
||||
It is recommended that you install ansible-core using your system's package manager instead of via pip.
|
||||
|
||||
Refresh the repositories:
|
||||
```shell
|
||||
sudo apt update
|
||||
```
|
||||
|
||||
Install software-properties-common:
|
||||
```shell
|
||||
sudo apt install -y software-properties-common
|
||||
```
|
||||
|
||||
Add the Ansible repository to your system:
|
||||
|
||||
```shell
|
||||
sudo add-apt-repository --yes --update ppa:ansible/ansible
|
||||
```
|
||||
|
||||
Install ansible-core from the Ansible repository:
|
||||
|
||||
```shell
|
||||
sudo apt install -y ansible-core
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
- <details>
|
||||
<summary>CentOS Stream 9</summary>
|
||||
|
||||
It is recommended that you install ansible-core using your system's package manager instead of via pip.
|
||||
|
||||
Install.
|
||||
|
||||
```shell
|
||||
dnf -y install ansible-core
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
**Platform**:
|
||||
|
||||
- Proxmox PVE 8.0 or later.
|
||||
|
||||
# Download
|
||||
|
||||
After installing the required software, the quickest way to get building is to clone this repository.
|
||||
|
||||
```shell
|
||||
git clone https://github.com/ajschroeder/packer-examples-for-proxmox.git
|
||||
cd packer-examples-for-proxmox
|
||||
```
|
||||
|
||||
The following table describes the directory structure.
|
||||
|
||||
| Directory | Description |
|
||||
| :--- | :--- |
|
||||
| **`ansible`** | Contains the Ansible roles to prepare Linux machine image builds. |
|
||||
| **`builds`** | Contains the templates, variables, and configuration files for the machine image builds. |
|
||||
| **`manifests`** | Manifests created after the completion of the machine image builds. |
|
||||
|
||||
|
||||
# Configuration
|
||||
|
||||
## Example Variables
|
||||
|
||||
The project includes example variables files that you can use as a starting point for your own configuration.
|
||||
|
||||
The [variables][packer-variables] are defined in `.pkrvars.hcl` files.
|
||||
|
||||
Run the config script `./config.sh` to copy the `.pkrvars.hcl.example` files to a `config` directory.
|
||||
|
||||
```shell
|
||||
./config.sh
|
||||
./build.sh
|
||||
```
|
||||
|
||||
The `config` folder is the default folder. You can override the default by passing an alternate value as the first argument.
|
||||
|
||||
For example:
|
||||
|
||||
San Francisco: `us-west-1`
|
||||
|
||||
```shell
|
||||
./config.sh us-west-1
|
||||
./build.sh us-west-1
|
||||
```
|
||||
|
||||
Los Angeles: `us-west-2`
|
||||
|
||||
```shell
|
||||
./config.sh us-west-2
|
||||
./build.sh us-west-2
|
||||
```
|
||||
|
||||
This is useful for the purposes of running machine image builds for different environment.
|
||||
|
||||
## Configuration Variables
|
||||
|
||||
### Build
|
||||
|
||||
Edit the `config/build.pkrvars.hcl` file to configure the credentials for the default account on machine images.
|
||||
|
||||
```hcl title="config/build.pkrvars.hcl"
|
||||
build_username = "example"
|
||||
build_password = "<plaintext_password>"
|
||||
build_password_encrypted = "<sha512_encrypted_password>"
|
||||
build_key = "<public_key>"
|
||||
```
|
||||
|
||||
You will need to generate a SHA-512 encrypted password for the `build_password_encrypted` using tools like `mkpasswd`.
|
||||
|
||||
Run the following command to generate a SHA-512 encrypted password:
|
||||
|
||||
```shell
|
||||
mkpasswd -m sha512
|
||||
```
|
||||
|
||||
The following output is displayed:
|
||||
|
||||
```shell
|
||||
Password: ***************
|
||||
[password hash]
|
||||
```
|
||||
|
||||
Generate a public key for the `build_key` for public key authentication.
|
||||
|
||||
Run the following command to generate a public key for the `build_key` for public key authentication.
|
||||
|
||||
```shell
|
||||
ssh-keygen -t ecdsa -b 512 -C "<name@example.com>"
|
||||
```
|
||||
|
||||
The following output is displayed:
|
||||
|
||||
```shell
|
||||
Generating public/private ecdsa key pair.
|
||||
Enter file in which to save the key (/Users/example/.ssh/id_ecdsa):
|
||||
Enter passphrase (empty for no passphrase): **************
|
||||
Enter same passphrase again: **************
|
||||
Your identification has been saved in /Users/example/.ssh/id_ecdsa.
|
||||
Your public key has been saved in /Users/example/.ssh/id_ecdsa.pub.
|
||||
```
|
||||
|
||||
The content of the public key, `build_key`, is added the key to the `~/.ssh/authorized_keys` file of the `build_username` on the Linux guest operating systems.
|
||||
|
||||
> [!IMPORTANT]
|
||||
>
|
||||
> Make sure to replace the example public keys and passwords!
|
||||
>
|
||||
> By default, both Public Key Authentication and Password Authentication are enabled for Linux distributions.
|
||||
>
|
||||
> If you wish to disable Password Authentication and only use Public Key Authentication, comment or remove the portion of the associated Ansible `configure` role.
|
||||
|
||||
### Ansible
|
||||
|
||||
Edit the `config/ansible.pkrvars.hcl` file to configure the credentials for the Ansible account on Linux machine images.
|
||||
|
||||
```hcl title="config/ansible.pkrvars.hcl"
|
||||
ansible_username = "ansible"
|
||||
ansible_key = "<public_key>"
|
||||
```
|
||||
|
||||
**Ansible User Password**
|
||||
|
||||
A random password is auto-generated for the Ansible user.
|
||||
|
||||
### Common
|
||||
|
||||
Edit the `config/common.pkrvars.hcl` file to configure the following common variables:
|
||||
|
||||
- Removable Media Settings
|
||||
- Boot and Provisioning Settings
|
||||
- HCP Packer Registry
|
||||
|
||||
```hcl title="config/common.pkrvars.hcl"
|
||||
// Removable Media Settings
|
||||
common_iso_storage = "<Proxmox Storage Location>"
|
||||
|
||||
// Boot and Provisioning Settings
|
||||
common_data_source = "http"
|
||||
common_http_ip = null
|
||||
common_http_port_min = 8000
|
||||
common_http_port_max = 8099
|
||||
common_ip_wait_timeout = "20m"
|
||||
common_shutdown_timeout = "15m"
|
||||
|
||||
// HCP Packer
|
||||
common_hcp_packer_registry_enabled = false
|
||||
```
|
||||
|
||||
### Data Source
|
||||
|
||||
The default provisioning data source for Linux machine image builds is `http`. This is used to serve the kickstart files to the Linux guest operating system during the build.
|
||||
|
||||
```hcl title="config/common.pkrvars.hcl"
|
||||
common_data_source = "http"
|
||||
```
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> Packer includes a built-in HTTP server that is used to serve the kickstart files for Linux machine image builds.
|
||||
>
|
||||
> If iptables/nftables is enabled on your Packer host, you will need to open `common_http_port_min` through `common_http_port_max` ports.
|
||||
>
|
||||
> iptables command:
|
||||
> ```shell
|
||||
> iptables -A INPUT -p tcp --match multiport --dports 8000:9000 -j ACCEPT
|
||||
> ```
|
||||
>
|
||||
> firewall-cmd example:
|
||||
> ```shell
|
||||
> firewall-cmd --zone=public --add-port=8000-9000/tcp --permanent
|
||||
> firewall-cmd --reload
|
||||
> ```
|
||||
|
||||
You can change the `common_data_source` from `http` to `disk` to build supported Linux machine images without the need to use Packer's HTTP server. This is useful for environments that may not be able to route back to the system from which Packer is running. For example, building a machine image in VMware Cloud on AWS.
|
||||
|
||||
```hcl title="config/common.pkrvars.hcl"
|
||||
common_data_source = "disk"
|
||||
```
|
||||
|
||||
The Packer plugin's `cd_content` option is used when selecting `disk` unless the distribution does not support a secondary CD-ROM.
|
||||
|
||||
### HTTP Binding
|
||||
|
||||
If you need to define a specific IPv4 address from your host for Packer's built-in HTTP server, modify the `common_http_ip` variable from `null` to a `string` value that matches an IP address on your Packer host.
|
||||
|
||||
```hcl title="config/common.pkrvars.hcl"
|
||||
common_http_ip = "172.16.11.254"
|
||||
```
|
||||
|
||||
### Proxmox VE
|
||||
|
||||
Edit the `config/proxmox.pkrvars.hcl` file to configure the following:
|
||||
|
||||
- Promxox Endpoint and Credentials
|
||||
|
||||
```hcl title="config/proxmox.pkrvars.hcl"
|
||||
// Proxmox Credentials
|
||||
proxmox_api_url = "<FQDN or IP of proxmox server>"
|
||||
proxmox_api_token_id = "name@realm!token"
|
||||
proxmox_api_token_secret = "<token secret>"
|
||||
proxmox_insecure_connection = false
|
||||
|
||||
// Proxmox Settings
|
||||
proxmox_node = "<proxmox node name>"
|
||||
```
|
||||
|
||||
The `proxmox_api_token_id` variable uses a specific format and, as the time of this writing, needs to be assigned to the `PVEAdmin` role. One of the to-do's is to document a least-privilege method of creating the Proxmox API token.
|
||||
|
||||
For more information, please see the [Proxmox documentation][proxmox-api-tokens] on authentication.
|
||||
|
||||
For Proxmox installs that use a self-signed certificate, you will want to set `proxmox_insecure_connection` to `true`.
|
||||
|
||||
### Machine Images
|
||||
|
||||
Edit the `*.auto.pkrvars.hcl` file in each `builds/<type>/<build>` directory to configure the following virtual machine hardware settings, as required:
|
||||
|
||||
- CPUs `(int)`
|
||||
- CPU Cores `(int)`
|
||||
- Memory in MB `(int)`
|
||||
- Primary Disk in MB `(string)` (e.g. 32GB)
|
||||
- .iso Path `(string)`
|
||||
- .iso File `(string)`
|
||||
|
||||
```hcl title="builds/linux/debian/11/linux-debian.auto.pkrvars.hcl"
|
||||
// Guest Operating System Metadata
|
||||
vm_os_language = "en_US"
|
||||
vm_os_keyboard = "us"
|
||||
vm_os_timezone = "UTC"
|
||||
vm_os_family = "linux"
|
||||
vm_os_name = "debian"
|
||||
vm_os_version = "11"
|
||||
|
||||
// Virtual Machine Guest Operating System Setting
|
||||
vm_os_type = "l26"
|
||||
|
||||
// Virtual Machine Hardware Settings
|
||||
vm_bios = "seabios"
|
||||
vm_cpu_count = 1
|
||||
vm_cpu_sockets = 1
|
||||
vm_cpu_type = "kvm64"
|
||||
vm_mem_size = 2048
|
||||
vm_disk_type = "virtio"
|
||||
vm_disk_size = "32G"
|
||||
vm_disk_format = "raw"
|
||||
vm_storage_pool = "vm-data"
|
||||
vm_disk_controller_type = "virtio-scsi-pci"
|
||||
vm_network_card_model = "virtio"
|
||||
vm_bridge_interface = "vmbr0"
|
||||
vm_vlan_tag = "102"
|
||||
|
||||
// Removable Media Settings
|
||||
iso_path = "iso"
|
||||
iso_file = "ubuntu-22.04-live-server-amd64.iso"
|
||||
iso_checksum = "84aeaf7823c8c61baa0ae862d0a06b03409394800000b3235854a6b38eb4856f"
|
||||
|
||||
// Boot Settings
|
||||
vm_boot = "order=virtio0;ide2;net0"
|
||||
vm_boot_wait = "5s"
|
||||
|
||||
// EFI Settings (currently an unsupported feature)
|
||||
vm_firmware_path = "./OVMF.fd"
|
||||
vm_efi_storage_pool = "vm-data"
|
||||
vm_efi_pre_enrolled_keys = false
|
||||
vm_efi_type = "4m"
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> All `variables.auto.pkrvars.hcl` default to using:
|
||||
> - VirtIO SCSI storage device
|
||||
> - VirtIO (paravirtualized) network card device
|
||||
> - BIOS boot firmware
|
||||
|
||||
The defaults use VirtIO to balance out performance, compatibility, and ease of use. Feel free to change the storage and network controllers to suit your needs. However, if you change the storage or network controllers and run into issues you should change them back to defaults and try the builds again. I won't support any builds that don't use the VirtIO drivers.
|
||||
|
||||
At this time UEFI is [not supported](#unsupported-features) so that means we are left with `seabios` as the default (and only) firmware setting. The reasons for not supporting UEFI may be boring, but the biggest reason is that Proxmox Virtual Machines that have EFI disks can't be live migrated between nodes or storage pools.
|
||||
|
||||
If you are interested in more detail - when I first started testing these packer builds in my home lab I was using `ovmf` (UEFI) firmware. During my initial testing the ZFS pool where I housed my VMs cratered and I had to rebuild the pool and restore all my VMs from backups. During the recovery of my storage pool, I changed over to LVM and had to migrate VMs between storage pools several times and each VM that had EFI disks had to be shutdown, migrated, and then powered on. Offline migration isn't *that* much of an inconvenience, however at the time I was trying to figure out my VM storage and recover all my VMs it was just one more annoyance. All that said, I think Proxmox should support live migration regardless of VM firmware type.
|
||||
|
||||
### VM Storage
|
||||
|
||||
> [!WARNING]
|
||||
> The storage config is still very much a work in progress. Suggestions are welcome, see the contributing section.
|
||||
|
||||
Edit the `config/linux-storage.pkrvars.hcl` file to configure storage for VM templates.
|
||||
|
||||
This file is fairly lengthy and should be broken down into chunks.
|
||||
|
||||
#### Disk Device
|
||||
|
||||
```hcl
|
||||
// VM Storage Settings
|
||||
vm_disk_device = "vda"
|
||||
```
|
||||
|
||||
`vm_disk_device`:`string` - This variable depends on the disk controller used inside of the specific `.auto.pkrvars.hcl` file. By default, the builds use the `virtio-scsi-pci` disk controller and that requires the use of `vda`. If you decide to run a SCSI controller, then you'll have to change the value to `sda`. This variable only accepts `sda` or `vda` as values.
|
||||
|
||||
#### Disk Partitions
|
||||
|
||||
`vm_disk_partitions`:`list[dict]` - Use this list to define the primary partitions that will be created when a specific build runs. Each of the builds process this list in order, so the first partition defined in the list will be the first partition created, the second one listed will be the second one created, and so on.
|
||||
|
||||
##### Automatic Partitioning (All In One) Example
|
||||
This example is the simplest way to allocate storage within your templates. It makes use of the particular Linux distribution's automatic partitioning feature in their respective automatic installers.
|
||||
|
||||
The three settings to note are:
|
||||
|
||||
- name `(string)`: This must be set to `autopart` to use automatic partitioning
|
||||
- size `(int)`: This needs to be set to -1 to consume all available disk space
|
||||
- fstype `(string)` (optional): This can be set to `lvm`, `simple`, or left blank. Setting this to `simple` uses a single regular partition. Setting this to `lvm` still uses a single partition, but makes use of LVM. Leaving this value blank will default to a `simple` partitioning scheme.
|
||||
|
||||
```hcl
|
||||
vm_disk_partitions = [
|
||||
{
|
||||
name = "autopart"
|
||||
size = -1,
|
||||
format = {
|
||||
label = "",
|
||||
fstype = "lvm",
|
||||
},
|
||||
mount = {
|
||||
path = "",
|
||||
options = "",
|
||||
},
|
||||
volume_group = "",
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
##### LVM Partitioning Example
|
||||
Below is an example of a partition layout for a VM template that boots with BIOS and uses LVM. The first partition is a 1GB primary partition and is mounted as /boot, finally the second partition consumes the rest of the free space (noted by -1 for space) and is setup for LVM.
|
||||
|
||||
> [!WARNING]
|
||||
> The mount point of `/boot` also is not arbitrary
|
||||
|
||||
```hcl
|
||||
vm_disk_partitions = [
|
||||
{
|
||||
name = "bios_grub"
|
||||
size = 1,
|
||||
format = {
|
||||
label = "",
|
||||
fstype = "",
|
||||
},
|
||||
mount = {
|
||||
path = "",
|
||||
options = "",
|
||||
},
|
||||
volume_group = "",
|
||||
},
|
||||
{
|
||||
name = "boot"
|
||||
size = 1000,
|
||||
format = {
|
||||
label = "BOOTFS",
|
||||
fstype = "ext4",
|
||||
},
|
||||
mount = {
|
||||
path = "/boot",
|
||||
options = "",
|
||||
},
|
||||
volume_group = "",
|
||||
},
|
||||
{
|
||||
name = "vg_root"
|
||||
size = -1,
|
||||
format = {
|
||||
label = "",
|
||||
fstype = "",
|
||||
},
|
||||
mount = {
|
||||
path = "",
|
||||
options = "",
|
||||
},
|
||||
volume_group = "vg_root",
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
##### LVM Partitioning Example with CIS partitions
|
||||
Below is an example of a partition layout for a VM template that uses LVM and has extra partitions with mount options required by CIS for hardening a system. The first partition is a 1GB primary partition and is mounted as /boot, finally the second partition consumes the rest of the free space (noted by -1 for space) and is setup for LVM.
|
||||
|
||||
> [!WARNING]
|
||||
> The mount point of `/boot` also is not arbitrary
|
||||
|
||||
```hcl title="config/linux-storage.pkrvars.hcl"
|
||||
// VM Storage Settings
|
||||
vm_disk_device = "vda"
|
||||
vm_disk_use_swap = true
|
||||
vm_disk_partitions = [
|
||||
{
|
||||
name = "boot"
|
||||
size = 1000,
|
||||
format = {
|
||||
label = "BOOTFS",
|
||||
fstype = "ext4",
|
||||
},
|
||||
mount = {
|
||||
path = "/boot",
|
||||
options = "",
|
||||
},
|
||||
volume_group = "",
|
||||
},
|
||||
{
|
||||
name = "vg_root"
|
||||
size = -1,
|
||||
format = {
|
||||
label = "",
|
||||
fstype = "",
|
||||
},
|
||||
mount = {
|
||||
path = "",
|
||||
options = "",
|
||||
},
|
||||
volume_group = "vg_root",
|
||||
},
|
||||
]
|
||||
vm_disk_lvm = [
|
||||
{
|
||||
name: "vg_root",
|
||||
partitions: [
|
||||
{
|
||||
name = "lv_swap",
|
||||
size = 1000,
|
||||
format = {
|
||||
label = "SWAPFS",
|
||||
fstype = "swap",
|
||||
},
|
||||
mount = {
|
||||
path = "",
|
||||
options = "",
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "lv_root",
|
||||
size = 3000,
|
||||
format = {
|
||||
label = "ROOTFS",
|
||||
fstype = "ext4",
|
||||
},
|
||||
mount = {
|
||||
path = "/",
|
||||
options = "",
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "lv_home",
|
||||
size = 1000,
|
||||
format = {
|
||||
label = "HOMEFS",
|
||||
fstype = "ext4",
|
||||
},
|
||||
mount = {
|
||||
path = "/home",
|
||||
options = "nodev,nosuid",
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "lv_opt",
|
||||
size = 2000,
|
||||
format = {
|
||||
label = "OPTFS",
|
||||
fstype = "ext4",
|
||||
},
|
||||
mount = {
|
||||
path = "/opt",
|
||||
options = "nodev",
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "lv_tmp",
|
||||
size = 2000,
|
||||
format = {
|
||||
label = "TMPFS",
|
||||
fstype = "ext4",
|
||||
},
|
||||
mount = {
|
||||
path = "/tmp",
|
||||
options = "nodev,noexec,nosuid",
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "lv_var",
|
||||
size = 3000,
|
||||
format = {
|
||||
label = "VARFS",
|
||||
fstype = "ext4",
|
||||
},
|
||||
mount = {
|
||||
path = "/var",
|
||||
options = "nodev",
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "lv_var_tmp",
|
||||
size = 1000,
|
||||
format = {
|
||||
label = "VARTMPFS",
|
||||
fstype = "ext4",
|
||||
},
|
||||
mount = {
|
||||
path = "/var/tmp",
|
||||
options = "nodev,noexec,nosuid",
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "lv_var_log",
|
||||
size = 1000,
|
||||
format = {
|
||||
label = "VARLOGFS",
|
||||
fstype = "ext4",
|
||||
},
|
||||
mount = {
|
||||
path = "/var/log",
|
||||
options = "nodev,noexec,nosuid",
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "lv_var_audit",
|
||||
size = 500,
|
||||
format = {
|
||||
label = "AUDITFS",
|
||||
fstype = "ext4",
|
||||
},
|
||||
mount = {
|
||||
path = "/var/log/audit",
|
||||
options = "nodev,noexec,nosuid",
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
# Known Issues
|
||||
|
||||
## CentOS Stream 8
|
||||
- Anaconda will stop the install with a message complaining about not enough disk space. This is a known issue with kickstart on RHEL 8, however none of the fixes that have been tried have worked. If you want to build a CentOS-Stream-8 template, you will need to access the console of the machine and simply ignore the warning and continue the installation.
|
||||
|
||||
# Unsupported Features
|
||||
- UEFI firmware
|
||||
- Networking configurations other than DHCP for templates
|
||||
|
||||
# Contributing
|
||||
Contributions
|
||||
|
||||
# Credits
|
||||
The repository is modeled after the [VMware Packer Examples][packer-examples-for-vsphere] repository. As someone who initially struggled with organization of a packer project, the VMware repository helped me significantly.
|
||||
|
||||
|
||||
[//]: Links
|
||||
[ansible]: https://www.ansible.com
|
||||
[ansible-core]: https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#selecting-an-ansible-package-and-version-to-install
|
||||
[packer]: https://www.packer.io
|
||||
[packer-examples-for-vsphere]: https://github.com/vmware-samples/packer-examples-for-vsphere
|
||||
[packer-install]: https://developer.hashicorp.com/packer/tutorials/docker-get-started/get-started-install-cli
|
||||
[packer-plugin-git]: https://github.com/ethanmdavidson/packer-plugin-git
|
||||
[packer-plugin-proxmox]: https://developer.hashicorp.com/packer/integrations/hashicorp/proxmox
|
||||
[packer-variables]: https://developer.hashicorp.com/packer/docs/templates/hcl_templates/variables
|
||||
[proxmox-api-tokens]: https://pve.proxmox.com/pve-docs/pveum-plain.html
|
||||
|
||||
|
||||
[^1]: If you try to create a VM with the same ID as an existing VM the Proxmox API will generate a 500 error.
|
||||
7
ansible/ansible.cfg
Normal file
7
ansible/ansible.cfg
Normal file
@@ -0,0 +1,7 @@
|
||||
[defaults]
|
||||
display_skipped_hosts = false
|
||||
ansible_python_interpreter = /usr/bin/python3
|
||||
|
||||
[ssh_connection]
|
||||
ssh_args = -C -o ControlMaster=auto -o ControlPersist=60s -o HostKeyAlgorithms=+ssh-rsa -o PubkeyAcceptedKeyTypes=+ssh-rsa
|
||||
scp_extra_args = "-O"
|
||||
11
ansible/main.yml
Normal file
11
ansible/main.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- become: "yes"
|
||||
become_method: sudo
|
||||
debugger: never
|
||||
gather_facts: "yes"
|
||||
hosts: all
|
||||
roles:
|
||||
- base
|
||||
- users
|
||||
- configure
|
||||
- clean
|
||||
17
ansible/roles/base/tasks/debian.yml
Normal file
17
ansible/roles/base/tasks/debian.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
- name: "Updating the guest operating system."
|
||||
apt:
|
||||
force_apt_get: true
|
||||
name: "*"
|
||||
state: latest # noqa package-latest
|
||||
update_cache: "yes"
|
||||
|
||||
- name: "Installing additional packages."
|
||||
apt:
|
||||
name:
|
||||
- bash-completion
|
||||
- curl
|
||||
- wget
|
||||
- unzip
|
||||
- ca-certificates
|
||||
state: latest # noqa package-latest
|
||||
10
ansible/roles/base/tasks/main.yml
Normal file
10
ansible/roles/base/tasks/main.yml
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
- name: "Prepare the {{ ansible_facts['distribution'] }} guest operating system."
|
||||
include_tasks: "{{ ansible_facts['distribution'] | lower }}.yml"
|
||||
when: "ansible_facts['distribution'] == 'Debian'"
|
||||
- name: "Prepare the {{ ansible_facts['distribution'] }} guest operating system."
|
||||
include_tasks: "{{ ansible_facts['distribution'] | lower }}.yml"
|
||||
when: "ansible_facts['distribution'] == 'Ubuntu'"
|
||||
- name: "Prepare the {{ ansible_facts['distribution'] }} guest operating system."
|
||||
include_tasks: redhat.yml
|
||||
when: "ansible_facts['distribution'] in ['RedHat', 'CentOS', 'Rocky', 'AlmaLinux', 'OracleLinux']"
|
||||
41
ansible/roles/base/tasks/redhat.yml
Normal file
41
ansible/roles/base/tasks/redhat.yml
Normal file
@@ -0,0 +1,41 @@
|
||||
---
|
||||
|
||||
- name: "Checking Red Hat Subscription Manager status."
|
||||
ansible.builtin.shell: "subscription-manager refresh"
|
||||
when: "ansible_facts['distribution'] == 'RedHat'"
|
||||
|
||||
- name: "Updating the guest operating system."
|
||||
ansible.builtin.dnf:
|
||||
name: "*"
|
||||
state: latest # noqa package-latest
|
||||
update_cache: "yes"
|
||||
when: "ansible_facts['distribution_major_version'] >= \"8\""
|
||||
|
||||
- name: "Installing additional packages."
|
||||
ansible.builtin.dnf:
|
||||
name:
|
||||
- curl
|
||||
- wget
|
||||
- unzip
|
||||
- ca-certificates
|
||||
state: latest # noqa package-latest
|
||||
when: "ansible_facts['distribution_major_version'] >= \"8\""
|
||||
|
||||
- name: "Updating the guest operating system."
|
||||
when: "ansible_facts['distribution_major_version'] <= \"7\""
|
||||
ansible.builtin.yum:
|
||||
name: "*"
|
||||
state: latest # noqa package-latest
|
||||
update_cache: "yes"
|
||||
|
||||
- name: "Installing additional packages."
|
||||
when: "ansible_facts['distribution_major_version'] <= \"7\""
|
||||
ansible.builtin.yum:
|
||||
name:
|
||||
- curl
|
||||
- wget
|
||||
- unzip
|
||||
- ca-certificates
|
||||
state: latest # noqa package-latest
|
||||
|
||||
...
|
||||
17
ansible/roles/base/tasks/ubuntu.yml
Normal file
17
ansible/roles/base/tasks/ubuntu.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
- name: "Updating the guest operating system."
|
||||
apt:
|
||||
force_apt_get: true
|
||||
name: "*"
|
||||
state: latest # noqa package-latest
|
||||
update_cache: "yes"
|
||||
|
||||
- name: "Installing additional packages."
|
||||
apt:
|
||||
name:
|
||||
- bash-completion
|
||||
- curl
|
||||
- wget
|
||||
- unzip
|
||||
- ca-certificates
|
||||
state: latest # noqa package-latest
|
||||
81
ansible/roles/clean/tasks/debian.yml
Normal file
81
ansible/roles/clean/tasks/debian.yml
Normal file
@@ -0,0 +1,81 @@
|
||||
---
|
||||
|
||||
- name: Remove audit log files
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
loop:
|
||||
- "/var/log/audit/audit.log"
|
||||
- "/var/log/wtmp"
|
||||
- "/var/log/lastlog"
|
||||
|
||||
- name: Check to see if the /var/log/audit directory exists
|
||||
ansible.builtin.stat:
|
||||
path: "/var/log/audit"
|
||||
register: audit_directory
|
||||
|
||||
- name: Ensure /var/log/audit directory exists
|
||||
ansible.builtin.file:
|
||||
path: /var/log/audit
|
||||
state: directory
|
||||
mode: "0750"
|
||||
owner: root
|
||||
group: adm
|
||||
when: audit_directory.stat.exists
|
||||
|
||||
- name: Ensure /var/log/audit/audit.log exists
|
||||
ansible.builtin.file:
|
||||
path: /var/log/audit/audit.log
|
||||
state: touch
|
||||
mode: "0640"
|
||||
owner: root
|
||||
group: adm
|
||||
when: audit_directory.stat.exists
|
||||
|
||||
- name: Ensure wtmp and lastlog exist with the correct permissions
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ item }}"
|
||||
content: ""
|
||||
mode: "0664"
|
||||
owner: root
|
||||
group: utmp
|
||||
loop:
|
||||
- "/var/log/wtmp"
|
||||
- "/var/log/lastlog"
|
||||
|
||||
- name: Cleaning persistent udev rules
|
||||
ansible.builtin.file:
|
||||
path: /etc/udev/rules.d/70-persistent-net.rules
|
||||
state: absent
|
||||
|
||||
- name: "Cleaning the /tmp directories"
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
loop:
|
||||
- "/tmp/*"
|
||||
- "/var/tmp/*"
|
||||
|
||||
- name: "Cleaning the SSH host keys."
|
||||
shell: |
|
||||
rm -f /etc/ssh/ssh_host_*
|
||||
|
||||
- name: remove /etc/machine-id
|
||||
file:
|
||||
path: /etc/machine-id
|
||||
state: absent
|
||||
|
||||
- name: remove /var/lib/dbus/machine-id
|
||||
file:
|
||||
path: /var/lib/dbus/machine-id
|
||||
state: absent
|
||||
|
||||
- name: generate new machine-id
|
||||
command: systemd-machine-id-setup
|
||||
|
||||
- name: Cleaning the shell history
|
||||
shell: |
|
||||
unset HISTFILE
|
||||
history -cw
|
||||
echo > ~/.bash_history
|
||||
rm -fr /root/.bash_history
|
||||
10
ansible/roles/clean/tasks/main.yml
Normal file
10
ansible/roles/clean/tasks/main.yml
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
- name: "Clean the {{ ansible_facts['distribution'] }} guest operating system."
|
||||
include_tasks: "{{ ansible_facts['distribution'] | lower }}.yml"
|
||||
when: "ansible_facts['distribution'] == 'Debian'"
|
||||
- name: "Clean the {{ ansible_facts['distribution'] }} guest operating system."
|
||||
include_tasks: "{{ ansible_facts['distribution'] | lower }}.yml"
|
||||
when: "ansible_facts['distribution'] == 'Ubuntu'"
|
||||
- name: "Clean the {{ ansible_facts['distribution'] }} guest operating system."
|
||||
include_tasks: redhat.yml
|
||||
when: "ansible_facts['distribution'] in ['RedHat', 'CentOS', 'Rocky', 'AlmaLinux', 'OracleLinux']"
|
||||
59
ansible/roles/clean/tasks/redhat.yml
Normal file
59
ansible/roles/clean/tasks/redhat.yml
Normal file
@@ -0,0 +1,59 @@
|
||||
---
|
||||
|
||||
- name: "Cleaning all audit logs."
|
||||
shell: |
|
||||
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
|
||||
|
||||
- name: "Cleaning persistent udev rules."
|
||||
shell: |
|
||||
if [ -f /etc/udev/rules.d/70-persistent-net.rules ]; then
|
||||
rm /etc/udev/rules.d/70-persistent-net.rules
|
||||
fi
|
||||
|
||||
- name: "Cleaning the /tmp directories"
|
||||
shell: |
|
||||
rm -rf /tmp/*
|
||||
rm -rf /var/tmp/*
|
||||
rm -rf /var/cache/dnf/*
|
||||
|
||||
- name: "Cleaning the Red Hat Subscription Manager logs."
|
||||
shell: |
|
||||
rm -rf /var/log/rhsm/*
|
||||
when: "ansible_facts['distribution'] == 'RedHat'"
|
||||
|
||||
- name: "Cleaning the SSH host keys."
|
||||
shell: |
|
||||
rm -f /etc/ssh/ssh_host_*
|
||||
|
||||
- name: "Cleaning the machine-id."
|
||||
when: 'ansible_facts[''distribution_major_version''] <= "8"'
|
||||
shell: |
|
||||
truncate -s 0 /etc/machine-id
|
||||
rm /var/lib/dbus/machine-id
|
||||
ln -s /etc/machine-id /var/lib/dbus/machine-id
|
||||
|
||||
- name: "Cleaning the machine-id."
|
||||
when: 'ansible_facts[''distribution_major_version''] >= "9"'
|
||||
shell: |
|
||||
truncate -s 0 /etc/machine-id
|
||||
|
||||
- name: "Cleaning the shell history."
|
||||
shell: |
|
||||
unset HISTFILE
|
||||
history -cw
|
||||
echo > ~/.bash_history
|
||||
rm -fr /root/.bash_history
|
||||
|
||||
- name: "Running a sync."
|
||||
shell: |
|
||||
sync && sync
|
||||
|
||||
...
|
||||
93
ansible/roles/clean/tasks/ubuntu.yml
Normal file
93
ansible/roles/clean/tasks/ubuntu.yml
Normal file
@@ -0,0 +1,93 @@
|
||||
---
|
||||
|
||||
- name: Remove audit log files
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
loop:
|
||||
- "/var/log/audit/audit.log"
|
||||
- "/var/log/wtmp"
|
||||
- "/var/log/lastlog"
|
||||
|
||||
- name: Check to see if the /var/log/audit directory exists
|
||||
ansible.builtin.stat:
|
||||
path: "/var/log/audit"
|
||||
register: audit_directory
|
||||
|
||||
- name: Ensure /var/log/audit directory exists
|
||||
ansible.builtin.file:
|
||||
path: /var/log/audit
|
||||
state: directory
|
||||
mode: "0750"
|
||||
owner: root
|
||||
group: adm
|
||||
when: audit_directory.stat.exists
|
||||
|
||||
- name: Ensure /var/log/audit/audit.log exists
|
||||
ansible.builtin.file:
|
||||
path: /var/log/audit/audit.log
|
||||
state: touch
|
||||
mode: "0640"
|
||||
owner: root
|
||||
group: adm
|
||||
when: audit_directory.stat.exists
|
||||
|
||||
- name: Ensure wtmp and lastlog exist with the correct permissions
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ item }}"
|
||||
content: ""
|
||||
mode: "0664"
|
||||
owner: root
|
||||
group: utmp
|
||||
loop:
|
||||
- "/var/log/wtmp"
|
||||
- "/var/log/lastlog"
|
||||
|
||||
- name: Cleaning persistent udev rules
|
||||
ansible.builtin.file:
|
||||
path: /etc/udev/rules.d/70-persistent-net.rules
|
||||
state: absent
|
||||
|
||||
- name: "Cleaning the /tmp directories"
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
loop:
|
||||
- "/tmp/*"
|
||||
- "/var/tmp/*"
|
||||
|
||||
- name: Cleaning the SSH host keys
|
||||
shell: |
|
||||
rm -f /etc/ssh/ssh_host_*
|
||||
|
||||
- name: remove /etc/machine-id
|
||||
file:
|
||||
path: /etc/machine-id
|
||||
state: absent
|
||||
|
||||
- name: remove /var/lib/dbus/machine-id
|
||||
file:
|
||||
path: /var/lib/dbus/machine-id
|
||||
state: absent
|
||||
|
||||
- name: generate new machine-id
|
||||
command: systemd-machine-id-setup
|
||||
|
||||
- name: Clean apt
|
||||
ansible.builtin.apt:
|
||||
autoclean: yes
|
||||
autoremove: yes
|
||||
clean: yes
|
||||
|
||||
- name: Cleaning the shell history
|
||||
shell: |
|
||||
unset HISTFILE
|
||||
history -cw
|
||||
echo > ~/.bash_history
|
||||
rm -fr /root/.bash_history
|
||||
|
||||
- name: Clean cloud-init
|
||||
ansible.builtin.command: cloud-init clean
|
||||
when: cloud_init | bool
|
||||
|
||||
...
|
||||
37
ansible/roles/configure/tasks/debian.yml
Normal file
37
ansible/roles/configure/tasks/debian.yml
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
- name: "Configure SSH for Public Key Authentication."
|
||||
shell: |
|
||||
sudo sed -i 's/.*PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config
|
||||
|
||||
- name: Creating SSH key regeneration service file
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/systemd/system/regenerate_ssh_host_keys.service
|
||||
content: |
|
||||
[Unit]
|
||||
Description=Regenerate SSH host keys
|
||||
Before=ssh.service
|
||||
ConditionFileIsExecutable=/usr/bin/ssh-keygen
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStartPre=-/bin/dd if=/dev/hwrng of=/dev/urandom count=1 bs=4096
|
||||
ExecStartPre=-/bin/sh -c "/bin/rm -f -v /etc/ssh/ssh_host_*_key*"
|
||||
ExecStart=/usr/bin/ssh-keygen -A -v
|
||||
ExecStartPost=/bin/systemctl disable regenerate_ssh_host_keys
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
when: not cloud_init | bool
|
||||
|
||||
- name: Reload systemd to re-read configurations
|
||||
ansible.builtin.systemd:
|
||||
daemon-reload: true
|
||||
when: not cloud_init | bool
|
||||
|
||||
- name: Enable regenerate_ssh_host_keys service
|
||||
ansible.builtin.systemd:
|
||||
name: regenerate_ssh_host_keys
|
||||
enabled: true
|
||||
when: not cloud_init | bool
|
||||
|
||||
...
|
||||
10
ansible/roles/configure/tasks/main.yml
Normal file
10
ansible/roles/configure/tasks/main.yml
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
- name: "Configure the {{ ansible_facts['distribution'] }} guest operating system."
|
||||
include_tasks: "{{ ansible_facts['distribution'] | lower }}.yml"
|
||||
when: "ansible_facts['distribution'] == 'Debian'"
|
||||
- name: "Configure the {{ ansible_facts['distribution'] }} guest operating system."
|
||||
include_tasks: "{{ ansible_facts['distribution'] | lower }}.yml"
|
||||
when: "ansible_facts['distribution'] == 'Ubuntu'"
|
||||
- name: "Configure the {{ ansible_facts['distribution'] }} guest operating system."
|
||||
include_tasks: redhat.yml
|
||||
when: "ansible_facts['distribution'] in ['RedHat', 'CentOS', 'Rocky', 'AlmaLinux', 'OracleLinux']"
|
||||
5
ansible/roles/configure/tasks/redhat.yml
Normal file
5
ansible/roles/configure/tasks/redhat.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
- name: "Configure SSH for Public Key Authentication."
|
||||
shell: |
|
||||
sudo sed -i 's/.*PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
|
||||
sudo sed -i 's/.*PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config
|
||||
87
ansible/roles/configure/tasks/ubuntu.yml
Normal file
87
ansible/roles/configure/tasks/ubuntu.yml
Normal file
@@ -0,0 +1,87 @@
|
||||
---
|
||||
- name: "Configure SSH for Public Key Authentication"
|
||||
shell: |
|
||||
sudo sed -i 's/.*PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config
|
||||
- name: "Restarting the SSH daemon."
|
||||
shell: |
|
||||
sudo systemctl restart sshd
|
||||
|
||||
- name: Remove cloud-init files
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
loop:
|
||||
- /etc/cloud/cloud.cfg.d/subiquity-disable-cloudinit-networking.cfg
|
||||
- /etc/cloud/cloud.cfg.d/50-curtin-networking.cfg
|
||||
- /etc/cloud/cloud.cfg.d/curtin-preserve-sources.cfg
|
||||
- /etc/cloud/cloud.cfg.d/99-installer.cfg
|
||||
- /etc/netplan/00-installer-config.yaml
|
||||
when:
|
||||
- cloud_init | bool
|
||||
- ansible_distribution_version == "20.04" or ansible_distribution_version == "22.04"
|
||||
|
||||
- name: Disable cloud-init if configured to
|
||||
block:
|
||||
- name: Check if /etc/cloud/ exists
|
||||
ansible.builtin.stat:
|
||||
path: '/etc/cloud/'
|
||||
register: etc_cloud_folder
|
||||
|
||||
- name: 'Generate /etc/cloud/cloud-init.disabled'
|
||||
ansible.builtin.copy:
|
||||
dest: '/etc/cloud/cloud-init.disabled'
|
||||
content: 'disabled by ansible\n'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0644'
|
||||
when:
|
||||
- 'etc_cloud_folder.stat.exists'
|
||||
when:
|
||||
- not cloud_init | bool
|
||||
- ansible_distribution_version == "20.04" or ansible_distribution_version == "22.04"
|
||||
|
||||
- name: Copy cloud-init PVE default file
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/cloud/cloud.cfg.d/90_dpkg.cfg
|
||||
content: |
|
||||
datasource_list: [ ConfigDrive, NoCloud ]
|
||||
when: cloud_init | bool
|
||||
|
||||
- name: "Modifying GRUB."
|
||||
shell: |
|
||||
sed -i -e "s/GRUB_CMDLINE_LINUX_DEFAULT=\"\(.*\)\"/GRUB_CMDLINE_LINUX_DEFAULT=\"\"/" /etc/default/grub
|
||||
update-grub
|
||||
when: ansible_distribution_version == "20.04" or ansible_distribution_version == "22.04"
|
||||
|
||||
- name: Creating SSH key regeneration service file
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/systemd/system/regenerate_ssh_host_keys.service
|
||||
content: |
|
||||
[Unit]
|
||||
Description=Regenerate SSH host keys
|
||||
Before=ssh.service
|
||||
ConditionFileIsExecutable=/usr/bin/ssh-keygen
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStartPre=-/bin/dd if=/dev/hwrng of=/dev/urandom count=1 bs=4096
|
||||
ExecStartPre=-/bin/sh -c "/bin/rm -f -v /etc/ssh/ssh_host_*_key*"
|
||||
ExecStart=/usr/bin/ssh-keygen -A -v
|
||||
ExecStartPost=/bin/systemctl disable regenerate_ssh_host_keys
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
when: not cloud_init | bool
|
||||
|
||||
- name: Reload systemd to re-read configurations
|
||||
ansible.builtin.systemd:
|
||||
daemon-reload: true
|
||||
when: not cloud_init | bool
|
||||
|
||||
- name: Enable regenerate_ssh_host_keys service
|
||||
ansible.builtin.systemd:
|
||||
name: regenerate_ssh_host_keys
|
||||
enabled: true
|
||||
when: not cloud_init | bool
|
||||
|
||||
...
|
||||
31
ansible/roles/users/tasks/linux.yml
Normal file
31
ansible/roles/users/tasks/linux.yml
Normal file
@@ -0,0 +1,31 @@
|
||||
---
|
||||
- name: "Adding authorized_keys for the default local user."
|
||||
shell: |
|
||||
sudo mkdir -p /home/{{BUILD_USERNAME}}/.ssh
|
||||
sudo tee /home/{{BUILD_USERNAME}}/.ssh/authorized_keys << EOF
|
||||
{{BUILD_SECRET}}
|
||||
EOF
|
||||
sudo chown -R {{BUILD_USERNAME}} /home/{{BUILD_USERNAME}}/.ssh
|
||||
sudo chmod 700 /home/{{BUILD_USERNAME}}/.ssh
|
||||
sudo chmod 644 /home/{{BUILD_USERNAME}}/.ssh/authorized_keys
|
||||
- name: "Adding the default local user to passwordless sudoers."
|
||||
shell: |
|
||||
sudo bash -c "echo \"""{{BUILD_USERNAME}}"" ALL=(ALL) NOPASSWD:ALL\" >> /etc/sudoers"
|
||||
- name: "Creating a local user for Ansible."
|
||||
shell: |
|
||||
sudo groupadd {{ANSIBLE_USERNAME}}
|
||||
sudo useradd -g {{ANSIBLE_USERNAME}} -m -s /bin/bash {{ANSIBLE_USERNAME}}
|
||||
sudo usermod -aG sudo {{ANSIBLE_USERNAME}}
|
||||
echo {{ANSIBLE_USERNAME}}:"$(openssl rand -base64 14)" | sudo chpasswd
|
||||
- name: "Adding authorized_keys to the local user for Ansible."
|
||||
shell: |
|
||||
sudo mkdir -p /home/{{ANSIBLE_USERNAME}}/.ssh
|
||||
sudo tee /home/{{ANSIBLE_USERNAME}}/.ssh/authorized_keys << EOF
|
||||
{{ANSIBLE_SECRET}}
|
||||
EOF
|
||||
sudo chown -R {{ANSIBLE_USERNAME}} /home/{{ANSIBLE_USERNAME}}/.ssh
|
||||
sudo chmod 700 /home/{{ANSIBLE_USERNAME}}/.ssh
|
||||
sudo chmod 644 /home/{{ANSIBLE_USERNAME}}/.ssh/authorized_keys
|
||||
- name: "Adding the local user for Ansible to passwordless sudoers."
|
||||
shell: |
|
||||
sudo bash -c "echo \"""{{ANSIBLE_USERNAME}}"" ALL=(ALL) NOPASSWD:ALL\" >> /etc/sudoers"
|
||||
10
ansible/roles/users/tasks/main.yml
Normal file
10
ansible/roles/users/tasks/main.yml
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
- name: "Configure users on {{ ansible_facts['distribution'] }} guest operating system."
|
||||
include_tasks: linux.yml
|
||||
when: "ansible_facts['distribution'] == 'Debian'"
|
||||
- name: "Configure users on {{ ansible_facts['distribution'] }} guest operating system."
|
||||
include_tasks: linux.yml
|
||||
when: "ansible_facts['distribution'] == 'Ubuntu'"
|
||||
- name: "Configure users on {{ ansible_facts['distribution'] }} guest operating system."
|
||||
include_tasks: linux.yml
|
||||
when: "ansible_facts['distribution'] in ['RedHat', 'CentOS', 'Rocky', 'AlmaLinux', 'OracleLinux']"
|
||||
189
build.sh
Executable file
189
build.sh
Executable file
@@ -0,0 +1,189 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
source common.sh
|
||||
|
||||
SCRIPT_PATH=$(realpath "$(dirname "$(follow_link "$0")")")
|
||||
CONFIG_PATH=$(realpath "${1:-${SCRIPT_PATH}/config}")
|
||||
|
||||
menu_option_1() {
|
||||
INPUT_PATH="$SCRIPT_PATH"/builds/linux/ubuntu/22-04-lts/
|
||||
echo -e "\nCONFIRM: Build a Ubuntu Server 22.04 LTS Template for Proxmox?"
|
||||
echo -e "\nContinue? (y/n)"
|
||||
read -r REPLY
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
### Build a Ubuntu Server 22.04 LTS Template for Proxmox. ###
|
||||
echo "Building a Ubuntu Server 22.04 LTS Template for Proxmox..."
|
||||
|
||||
### Initialize HashiCorp Packer and required plugins. ###
|
||||
echo "Initializing HashiCorp Packer and required plugins..."
|
||||
packer init "$INPUT_PATH"
|
||||
|
||||
### Start the Build. ###
|
||||
echo "Starting the build...."
|
||||
packer build -force \
|
||||
-var-file="$CONFIG_PATH/proxmox.pkrvars.hcl" \
|
||||
-var-file="$CONFIG_PATH/build.pkrvars.hcl" \
|
||||
-var-file="$CONFIG_PATH/ansible.pkrvars.hcl" \
|
||||
-var-file="$CONFIG_PATH/common.pkrvars.hcl" \
|
||||
-var-file="$CONFIG_PATH/linux-storage.pkrvars.hcl" \
|
||||
"$INPUT_PATH"
|
||||
|
||||
### All done. ###
|
||||
echo "Done."
|
||||
}
|
||||
|
||||
menu_option_2() {
|
||||
INPUT_PATH="$SCRIPT_PATH"/builds/linux/ubuntu/22-04-lts/
|
||||
echo -e "\nCONFIRM: Build a Ubuntu Server 22.04 LTS (cloud-init) Template for Proxmox?"
|
||||
echo -e "\nContinue? (y/n)"
|
||||
read -r REPLY
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
### Build a Ubuntu Server 22.04 LTS Template for Proxmox. ###
|
||||
echo "Building a Ubuntu Server 22.04 LTS (cloud-init) Template for Proxmox..."
|
||||
|
||||
### Initialize HashiCorp Packer and required plugins. ###
|
||||
echo "Initializing HashiCorp Packer and required plugins..."
|
||||
packer init "$INPUT_PATH"
|
||||
|
||||
### Start the Build. ###
|
||||
echo "Starting the build...."
|
||||
packer build -force \
|
||||
-var-file="$CONFIG_PATH/proxmox.pkrvars.hcl" \
|
||||
-var-file="$CONFIG_PATH/build.pkrvars.hcl" \
|
||||
-var-file="$CONFIG_PATH/ansible.pkrvars.hcl" \
|
||||
-var-file="$CONFIG_PATH/common.pkrvars.hcl" \
|
||||
-var-file="$CONFIG_PATH/linux-storage.pkrvars.hcl" \
|
||||
-var "vm_cloud_init_enable=true" \
|
||||
"$INPUT_PATH"
|
||||
|
||||
### All done. ###
|
||||
echo "Done."
|
||||
}
|
||||
|
||||
menu_option_3() {
|
||||
INPUT_PATH="$SCRIPT_PATH"/builds/linux/ubuntu/20-04-lts/
|
||||
echo -e "\nCONFIRM: Build a Ubuntu Server 20.04 LTS Template for Proxmox?"
|
||||
echo -e "\nContinue? (y/n)"
|
||||
read -r REPLY
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
### Build a Ubuntu Server 20.04 LTS Template for Proxmox. ###
|
||||
echo "Building a Ubuntu Server 20.04 LTS Template for Proxmox..."
|
||||
|
||||
### Initialize HashiCorp Packer and required plugins. ###
|
||||
echo "Initializing HashiCorp Packer and required plugins..."
|
||||
packer init "$INPUT_PATH"
|
||||
|
||||
### Start the Build. ###
|
||||
echo "Starting the build...."
|
||||
packer build -force \
|
||||
-var-file="$CONFIG_PATH/proxmox.pkrvars.hcl" \
|
||||
-var-file="$CONFIG_PATH/build.pkrvars.hcl" \
|
||||
-var-file="$CONFIG_PATH/ansible.pkrvars.hcl" \
|
||||
-var-file="$CONFIG_PATH/common.pkrvars.hcl" \
|
||||
-var-file="$CONFIG_PATH/linux-storage.pkrvars.hcl" \
|
||||
"$INPUT_PATH"
|
||||
|
||||
### All done. ###
|
||||
echo "Done."
|
||||
}
|
||||
|
||||
menu_option_4() {
|
||||
INPUT_PATH="$SCRIPT_PATH"/builds/linux/ubuntu/20-04-lts/
|
||||
echo -e "\nCONFIRM: Build a Ubuntu Server 20.04 LTS (cloud-init) Template for Proxmox?"
|
||||
echo -e "\nContinue? (y/n)"
|
||||
read -r REPLY
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
### Build a Ubuntu Server 20.04 LTS Template for Proxmox. ###
|
||||
echo "Building a Ubuntu Server 20.04 LTS (cloud-init) Template for Proxmox..."
|
||||
|
||||
### Initialize HashiCorp Packer and required plugins. ###
|
||||
echo "Initializing HashiCorp Packer and required plugins..."
|
||||
packer init "$INPUT_PATH"
|
||||
|
||||
### Start the Build. ###
|
||||
echo "Starting the build...."
|
||||
packer build -force \
|
||||
-var-file="$CONFIG_PATH/proxmox.pkrvars.hcl" \
|
||||
-var-file="$CONFIG_PATH/build.pkrvars.hcl" \
|
||||
-var-file="$CONFIG_PATH/ansible.pkrvars.hcl" \
|
||||
-var-file="$CONFIG_PATH/common.pkrvars.hcl" \
|
||||
-var-file="$CONFIG_PATH/linux-storage.pkrvars.hcl" \
|
||||
-var "vm_cloud_init_enable=true" \
|
||||
"$INPUT_PATH"
|
||||
|
||||
### All done. ###
|
||||
echo "Done."
|
||||
}
|
||||
|
||||
press_enter() {
|
||||
cd "$SCRIPT_PATH"
|
||||
echo -n "Press Enter to continue."
|
||||
read -r
|
||||
clear
|
||||
}
|
||||
|
||||
info() {
|
||||
echo "License: BSD-2"
|
||||
echo ""
|
||||
echo "For more information, review the project README."
|
||||
read -r
|
||||
}
|
||||
|
||||
incorrect_selection() {
|
||||
echo "Invalid selection, please try again."
|
||||
}
|
||||
|
||||
until [ "$selection" = "0" ]; do
|
||||
clear
|
||||
echo ""
|
||||
echo " ____ __ ____ "
|
||||
echo " / __ \ ____ _ _____ / /__ ___ _____ / __ \ _____ ____ _ __ ____ ___ ____ _ __ "
|
||||
echo ' / /_/ // __ `// ___// //_// _ \ / ___/ / /_/ // ___// __ \ | |/_// __ `__ \ / __ \ | |/_/ '
|
||||
echo " / ____// /_/ // /__ / ,< / __// / / ____// / / /_/ /_> < / / / / / // /_/ /_> < "
|
||||
echo '/_/ \__,_/ \___//_/|_| \___//_/ /_/ /_/ \____//_/|_|/_/ /_/ /_/ \____//_/|_| '
|
||||
echo ""
|
||||
echo -n " Select a HashiCorp Packer build for your hypervisor:"
|
||||
echo ""
|
||||
echo ""
|
||||
echo " Linux Distribution:"
|
||||
echo ""
|
||||
echo " 1 - Ubuntu Server 22.04 LTS"
|
||||
echo " 2 - Ubuntu Server 22.04 LTS (cloud-init)"
|
||||
echo " 3 - Ubuntu Server 20.04 LTS"
|
||||
echo " 4 - Ubuntu Server 20.04 LTS (cloud-init)"
|
||||
echo ""
|
||||
echo " Other:"
|
||||
echo ""
|
||||
echo " I - Information"
|
||||
echo " Q - Quit"
|
||||
echo ""
|
||||
read -r selection
|
||||
echo ""
|
||||
case $selection in
|
||||
1 ) clear ; menu_option_1 ; press_enter ;;
|
||||
2 ) clear ; menu_option_2 ; press_enter ;;
|
||||
3 ) clear ; menu_option_3 ; press_enter ;;
|
||||
4 ) clear ; menu_option_4 ; press_enter ;;
|
||||
[Ii] ) clear ; info ; press_enter ;;
|
||||
[Qq] ) clear ; exit ;;
|
||||
* ) clear ; incorrect_selection ; press_enter ;;
|
||||
esac
|
||||
done
|
||||
9
builds/ansible.pkrvars.hcl.example
Normal file
9
builds/ansible.pkrvars.hcl.example
Normal file
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Ansible credential variables used for Linux builds.
|
||||
- Variables are passed to and used by configuration scripts.
|
||||
*/
|
||||
|
||||
// Ansible Credentials
|
||||
ansible_username = "ansible"
|
||||
ansible_key = "<SSH public key for Ansible user goes here>"
|
||||
12
builds/build.pkrvars.hcl.example
Normal file
12
builds/build.pkrvars.hcl.example
Normal file
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Build account variables used for all builds.
|
||||
- Variables are passed to and used by guest operating system configuration files (e.g., ks.cfg, autounattend.xml).
|
||||
- Variables are passed to and used by configuration scripts.
|
||||
*/
|
||||
|
||||
// Default Account Credentials
|
||||
build_username = "ubuntu"
|
||||
build_password = "ubuntu"
|
||||
build_password_encrypted = "$6$Gg0b6uacy6apqKTP$OIvG1n8YUNpiDpsQgS02PgGgGY0egsYM0lqQq1lvOLKCAhMQcrY6SXq2K6ynt6RI8GVvmiagbKkcN6YXRzQtb1"
|
||||
build_key = "Your public SSH key goes here"
|
||||
19
builds/common.pkrvars.hcl.example
Normal file
19
builds/common.pkrvars.hcl.example
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Common variables used for all builds.
|
||||
- Variables are use by the source blocks.
|
||||
*/
|
||||
|
||||
// Removable Media Settings
|
||||
common_iso_storage = "OS"
|
||||
|
||||
// Boot and Provisioning Settings
|
||||
common_data_source = "http"
|
||||
common_http_ip = null
|
||||
common_http_port_min = 8000
|
||||
common_http_port_max = 8099
|
||||
common_ip_wait_timeout = "20m"
|
||||
common_shutdown_timeout = "15m"
|
||||
|
||||
// HCP Packer
|
||||
common_hcp_packer_registry_enabled = false
|
||||
169
builds/linux-storage.pkrvars.hcl.example
Normal file
169
builds/linux-storage.pkrvars.hcl.example
Normal file
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Storage variables used for Linux builds.
|
||||
- Variables are passed to and used by guest operating system configuration files (e.g., ks.cfg).
|
||||
*/
|
||||
|
||||
vm_efi_storage_pool = "vm-data"
|
||||
vm_efi_type = "4m"
|
||||
vm_efi_pre_enrolled_keys = false
|
||||
|
||||
// VM Storage Settings
|
||||
vm_disk_device = "vda"
|
||||
vm_disk_use_swap = true
|
||||
vm_disk_partitions = [
|
||||
{
|
||||
name = "efi"
|
||||
size = 1024,
|
||||
format = {
|
||||
label = "EFIFS",
|
||||
fstype = "fat32",
|
||||
},
|
||||
mount = {
|
||||
path = "/boot/efi",
|
||||
options = "",
|
||||
},
|
||||
volume_group = "",
|
||||
},
|
||||
{
|
||||
name = "boot"
|
||||
size = 1024,
|
||||
format = {
|
||||
label = "BOOTFS",
|
||||
fstype = "ext4",
|
||||
},
|
||||
mount = {
|
||||
path = "/boot",
|
||||
options = "",
|
||||
},
|
||||
volume_group = "",
|
||||
},
|
||||
{
|
||||
name = "vg_root"
|
||||
size = -1,
|
||||
format = {
|
||||
label = "",
|
||||
fstype = "",
|
||||
},
|
||||
mount = {
|
||||
path = "",
|
||||
options = "",
|
||||
},
|
||||
volume_group = "vg_root",
|
||||
},
|
||||
]
|
||||
vm_disk_lvm = [
|
||||
{
|
||||
name: "vg_root",
|
||||
partitions: [
|
||||
{
|
||||
name = "lv_swap",
|
||||
size = 1024,
|
||||
format = {
|
||||
label = "SWAPFS",
|
||||
fstype = "swap",
|
||||
},
|
||||
mount = {
|
||||
path = "",
|
||||
options = "",
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "lv_root",
|
||||
size = 3000,
|
||||
format = {
|
||||
label = "ROOTFS",
|
||||
fstype = "ext4",
|
||||
},
|
||||
mount = {
|
||||
path = "/",
|
||||
options = "",
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "lv_home",
|
||||
size = 1200,
|
||||
format = {
|
||||
label = "HOMEFS",
|
||||
fstype = "ext4",
|
||||
},
|
||||
mount = {
|
||||
path = "/home",
|
||||
options = "nodev,nosuid",
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "lv_opt",
|
||||
size = 2048,
|
||||
format = {
|
||||
label = "OPTFS",
|
||||
fstype = "ext4",
|
||||
},
|
||||
mount = {
|
||||
path = "/opt",
|
||||
options = "nodev",
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "lv_tmp",
|
||||
size = 2500,
|
||||
format = {
|
||||
label = "TMPFS",
|
||||
fstype = "ext4",
|
||||
},
|
||||
mount = {
|
||||
path = "/tmp",
|
||||
options = "nodev,noexec,nosuid",
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "lv_var",
|
||||
size = 3072,
|
||||
format = {
|
||||
label = "VARFS",
|
||||
fstype = "ext4",
|
||||
},
|
||||
mount = {
|
||||
path = "/var",
|
||||
options = "nodev",
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "lv_var_tmp",
|
||||
size = 4096,
|
||||
format = {
|
||||
label = "VARTMPFS",
|
||||
fstype = "ext4",
|
||||
},
|
||||
mount = {
|
||||
path = "/var/tmp",
|
||||
options = "nodev,noexec,nosuid",
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "lv_var_log",
|
||||
size = 1024,
|
||||
format = {
|
||||
label = "VARLOGFS",
|
||||
fstype = "ext4",
|
||||
},
|
||||
mount = {
|
||||
path = "/var/log",
|
||||
options = "nodev,noexec,nosuid",
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "lv_var_audit",
|
||||
size = 500,
|
||||
format = {
|
||||
label = "AUDITFS",
|
||||
fstype = "ext4",
|
||||
},
|
||||
mount = {
|
||||
path = "/var/log/audit",
|
||||
options = "nodev,noexec,nosuid",
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
]
|
||||
84
builds/linux/centos/8-stream/data/ks.pkrtpl.hcl
Normal file
84
builds/linux/centos/8-stream/data/ks.pkrtpl.hcl
Normal file
@@ -0,0 +1,84 @@
|
||||
# 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.
|
||||
|
||||
# CentOS Stream 8
|
||||
|
||||
### 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_os_language}
|
||||
|
||||
### Sets the default keyboard type for the system.
|
||||
keyboard ${vm_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
|
||||
|
||||
### Lock the root account.
|
||||
rootpw --lock
|
||||
|
||||
### 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_os_timezone}
|
||||
|
||||
### Partitioning
|
||||
${storage}
|
||||
|
||||
### 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
|
||||
|
||||
### Packages selection.
|
||||
%packages --ignoremissing --excludedocs
|
||||
@core
|
||||
-iwl*firmware
|
||||
%end
|
||||
|
||||
### Post-installation commands.
|
||||
%post
|
||||
dnf makecache
|
||||
dnf install epel-release -y
|
||||
dnf makecache
|
||||
dnf install -y sudo qemu-guest-tools
|
||||
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
|
||||
66
builds/linux/centos/8-stream/data/storage.pkrtpl.hcl
Normal file
66
builds/linux/centos/8-stream/data/storage.pkrtpl.hcl
Normal file
@@ -0,0 +1,66 @@
|
||||
### 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.
|
||||
### --all Erases all partitions from the system
|
||||
### --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.
|
||||
%{~ if length(partitions) == 1 && partitions[0].name == "autopart" ~}
|
||||
%{~ if partitions[0].format.fstype == "lvm" ~}
|
||||
autopart --type=lvm
|
||||
%{ endif }
|
||||
%{~ if partitions[0].format.fstype == "simple" ~}
|
||||
autopart --type=plain
|
||||
%{ endif }
|
||||
%{~ if partitions[0].format.fstype == "" ~}
|
||||
autopart --type=plain
|
||||
%{ endif }
|
||||
%{ else }
|
||||
%{~ for partition in partitions ~}
|
||||
%{~ if partition.format.fstype == "swap" ~}
|
||||
part swap --size=${partition.size}
|
||||
|
||||
%{~ endif ~}
|
||||
%{~ if partition.mount.path == "/boot/efi" ~}
|
||||
part ${partition.mount.path} --fstype vfat --size=${partition.size} --label=${partition.format.label}
|
||||
|
||||
%{~ endif ~}
|
||||
%{~ if partition.mount.path != "" ~}
|
||||
part ${partition.mount.path} --fstype ${partition.format.fstype} --size=${partition.size} --label=${partition.format.label} %{~ if partition.mount.options != "" ~}--fsoptions="${partition.mount.options}"%{~ endif ~}
|
||||
|
||||
%{~ endif ~}
|
||||
%{~ if partition.volume_group != "" ~}
|
||||
%{~ if partition.size == -1 ~}
|
||||
part pv.${partition.volume_group} --size=100 --grow
|
||||
|
||||
%{~ else ~}
|
||||
part pv.${partition.volume_group} --size=${partition.size}
|
||||
|
||||
%{~ endif ~}
|
||||
### Create a logical volume management (LVM) group.
|
||||
### Modify logical volume sizes for the virtual machine hardware.
|
||||
%{~ for index, volume_group in lvm ~}
|
||||
%{~ if partition.volume_group != "" ~}
|
||||
volgroup ${volume_group.name} --pesize=4096 pv.${partition.volume_group}
|
||||
|
||||
%{~ endif ~}
|
||||
### Create logical volumes.
|
||||
%{~ for partition in volume_group.partitions ~}
|
||||
%{~ if partition.format.fstype == "swap" ~}
|
||||
logvol swap --fstype ${partition.format.fstype} --name=${partition.name} --vgname=${volume_group.name} --size=${partition.size} --label=${partition.format.label}
|
||||
%{~ else ~}
|
||||
logvol ${partition.mount.path} %{ if partition.format.fstype == "fat32" } --fstype vfat %{ else } --fstype ${partition.format.fstype} %{ endif } %{ if partition.size != -1 } --size=${partition.size} %{ else } --size=100 --grow %{ endif } --name=${partition.name} --vgname=${volume_group.name} --label=${partition.format.label} %{ if partition.mount.options != "" ~} --fsoptions="${partition.mount.options}" %{~ endif ~}
|
||||
|
||||
%{~ endif ~}
|
||||
%{~ endfor ~}
|
||||
%{~ endfor ~}
|
||||
%{~ endif ~}
|
||||
%{~ endfor ~}
|
||||
%{~ endif }
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Ubuntu Server 22.04 LTS variables used by the Packer Plugin for Proxmox (proxmox-iso).
|
||||
*/
|
||||
|
||||
// Guest Operating System Metadata
|
||||
vm_os_language = "en_US"
|
||||
vm_os_keyboard = "us"
|
||||
vm_os_timezone = "UTC"
|
||||
vm_os_family = "linux"
|
||||
vm_os_name = "centos-stream"
|
||||
vm_os_version = "8"
|
||||
|
||||
// Virtual Machine Guest Operating System Setting
|
||||
vm_os_type = "l26"
|
||||
|
||||
// Virtual Machine Hardware Settings
|
||||
vm_bios = "seabios"
|
||||
vm_cpu_count = 1
|
||||
vm_cpu_sockets = 1
|
||||
vm_cpu_type = "kvm64"
|
||||
vm_mem_size = 2048
|
||||
vm_disk_type = "virtio"
|
||||
vm_disk_size = "32G"
|
||||
vm_disk_format = "raw"
|
||||
vm_storage_pool = "vm-data"
|
||||
vm_disk_controller_type = "virtio-scsi-pci"
|
||||
vm_network_card_model = "virtio"
|
||||
vm_bridge_interface = "vmbr0"
|
||||
vm_vlan_tag = "102"
|
||||
|
||||
// Removable Media Settings
|
||||
iso_path = "iso"
|
||||
iso_file = "CentOS-Stream-8-x86_64-latest-dvd1.iso"
|
||||
iso_checksum = "file:http://centos.mirror.ndchost.com/8-stream/isos/x86_64/CHECKSUM"
|
||||
|
||||
// Boot Settings
|
||||
vm_boot = "order=virtio0;ide2;net0"
|
||||
vm_boot_wait = "10s"
|
||||
|
||||
// EFI Settings
|
||||
vm_firmware_path = "./OVMF.fd"
|
||||
vm_efi_storage_pool = "vm-data"
|
||||
vm_efi_pre_enrolled_keys = false
|
||||
vm_efi_type = "4m"
|
||||
197
builds/linux/centos/8-stream/linux-centos-stream.pkr.hcl
Normal file
197
builds/linux/centos/8-stream/linux-centos-stream.pkr.hcl
Normal file
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Debian 11 template using the Packer Builder for Proxmox (proxmox-iso).
|
||||
*/
|
||||
|
||||
// BLOCK: packer
|
||||
// The Packer configuration.
|
||||
|
||||
packer {
|
||||
required_version = ">= 1.9.1"
|
||||
required_plugins {
|
||||
ansible = {
|
||||
source = "github.com/hashicorp/ansible"
|
||||
version = "~> 1"
|
||||
}
|
||||
git = {
|
||||
version = ">= 0.4.2"
|
||||
source = "github.com/ethanmdavidson/git"
|
||||
}
|
||||
proxmox = {
|
||||
version = ">= 1.0.6"
|
||||
source = "github.com/hashicorp/proxmox"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BLOCK: data
|
||||
// Defines the data sources.
|
||||
|
||||
data "git-repository" "cwd" {}
|
||||
|
||||
// BLOCK: locals
|
||||
// Defines the local variables.
|
||||
|
||||
locals {
|
||||
build_by = "Built by: HashiCorp Packer ${packer.version}"
|
||||
build_date = formatdate("DD-MM-YYYY hh:mm ZZZ", "${timestamp()}" )
|
||||
build_version = data.git-repository.cwd.head
|
||||
build_description = "Version: ${local.build_version}\nBuilt on: ${local.build_date}\n${local.build_by}\nCloud-Init: ${var.vm_cloud_init_enable}"
|
||||
vm_disk_type = var.vm_disk_type == "virtio" ? "vda" : "sda"
|
||||
manifest_date = formatdate("YYYY-MM-DD hh:mm:ss", timestamp())
|
||||
manifest_path = "${path.cwd}/manifests/"
|
||||
manifest_output = "${local.manifest_path}${local.manifest_date}.json"
|
||||
data_source_content = {
|
||||
"/ks.cfg" = templatefile("${abspath(path.root)}/data/ks.pkrtpl.hcl", {
|
||||
build_username = var.build_username
|
||||
build_password = var.build_password
|
||||
build_password_encrypted = var.build_password_encrypted
|
||||
vm_disk_type = local.vm_disk_type
|
||||
vm_os_language = var.vm_os_language
|
||||
vm_os_keyboard = var.vm_os_keyboard
|
||||
vm_os_timezone = var.vm_os_timezone
|
||||
common_data_source = var.common_data_source
|
||||
# lvm needs to be here so late commands can access vg names
|
||||
lvm = var.vm_disk_lvm
|
||||
storage = templatefile("${abspath(path.root)}/data/storage.pkrtpl.hcl", {
|
||||
device = var.vm_disk_device
|
||||
swap = var.vm_disk_use_swap
|
||||
partitions = var.vm_disk_partitions
|
||||
lvm = var.vm_disk_lvm
|
||||
vm_bios = var.vm_bios
|
||||
})
|
||||
})
|
||||
}
|
||||
data_source_command = var.common_data_source == "http" ? "inst.ks=http://{{.HTTPIP}}:{{.HTTPPort}}/ks.cfg" : "inst.ks=/cdrom/ks.cfg"
|
||||
vm_name = "${var.vm_os_family}-${var.vm_os_name}-${var.vm_os_version}"
|
||||
vm_bios = var.vm_bios == "ovmf" ? var.vm_firmware_path : null
|
||||
}
|
||||
|
||||
// BLOCK: source
|
||||
// Defines the builder configuration blocks.
|
||||
|
||||
source "proxmox-iso" "linux-centos-stream" {
|
||||
|
||||
// Proxmox Connection Settings and Credentials
|
||||
proxmox_url = "https://${var.proxmox_hostname}:8006/api2/json"
|
||||
username = "${var.proxmox_api_token_id}"
|
||||
token = "${var.proxmox_api_token_secret}"
|
||||
insecure_skip_tls_verify = "${var.proxmox_insecure_connection}"
|
||||
|
||||
// Proxmox Settings
|
||||
node = "${var.proxmox_node}"
|
||||
|
||||
// Virtual Machine Settings
|
||||
vm_name = "${local.vm_name}"
|
||||
bios = "${var.vm_bios}"
|
||||
sockets = "${var.vm_cpu_sockets}"
|
||||
cores = "${var.vm_cpu_count}"
|
||||
cpu_type = "${var.vm_cpu_type}"
|
||||
memory = "${var.vm_mem_size}"
|
||||
os = "${var.vm_os_type}"
|
||||
scsi_controller = "${var.vm_disk_controller_type}"
|
||||
disks {
|
||||
disk_size = "${var.vm_disk_size}"
|
||||
type = "${var.vm_disk_type}"
|
||||
storage_pool = "${var.vm_storage_pool}"
|
||||
format = "${var.vm_disk_format}"
|
||||
}
|
||||
dynamic "efi_config" {
|
||||
for_each = var.vm_bios == "ovmf" ? [1] : []
|
||||
content {
|
||||
efi_storage_pool = var.vm_bios == "ovmf" ? var.vm_efi_storage_pool : null
|
||||
efi_type = var.vm_bios == "ovmf" ? var.vm_efi_type : null
|
||||
pre_enrolled_keys = var.vm_bios == "ovmf" ? var.vm_efi_pre_enrolled_keys : null
|
||||
}
|
||||
}
|
||||
unmount_iso = true
|
||||
ssh_username = "${var.build_username}"
|
||||
ssh_password = "${var.build_password}"
|
||||
ssh_timeout = "${var.timeout}"
|
||||
ssh_port = "22"
|
||||
iso_file = "${var.common_iso_storage}:${var.iso_path}/${var.iso_file}"
|
||||
iso_checksum = "${var.iso_checksum}"
|
||||
qemu_agent = true
|
||||
|
||||
network_adapters {
|
||||
bridge = "${var.vm_bridge_interface}"
|
||||
model = "${var.vm_network_card_model}"
|
||||
vlan_tag = "${var.vm_vlan_tag}"
|
||||
}
|
||||
|
||||
// Removable Media Settings
|
||||
http_content = "${var.common_data_source}" == "http" ? "${local.data_source_content}" : null
|
||||
|
||||
// Boot and Provisioning Settings
|
||||
http_bind_address = var.common_data_source == "http" ? var.common_http_bind_address : null
|
||||
http_port_min = var.common_data_source == "http" ? var.common_http_port_min : null
|
||||
http_port_max = var.common_data_source == "http" ? var.common_http_port_max : null
|
||||
boot = var.vm_boot
|
||||
boot_wait = var.vm_boot_wait
|
||||
boot_command = [
|
||||
"<up><wait>",
|
||||
"<tab><wait>",
|
||||
" text ${local.data_source_command}",
|
||||
"<enter><wait>"
|
||||
]
|
||||
|
||||
dynamic "additional_iso_files" {
|
||||
for_each = var.common_data_source == "disk" ? [1] : []
|
||||
content {
|
||||
cd_files = var.common_data_source == "disk" ? local.data_source_content : null
|
||||
cd_label = var.common_data_source == "disk" ? "cidata" : null
|
||||
iso_storage_pool = var.common_data_source == "disk" ? "local" : null
|
||||
}
|
||||
}
|
||||
|
||||
template_name = "${local.vm_name}"
|
||||
template_description = "${local.build_description}"
|
||||
|
||||
# VM Cloud Init Settings
|
||||
cloud_init = var.vm_cloud_init_enable
|
||||
cloud_init_storage_pool = var.vm_cloud_init_enable == true ? var.vm_storage_pool : null
|
||||
|
||||
}
|
||||
|
||||
# Build Definition to create the VM Template
|
||||
build {
|
||||
sources = ["source.proxmox-iso.linux-centos-stream"]
|
||||
|
||||
provisioner "ansible" {
|
||||
user = "${var.build_username}"
|
||||
playbook_file = "${path.cwd}/ansible/main.yml"
|
||||
roles_path = "${path.cwd}/ansible/roles"
|
||||
ansible_env_vars = [
|
||||
"ANSIBLE_CONFIG=${path.cwd}/ansible/ansible.cfg"
|
||||
]
|
||||
extra_arguments = [
|
||||
"--extra-vars", "display_skipped_hosts=false",
|
||||
"--extra-vars", "BUILD_USERNAME=${var.build_username}",
|
||||
"--extra-vars", "BUILD_SECRET='${var.build_key}'",
|
||||
"--extra-vars", "ANSIBLE_USERNAME=${var.ansible_username}",
|
||||
"--extra-vars", "ANSIBLE_SECRET='${var.ansible_key}'",
|
||||
"--extra-vars", "cloud_init='${var.vm_cloud_init_enable}'",
|
||||
]
|
||||
}
|
||||
|
||||
post-processor "manifest" {
|
||||
output = local.manifest_output
|
||||
strip_path = true
|
||||
strip_time = true
|
||||
custom_data = {
|
||||
ansible_username = "${var.ansible_username}"
|
||||
build_username = "${var.build_username}"
|
||||
build_date = "${local.build_date}"
|
||||
build_version = "${local.build_version}"
|
||||
common_data_source = "${var.common_data_source}"
|
||||
vm_cpu_sockets = "${var.vm_cpu_sockets}"
|
||||
vm_cpu_count = "${var.vm_cpu_count}"
|
||||
vm_disk_size = "${var.vm_disk_size}"
|
||||
vm_bios = "${var.vm_bios}"
|
||||
vm_os_type = "${var.vm_os_type}"
|
||||
vm_mem_size = "${var.vm_mem_size}"
|
||||
vm_network_card_model = "${var.vm_network_card_model}"
|
||||
vm_cloud_init_enable = "${var.vm_cloud_init_enable}"
|
||||
}
|
||||
}
|
||||
}
|
||||
53
builds/linux/centos/8-stream/variables-storage.pkr.hcl
Normal file
53
builds/linux/centos/8-stream/variables-storage.pkr.hcl
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Debian 11 storage variables used by the Packer Plugin for Proxmox (proxmox-iso).
|
||||
*/
|
||||
|
||||
// VM Storage Settings
|
||||
|
||||
variable "vm_disk_device" {
|
||||
type = string
|
||||
description = "The device for the virtual disk. (e.g. 'sda')"
|
||||
}
|
||||
|
||||
variable "vm_disk_use_swap" {
|
||||
type = bool
|
||||
description = "Whether to use a swap partition."
|
||||
}
|
||||
|
||||
variable "vm_disk_partitions" {
|
||||
type = list(object({
|
||||
name = string
|
||||
size = number
|
||||
format = object({
|
||||
label = string
|
||||
fstype = string
|
||||
})
|
||||
mount = object({
|
||||
path = string
|
||||
options = string
|
||||
})
|
||||
volume_group = string
|
||||
}))
|
||||
description = "The disk partitions for the virtual disk."
|
||||
}
|
||||
|
||||
variable "vm_disk_lvm" {
|
||||
type = list(object({
|
||||
name = string
|
||||
partitions = list(object({
|
||||
name = string
|
||||
size = number
|
||||
format = object({
|
||||
label = string
|
||||
fstype = string
|
||||
})
|
||||
mount = object({
|
||||
path = string
|
||||
options = string
|
||||
})
|
||||
}))
|
||||
}))
|
||||
description = "The LVM configuration for the virtual disk."
|
||||
default = []
|
||||
}
|
||||
297
builds/linux/centos/8-stream/variables.pkr.hcl
Normal file
297
builds/linux/centos/8-stream/variables.pkr.hcl
Normal file
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Debian 11 variables using the Packer Builder for Proxmox (proxmox-iso).
|
||||
*/
|
||||
|
||||
// BLOCK: variable
|
||||
// Defines the input variables.
|
||||
|
||||
// Proxmox Credentials
|
||||
|
||||
variable "proxmox_hostname" {
|
||||
type = string
|
||||
description = "The FQDN or IP address of a Proxmox node. Only one node should be specified in a cluster."
|
||||
}
|
||||
|
||||
variable "proxmox_api_token_id" {
|
||||
type = string
|
||||
description = "The token to login to the Proxmox node/cluster. The format is USER@REALM!TOKENID. (e.g. packer@pam!packer_pve_token)"
|
||||
}
|
||||
|
||||
variable "proxmox_api_token_secret" {
|
||||
type = string
|
||||
description = "The secret for the API token used to login to the Proxmox API."
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
variable "proxmox_insecure_connection" {
|
||||
description = "true/false to skip Proxmox TLS certificate checks."
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
// Proxmox Settings
|
||||
|
||||
variable "proxmox_node" {
|
||||
type = string
|
||||
description = "The name of the Proxmox node that Packer will build templates on."
|
||||
}
|
||||
|
||||
// Virtual Machine Settings
|
||||
|
||||
variable "vm_os_language" {
|
||||
type = string
|
||||
description = "The guest operating system language."
|
||||
default = "en_US"
|
||||
}
|
||||
|
||||
variable "vm_os_keyboard" {
|
||||
type = string
|
||||
description = "The guest operating system keyboard layout."
|
||||
default = "us"
|
||||
}
|
||||
|
||||
variable "vm_os_timezone" {
|
||||
type = string
|
||||
description = "The guest operating system timezone."
|
||||
default = "UTC"
|
||||
}
|
||||
|
||||
variable "vm_os_family" {
|
||||
type = string
|
||||
description = "The guest operating system family. Used for naming. (e.g. 'linux')"
|
||||
}
|
||||
|
||||
variable "vm_os_name" {
|
||||
type = string
|
||||
description = "The guest operating system name. Used for naming. (e.g. 'ubuntu')"
|
||||
}
|
||||
|
||||
variable "vm_os_version" {
|
||||
type = string
|
||||
description = "The guest operating system version. Used for naming. (e.g. '22-04-lts')"
|
||||
}
|
||||
|
||||
variable "vm_os_type" {
|
||||
type = string
|
||||
description = "The guest operating system type. (e.g. 'l26')"
|
||||
}
|
||||
|
||||
variable "vm_bios" {
|
||||
type = string
|
||||
description = "The firmware type. Allowed values 'ovmf' or 'seabios'"
|
||||
default = "OVMF"
|
||||
|
||||
validation {
|
||||
condition = contains(["ovmf", "seabios"], var.vm_bios)
|
||||
error_message = "The vm_bios value must be 'ovmf' or 'seabios'."
|
||||
}
|
||||
}
|
||||
|
||||
variable "vm_firmware_path" {
|
||||
type = string
|
||||
description = "The firmware file to be used. Needed for EFI"
|
||||
default = "/usr/share/ovmf/OVMF.fd"
|
||||
}
|
||||
|
||||
variable "vm_efi_storage_pool" {
|
||||
type = string
|
||||
description = "Set the UEFI disk storage location. (e.g. 'local-lvm')"
|
||||
}
|
||||
|
||||
variable "vm_efi_type" {
|
||||
type = string
|
||||
description = "Specifies the version of the OVMF firmware to be used. (e.g. '4m')"
|
||||
}
|
||||
|
||||
variable "vm_efi_pre_enrolled_keys" {
|
||||
type = bool
|
||||
description = "Whether Microsoft Standard Secure Boot keys should be pre-loaded on the EFI disk. (e.g. false)"
|
||||
}
|
||||
|
||||
variable "vm_cpu_count" {
|
||||
type = number
|
||||
description = "The number of virtual CPUs. (e.g. '2')"
|
||||
}
|
||||
|
||||
variable "vm_cpu_sockets" {
|
||||
type = number
|
||||
description = "The number of virtual CPU sockets. (e.g. '1')"
|
||||
}
|
||||
|
||||
variable "vm_cpu_type" {
|
||||
type = string
|
||||
description = "The CPU type to emulate. See the Proxmox API documentation for the complete list of accepted values. For best performance, set this to host. Defaults to kvm64."
|
||||
}
|
||||
|
||||
variable "vm_mem_size" {
|
||||
type = number
|
||||
description = "The size for the virtual memory in MB. (e.g. '2048')"
|
||||
}
|
||||
|
||||
variable "vm_disk_controller_type" {
|
||||
type = string
|
||||
description = "The SCSI controller model to emulate. (e.g. 'virtio-scsi-pci')"
|
||||
}
|
||||
|
||||
variable "vm_disk_type" {
|
||||
type = string
|
||||
description = "The type of disk to emulate. (e.g. 'virtio')"
|
||||
}
|
||||
|
||||
variable "vm_storage_pool" {
|
||||
type = string
|
||||
description = "The name of the Proxmox storage pool to store the VM template. (e.g. 'local-lvm')"
|
||||
}
|
||||
|
||||
variable "vm_disk_size" {
|
||||
type = string
|
||||
description = "The size for the virtual disk in GB. (e.g. '32G')"
|
||||
}
|
||||
|
||||
variable "vm_disk_format" {
|
||||
type = string
|
||||
description = "The format of the file backing the disk. (e.g. 'qcow2')"
|
||||
}
|
||||
|
||||
variable "vm_network_card_model" {
|
||||
type = string
|
||||
description = "The model of the virtual network adapter to emulate. (e.g. 'virtio')"
|
||||
}
|
||||
|
||||
variable "vm_bridge_interface" {
|
||||
type = string
|
||||
description = "The name of the Proxmox bridge to attach the adapter to."
|
||||
}
|
||||
|
||||
variable "vm_vlan_tag" {
|
||||
type = string
|
||||
description = "If the adapter should tag packets, give the VLAN ID. (e.g. '102')"
|
||||
}
|
||||
|
||||
// Cloud-Init Settings
|
||||
|
||||
variable "vm_cloud_init_enable" {
|
||||
type = bool
|
||||
description = "Enable or disable cloud-init drive in Proxmox. (e.g. false)"
|
||||
default = false
|
||||
}
|
||||
|
||||
// Removable Media Settings
|
||||
|
||||
variable "common_iso_storage" {
|
||||
type = string
|
||||
description = "The name of the source Proxmox storage location for ISO images. (e.g. 'local-lvm')"
|
||||
}
|
||||
|
||||
variable "iso_path" {
|
||||
type = string
|
||||
description = "The path on the source Proxmox storage location for ISO images. (e.g. 'iso')"
|
||||
}
|
||||
|
||||
variable "iso_file" {
|
||||
type = string
|
||||
description = "The file name of the ISO image used by the vendor. (e.g. 'ubuntu-<version>-live-server-amd64.iso')"
|
||||
}
|
||||
|
||||
variable "iso_checksum" {
|
||||
type = string
|
||||
description = "The checksum value of the ISO image provided by the vendor."
|
||||
}
|
||||
|
||||
// Boot Settings
|
||||
|
||||
variable "common_data_source" {
|
||||
type = string
|
||||
description = "The provisioning data source. (e.g. 'http' or 'disk')"
|
||||
}
|
||||
|
||||
variable "common_http_bind_address" {
|
||||
type = string
|
||||
description = "Define an IP address on the host to use for the HTTP server."
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "common_http_port_min" {
|
||||
type = number
|
||||
description = "The start of the HTTP port range."
|
||||
}
|
||||
|
||||
variable "common_http_port_max" {
|
||||
type = number
|
||||
description = "The end of the HTTP port range."
|
||||
}
|
||||
|
||||
variable "vm_boot" {
|
||||
type = string
|
||||
description = "The boot order for virtual machine devices. (e.g. 'order=virtio0;ide2;net0')"
|
||||
}
|
||||
|
||||
variable "vm_boot_wait" {
|
||||
type = string
|
||||
description = "The time to wait after booting the initial VM before typing the boot_command (e.g '10s')"
|
||||
}
|
||||
|
||||
variable "common_ip_wait_timeout" {
|
||||
type = string
|
||||
description = "Time to wait for guest operating system IP address response."
|
||||
}
|
||||
|
||||
variable "common_shutdown_timeout" {
|
||||
type = string
|
||||
description = "Time to wait for guest operating system shutdown."
|
||||
}
|
||||
|
||||
// Communicator Settings and Credentials
|
||||
|
||||
variable "build_username" {
|
||||
type = string
|
||||
description = "The username to login to the guest operating system. (e.g. 'ubuntu')"
|
||||
# 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 to the guest operating system."
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
variable "build_key" {
|
||||
type = string
|
||||
description = "The SSH public key to login to the guest operating system."
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
variable "timeout" {
|
||||
description = "not sure why I need so high a timeout but here we are"
|
||||
default = "90m"
|
||||
}
|
||||
|
||||
// Ansible Credentials
|
||||
|
||||
variable "ansible_username" {
|
||||
type = string
|
||||
description = "The username for Ansible to login to the guest operating system. (e.g. 'ansible')"
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
variable "ansible_key" {
|
||||
type = string
|
||||
description = "The public key for Ansible to login to the guest operating system."
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
// HCP Packer Settings
|
||||
|
||||
variable "common_hcp_packer_registry_enabled" {
|
||||
type = bool
|
||||
description = "Enable the HCP Packer registry."
|
||||
default = false
|
||||
}
|
||||
|
||||
84
builds/linux/centos/9-stream/data/ks.pkrtpl.hcl
Normal file
84
builds/linux/centos/9-stream/data/ks.pkrtpl.hcl
Normal file
@@ -0,0 +1,84 @@
|
||||
# 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.
|
||||
|
||||
# CentOS Stream 9
|
||||
|
||||
### 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_os_language}
|
||||
|
||||
### Sets the default keyboard type for the system.
|
||||
keyboard ${vm_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
|
||||
|
||||
### Lock the root account.
|
||||
rootpw --lock
|
||||
|
||||
### 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_os_timezone}
|
||||
|
||||
### Partitioning
|
||||
${storage}
|
||||
|
||||
### 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
|
||||
|
||||
### Packages selection.
|
||||
%packages --ignoremissing --excludedocs
|
||||
@core
|
||||
-iwl*firmware
|
||||
%end
|
||||
|
||||
### Post-installation commands.
|
||||
%post
|
||||
dnf makecache
|
||||
dnf install epel-release -y
|
||||
dnf makecache
|
||||
dnf install -y sudo qemu-guest-tools
|
||||
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
|
||||
66
builds/linux/centos/9-stream/data/storage.pkrtpl.hcl
Normal file
66
builds/linux/centos/9-stream/data/storage.pkrtpl.hcl
Normal file
@@ -0,0 +1,66 @@
|
||||
### 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.
|
||||
### --all Erases all partitions from the system
|
||||
### --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.
|
||||
%{~ if length(partitions) == 1 && partitions[0].name == "autopart" ~}
|
||||
%{~ if partitions[0].format.fstype == "lvm" ~}
|
||||
autopart --type=lvm
|
||||
%{ endif }
|
||||
%{~ if partitions[0].format.fstype == "simple" ~}
|
||||
autopart --type=plain
|
||||
%{ endif }
|
||||
%{~ if partitions[0].format.fstype == "" ~}
|
||||
autopart --type=plain
|
||||
%{ endif }
|
||||
%{ else }
|
||||
%{~ for partition in partitions ~}
|
||||
%{~ if partition.format.fstype == "swap" ~}
|
||||
part swap --size=${partition.size}
|
||||
|
||||
%{~ endif ~}
|
||||
%{~ if partition.mount.path == "/boot/efi" ~}
|
||||
part ${partition.mount.path} --fstype vfat --size=${partition.size} --label=${partition.format.label}
|
||||
|
||||
%{~ endif ~}
|
||||
%{~ if partition.mount.path != "" ~}
|
||||
part ${partition.mount.path} --fstype ${partition.format.fstype} --size=${partition.size} --label=${partition.format.label} %{~ if partition.mount.options != "" ~}--fsoptions="${partition.mount.options}"%{~ endif ~}
|
||||
|
||||
%{~ endif ~}
|
||||
%{~ if partition.volume_group != "" ~}
|
||||
%{~ if partition.size == -1 ~}
|
||||
part pv.${partition.volume_group} --size=100 --grow
|
||||
|
||||
%{~ else ~}
|
||||
part pv.${partition.volume_group} --size=${partition.size}
|
||||
|
||||
%{~ endif ~}
|
||||
### Create a logical volume management (LVM) group.
|
||||
### Modify logical volume sizes for the virtual machine hardware.
|
||||
%{~ for index, volume_group in lvm ~}
|
||||
%{~ if partition.volume_group != "" ~}
|
||||
volgroup ${volume_group.name} --pesize=4096 pv.${partition.volume_group}
|
||||
|
||||
%{~ endif ~}
|
||||
### Create logical volumes.
|
||||
%{~ for partition in volume_group.partitions ~}
|
||||
%{~ if partition.format.fstype == "swap" ~}
|
||||
logvol swap --fstype ${partition.format.fstype} --name=${partition.name} --vgname=${volume_group.name} --size=${partition.size} --label=${partition.format.label}
|
||||
%{~ else ~}
|
||||
logvol ${partition.mount.path} %{ if partition.format.fstype == "fat32" } --fstype vfat %{ else } --fstype ${partition.format.fstype} %{ endif } %{ if partition.size != -1 } --size=${partition.size} %{ else } --size=100 --grow %{ endif } --name=${partition.name} --vgname=${volume_group.name} --label=${partition.format.label} %{ if partition.mount.options != "" ~} --fsoptions="${partition.mount.options}" %{~ endif ~}
|
||||
|
||||
%{~ endif ~}
|
||||
%{~ endfor ~}
|
||||
%{~ endfor ~}
|
||||
%{~ endif ~}
|
||||
%{~ endfor ~}
|
||||
%{~ endif }
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Ubuntu Server 22.04 LTS variables used by the Packer Plugin for Proxmox (proxmox-iso).
|
||||
*/
|
||||
|
||||
// Guest Operating System Metadata
|
||||
vm_os_language = "en_US"
|
||||
vm_os_keyboard = "us"
|
||||
vm_os_timezone = "UTC"
|
||||
vm_os_family = "linux"
|
||||
vm_os_name = "centos-stream"
|
||||
vm_os_version = "9"
|
||||
|
||||
// Virtual Machine Guest Operating System Setting
|
||||
vm_os_type = "l26"
|
||||
|
||||
// Virtual Machine Hardware Settings
|
||||
vm_bios = "seabios"
|
||||
vm_cpu_count = 1
|
||||
vm_cpu_sockets = 1
|
||||
vm_cpu_type = "x86-64-v2-AES"
|
||||
vm_mem_size = 2048
|
||||
vm_disk_type = "virtio"
|
||||
vm_disk_size = "32G"
|
||||
vm_disk_format = "raw"
|
||||
vm_storage_pool = "vm-data"
|
||||
vm_disk_controller_type = "virtio-scsi-pci"
|
||||
vm_network_card_model = "virtio"
|
||||
vm_bridge_interface = "vmbr0"
|
||||
vm_vlan_tag = "102"
|
||||
|
||||
// Removable Media Settings
|
||||
iso_path = "iso"
|
||||
iso_file = "CentOS-Stream-9-latest-x86_64-dvd1.iso"
|
||||
iso_checksum = "file:https://mirror.stream.centos.org/9-stream/BaseOS/x86_64/iso/SHA256SUM"
|
||||
|
||||
// Boot Settings
|
||||
vm_boot = "order=virtio0;ide2;net0"
|
||||
vm_boot_wait = "5s"
|
||||
|
||||
// EFI Settings
|
||||
vm_firmware_path = "./OVMF.fd"
|
||||
vm_efi_storage_pool = "vm-data"
|
||||
vm_efi_pre_enrolled_keys = false
|
||||
vm_efi_type = "4m"
|
||||
197
builds/linux/centos/9-stream/linux-centos-stream.pkr.hcl
Normal file
197
builds/linux/centos/9-stream/linux-centos-stream.pkr.hcl
Normal file
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Debian 11 template using the Packer Builder for Proxmox (proxmox-iso).
|
||||
*/
|
||||
|
||||
// BLOCK: packer
|
||||
// The Packer configuration.
|
||||
|
||||
packer {
|
||||
required_version = ">= 1.9.1"
|
||||
required_plugins {
|
||||
ansible = {
|
||||
source = "github.com/hashicorp/ansible"
|
||||
version = "~> 1"
|
||||
}
|
||||
git = {
|
||||
version = ">= 0.4.2"
|
||||
source = "github.com/ethanmdavidson/git"
|
||||
}
|
||||
proxmox = {
|
||||
version = ">= 1.0.6"
|
||||
source = "github.com/hashicorp/proxmox"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BLOCK: data
|
||||
// Defines the data sources.
|
||||
|
||||
data "git-repository" "cwd" {}
|
||||
|
||||
// BLOCK: locals
|
||||
// Defines the local variables.
|
||||
|
||||
locals {
|
||||
build_by = "Built by: HashiCorp Packer ${packer.version}"
|
||||
build_date = formatdate("DD-MM-YYYY hh:mm ZZZ", "${timestamp()}" )
|
||||
build_version = data.git-repository.cwd.head
|
||||
build_description = "Version: ${local.build_version}\nBuilt on: ${local.build_date}\n${local.build_by}\nCloud-Init: ${var.vm_cloud_init_enable}"
|
||||
vm_disk_type = var.vm_disk_type == "virtio" ? "vda" : "sda"
|
||||
manifest_date = formatdate("YYYY-MM-DD hh:mm:ss", timestamp())
|
||||
manifest_path = "${path.cwd}/manifests/"
|
||||
manifest_output = "${local.manifest_path}${local.manifest_date}.json"
|
||||
data_source_content = {
|
||||
"/ks.cfg" = templatefile("${abspath(path.root)}/data/ks.pkrtpl.hcl", {
|
||||
build_username = var.build_username
|
||||
build_password = var.build_password
|
||||
build_password_encrypted = var.build_password_encrypted
|
||||
vm_disk_type = local.vm_disk_type
|
||||
vm_os_language = var.vm_os_language
|
||||
vm_os_keyboard = var.vm_os_keyboard
|
||||
vm_os_timezone = var.vm_os_timezone
|
||||
common_data_source = var.common_data_source
|
||||
# lvm needs to be here so late commands can access vg names
|
||||
lvm = var.vm_disk_lvm
|
||||
storage = templatefile("${abspath(path.root)}/data/storage.pkrtpl.hcl", {
|
||||
device = var.vm_disk_device
|
||||
swap = var.vm_disk_use_swap
|
||||
partitions = var.vm_disk_partitions
|
||||
lvm = var.vm_disk_lvm
|
||||
vm_bios = var.vm_bios
|
||||
})
|
||||
})
|
||||
}
|
||||
data_source_command = var.common_data_source == "http" ? "inst.ks=http://{{.HTTPIP}}:{{.HTTPPort}}/ks.cfg" : "inst.ks=/cdrom/ks.cfg"
|
||||
vm_name = "${var.vm_os_family}-${var.vm_os_name}-${var.vm_os_version}"
|
||||
vm_bios = var.vm_bios == "ovmf" ? var.vm_firmware_path : null
|
||||
}
|
||||
|
||||
// BLOCK: source
|
||||
// Defines the builder configuration blocks.
|
||||
|
||||
source "proxmox-iso" "linux-centos-stream" {
|
||||
|
||||
// Proxmox Connection Settings and Credentials
|
||||
proxmox_url = "https://${var.proxmox_hostname}:8006/api2/json"
|
||||
username = "${var.proxmox_api_token_id}"
|
||||
token = "${var.proxmox_api_token_secret}"
|
||||
insecure_skip_tls_verify = "${var.proxmox_insecure_connection}"
|
||||
|
||||
// Proxmox Settings
|
||||
node = "${var.proxmox_node}"
|
||||
|
||||
// Virtual Machine Settings
|
||||
vm_name = "${local.vm_name}"
|
||||
bios = "${var.vm_bios}"
|
||||
sockets = "${var.vm_cpu_sockets}"
|
||||
cores = "${var.vm_cpu_count}"
|
||||
cpu_type = "${var.vm_cpu_type}"
|
||||
memory = "${var.vm_mem_size}"
|
||||
os = "${var.vm_os_type}"
|
||||
scsi_controller = "${var.vm_disk_controller_type}"
|
||||
disks {
|
||||
disk_size = "${var.vm_disk_size}"
|
||||
type = "${var.vm_disk_type}"
|
||||
storage_pool = "${var.vm_storage_pool}"
|
||||
format = "${var.vm_disk_format}"
|
||||
}
|
||||
dynamic "efi_config" {
|
||||
for_each = var.vm_bios == "ovmf" ? [1] : []
|
||||
content {
|
||||
efi_storage_pool = var.vm_bios == "ovmf" ? var.vm_efi_storage_pool : null
|
||||
efi_type = var.vm_bios == "ovmf" ? var.vm_efi_type : null
|
||||
pre_enrolled_keys = var.vm_bios == "ovmf" ? var.vm_efi_pre_enrolled_keys : null
|
||||
}
|
||||
}
|
||||
unmount_iso = true
|
||||
ssh_username = "${var.build_username}"
|
||||
ssh_password = "${var.build_password}"
|
||||
ssh_timeout = "${var.timeout}"
|
||||
ssh_port = "22"
|
||||
iso_file = "${var.common_iso_storage}:${var.iso_path}/${var.iso_file}"
|
||||
iso_checksum = "${var.iso_checksum}"
|
||||
qemu_agent = true
|
||||
|
||||
network_adapters {
|
||||
bridge = "${var.vm_bridge_interface}"
|
||||
model = "${var.vm_network_card_model}"
|
||||
vlan_tag = "${var.vm_vlan_tag}"
|
||||
}
|
||||
|
||||
// Removable Media Settings
|
||||
http_content = "${var.common_data_source}" == "http" ? "${local.data_source_content}" : null
|
||||
|
||||
// Boot and Provisioning Settings
|
||||
http_bind_address = var.common_data_source == "http" ? var.common_http_bind_address : null
|
||||
http_port_min = var.common_data_source == "http" ? var.common_http_port_min : null
|
||||
http_port_max = var.common_data_source == "http" ? var.common_http_port_max : null
|
||||
boot = var.vm_boot
|
||||
boot_wait = var.vm_boot_wait
|
||||
boot_command = [
|
||||
"<up><wait>",
|
||||
"<tab><wait>",
|
||||
" text ${local.data_source_command}",
|
||||
"<enter><wait>"
|
||||
]
|
||||
|
||||
dynamic "additional_iso_files" {
|
||||
for_each = var.common_data_source == "disk" ? [1] : []
|
||||
content {
|
||||
cd_files = var.common_data_source == "disk" ? local.data_source_content : null
|
||||
cd_label = var.common_data_source == "disk" ? "cidata" : null
|
||||
iso_storage_pool = var.common_data_source == "disk" ? "local" : null
|
||||
}
|
||||
}
|
||||
|
||||
template_name = "${local.vm_name}"
|
||||
template_description = "${local.build_description}"
|
||||
|
||||
# VM Cloud Init Settings
|
||||
cloud_init = var.vm_cloud_init_enable
|
||||
cloud_init_storage_pool = var.vm_cloud_init_enable == true ? var.vm_storage_pool : null
|
||||
|
||||
}
|
||||
|
||||
# Build Definition to create the VM Template
|
||||
build {
|
||||
sources = ["source.proxmox-iso.linux-centos-stream"]
|
||||
|
||||
provisioner "ansible" {
|
||||
user = "${var.build_username}"
|
||||
playbook_file = "${path.cwd}/ansible/main.yml"
|
||||
roles_path = "${path.cwd}/ansible/roles"
|
||||
ansible_env_vars = [
|
||||
"ANSIBLE_CONFIG=${path.cwd}/ansible/ansible.cfg"
|
||||
]
|
||||
extra_arguments = [
|
||||
"--extra-vars", "display_skipped_hosts=false",
|
||||
"--extra-vars", "BUILD_USERNAME=${var.build_username}",
|
||||
"--extra-vars", "BUILD_SECRET='${var.build_key}'",
|
||||
"--extra-vars", "ANSIBLE_USERNAME=${var.ansible_username}",
|
||||
"--extra-vars", "ANSIBLE_SECRET='${var.ansible_key}'",
|
||||
"--extra-vars", "cloud_init='${var.vm_cloud_init_enable}'",
|
||||
]
|
||||
}
|
||||
|
||||
post-processor "manifest" {
|
||||
output = local.manifest_output
|
||||
strip_path = true
|
||||
strip_time = true
|
||||
custom_data = {
|
||||
ansible_username = "${var.ansible_username}"
|
||||
build_username = "${var.build_username}"
|
||||
build_date = "${local.build_date}"
|
||||
build_version = "${local.build_version}"
|
||||
common_data_source = "${var.common_data_source}"
|
||||
vm_cpu_sockets = "${var.vm_cpu_sockets}"
|
||||
vm_cpu_count = "${var.vm_cpu_count}"
|
||||
vm_disk_size = "${var.vm_disk_size}"
|
||||
vm_bios = "${var.vm_bios}"
|
||||
vm_os_type = "${var.vm_os_type}"
|
||||
vm_mem_size = "${var.vm_mem_size}"
|
||||
vm_network_card_model = "${var.vm_network_card_model}"
|
||||
vm_cloud_init_enable = "${var.vm_cloud_init_enable}"
|
||||
}
|
||||
}
|
||||
}
|
||||
53
builds/linux/centos/9-stream/variables-storage.pkr.hcl
Normal file
53
builds/linux/centos/9-stream/variables-storage.pkr.hcl
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Debian 11 storage variables used by the Packer Plugin for Proxmox (proxmox-iso).
|
||||
*/
|
||||
|
||||
// VM Storage Settings
|
||||
|
||||
variable "vm_disk_device" {
|
||||
type = string
|
||||
description = "The device for the virtual disk. (e.g. 'sda')"
|
||||
}
|
||||
|
||||
variable "vm_disk_use_swap" {
|
||||
type = bool
|
||||
description = "Whether to use a swap partition."
|
||||
}
|
||||
|
||||
variable "vm_disk_partitions" {
|
||||
type = list(object({
|
||||
name = string
|
||||
size = number
|
||||
format = object({
|
||||
label = string
|
||||
fstype = string
|
||||
})
|
||||
mount = object({
|
||||
path = string
|
||||
options = string
|
||||
})
|
||||
volume_group = string
|
||||
}))
|
||||
description = "The disk partitions for the virtual disk."
|
||||
}
|
||||
|
||||
variable "vm_disk_lvm" {
|
||||
type = list(object({
|
||||
name = string
|
||||
partitions = list(object({
|
||||
name = string
|
||||
size = number
|
||||
format = object({
|
||||
label = string
|
||||
fstype = string
|
||||
})
|
||||
mount = object({
|
||||
path = string
|
||||
options = string
|
||||
})
|
||||
}))
|
||||
}))
|
||||
description = "The LVM configuration for the virtual disk."
|
||||
default = []
|
||||
}
|
||||
297
builds/linux/centos/9-stream/variables.pkr.hcl
Normal file
297
builds/linux/centos/9-stream/variables.pkr.hcl
Normal file
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Debian 11 variables using the Packer Builder for Proxmox (proxmox-iso).
|
||||
*/
|
||||
|
||||
// BLOCK: variable
|
||||
// Defines the input variables.
|
||||
|
||||
// Proxmox Credentials
|
||||
|
||||
variable "proxmox_hostname" {
|
||||
type = string
|
||||
description = "The FQDN or IP address of a Proxmox node. Only one node should be specified in a cluster."
|
||||
}
|
||||
|
||||
variable "proxmox_api_token_id" {
|
||||
type = string
|
||||
description = "The token to login to the Proxmox node/cluster. The format is USER@REALM!TOKENID. (e.g. packer@pam!packer_pve_token)"
|
||||
}
|
||||
|
||||
variable "proxmox_api_token_secret" {
|
||||
type = string
|
||||
description = "The secret for the API token used to login to the Proxmox API."
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
variable "proxmox_insecure_connection" {
|
||||
description = "true/false to skip Proxmox TLS certificate checks."
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
// Proxmox Settings
|
||||
|
||||
variable "proxmox_node" {
|
||||
type = string
|
||||
description = "The name of the Proxmox node that Packer will build templates on."
|
||||
}
|
||||
|
||||
// Virtual Machine Settings
|
||||
|
||||
variable "vm_os_language" {
|
||||
type = string
|
||||
description = "The guest operating system language."
|
||||
default = "en_US"
|
||||
}
|
||||
|
||||
variable "vm_os_keyboard" {
|
||||
type = string
|
||||
description = "The guest operating system keyboard layout."
|
||||
default = "us"
|
||||
}
|
||||
|
||||
variable "vm_os_timezone" {
|
||||
type = string
|
||||
description = "The guest operating system timezone."
|
||||
default = "UTC"
|
||||
}
|
||||
|
||||
variable "vm_os_family" {
|
||||
type = string
|
||||
description = "The guest operating system family. Used for naming. (e.g. 'linux')"
|
||||
}
|
||||
|
||||
variable "vm_os_name" {
|
||||
type = string
|
||||
description = "The guest operating system name. Used for naming. (e.g. 'ubuntu')"
|
||||
}
|
||||
|
||||
variable "vm_os_version" {
|
||||
type = string
|
||||
description = "The guest operating system version. Used for naming. (e.g. '22-04-lts')"
|
||||
}
|
||||
|
||||
variable "vm_os_type" {
|
||||
type = string
|
||||
description = "The guest operating system type. (e.g. 'l26')"
|
||||
}
|
||||
|
||||
variable "vm_bios" {
|
||||
type = string
|
||||
description = "The firmware type. Allowed values 'ovmf' or 'seabios'"
|
||||
default = "OVMF"
|
||||
|
||||
validation {
|
||||
condition = contains(["ovmf", "seabios"], var.vm_bios)
|
||||
error_message = "The vm_bios value must be 'ovmf' or 'seabios'."
|
||||
}
|
||||
}
|
||||
|
||||
variable "vm_firmware_path" {
|
||||
type = string
|
||||
description = "The firmware file to be used. Needed for EFI"
|
||||
default = "/usr/share/ovmf/OVMF.fd"
|
||||
}
|
||||
|
||||
variable "vm_efi_storage_pool" {
|
||||
type = string
|
||||
description = "Set the UEFI disk storage location. (e.g. 'local-lvm')"
|
||||
}
|
||||
|
||||
variable "vm_efi_type" {
|
||||
type = string
|
||||
description = "Specifies the version of the OVMF firmware to be used. (e.g. '4m')"
|
||||
}
|
||||
|
||||
variable "vm_efi_pre_enrolled_keys" {
|
||||
type = bool
|
||||
description = "Whether Microsoft Standard Secure Boot keys should be pre-loaded on the EFI disk. (e.g. false)"
|
||||
}
|
||||
|
||||
variable "vm_cpu_count" {
|
||||
type = number
|
||||
description = "The number of virtual CPUs. (e.g. '2')"
|
||||
}
|
||||
|
||||
variable "vm_cpu_sockets" {
|
||||
type = number
|
||||
description = "The number of virtual CPU sockets. (e.g. '1')"
|
||||
}
|
||||
|
||||
variable "vm_cpu_type" {
|
||||
type = string
|
||||
description = "The CPU type to emulate. See the Proxmox API documentation for the complete list of accepted values. For best performance, set this to host. Defaults to kvm64."
|
||||
}
|
||||
|
||||
variable "vm_mem_size" {
|
||||
type = number
|
||||
description = "The size for the virtual memory in MB. (e.g. '2048')"
|
||||
}
|
||||
|
||||
variable "vm_disk_controller_type" {
|
||||
type = string
|
||||
description = "The SCSI controller model to emulate. (e.g. 'virtio-scsi-pci')"
|
||||
}
|
||||
|
||||
variable "vm_disk_type" {
|
||||
type = string
|
||||
description = "The type of disk to emulate. (e.g. 'virtio')"
|
||||
}
|
||||
|
||||
variable "vm_storage_pool" {
|
||||
type = string
|
||||
description = "The name of the Proxmox storage pool to store the VM template. (e.g. 'local-lvm')"
|
||||
}
|
||||
|
||||
variable "vm_disk_size" {
|
||||
type = string
|
||||
description = "The size for the virtual disk in GB. (e.g. '32G')"
|
||||
}
|
||||
|
||||
variable "vm_disk_format" {
|
||||
type = string
|
||||
description = "The format of the file backing the disk. (e.g. 'qcow2')"
|
||||
}
|
||||
|
||||
variable "vm_network_card_model" {
|
||||
type = string
|
||||
description = "The model of the virtual network adapter to emulate. (e.g. 'virtio')"
|
||||
}
|
||||
|
||||
variable "vm_bridge_interface" {
|
||||
type = string
|
||||
description = "The name of the Proxmox bridge to attach the adapter to."
|
||||
}
|
||||
|
||||
variable "vm_vlan_tag" {
|
||||
type = string
|
||||
description = "If the adapter should tag packets, give the VLAN ID. (e.g. '102')"
|
||||
}
|
||||
|
||||
// Cloud-Init Settings
|
||||
|
||||
variable "vm_cloud_init_enable" {
|
||||
type = bool
|
||||
description = "Enable or disable cloud-init drive in Proxmox. (e.g. false)"
|
||||
default = false
|
||||
}
|
||||
|
||||
// Removable Media Settings
|
||||
|
||||
variable "common_iso_storage" {
|
||||
type = string
|
||||
description = "The name of the source Proxmox storage location for ISO images. (e.g. 'local-lvm')"
|
||||
}
|
||||
|
||||
variable "iso_path" {
|
||||
type = string
|
||||
description = "The path on the source Proxmox storage location for ISO images. (e.g. 'iso')"
|
||||
}
|
||||
|
||||
variable "iso_file" {
|
||||
type = string
|
||||
description = "The file name of the ISO image used by the vendor. (e.g. 'ubuntu-<version>-live-server-amd64.iso')"
|
||||
}
|
||||
|
||||
variable "iso_checksum" {
|
||||
type = string
|
||||
description = "The checksum value of the ISO image provided by the vendor."
|
||||
}
|
||||
|
||||
// Boot Settings
|
||||
|
||||
variable "common_data_source" {
|
||||
type = string
|
||||
description = "The provisioning data source. (e.g. 'http' or 'disk')"
|
||||
}
|
||||
|
||||
variable "common_http_bind_address" {
|
||||
type = string
|
||||
description = "Define an IP address on the host to use for the HTTP server."
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "common_http_port_min" {
|
||||
type = number
|
||||
description = "The start of the HTTP port range."
|
||||
}
|
||||
|
||||
variable "common_http_port_max" {
|
||||
type = number
|
||||
description = "The end of the HTTP port range."
|
||||
}
|
||||
|
||||
variable "vm_boot" {
|
||||
type = string
|
||||
description = "The boot order for virtual machine devices. (e.g. 'order=virtio0;ide2;net0')"
|
||||
}
|
||||
|
||||
variable "vm_boot_wait" {
|
||||
type = string
|
||||
description = "The time to wait after booting the initial VM before typing the boot_command (e.g '10s')"
|
||||
}
|
||||
|
||||
variable "common_ip_wait_timeout" {
|
||||
type = string
|
||||
description = "Time to wait for guest operating system IP address response."
|
||||
}
|
||||
|
||||
variable "common_shutdown_timeout" {
|
||||
type = string
|
||||
description = "Time to wait for guest operating system shutdown."
|
||||
}
|
||||
|
||||
// Communicator Settings and Credentials
|
||||
|
||||
variable "build_username" {
|
||||
type = string
|
||||
description = "The username to login to the guest operating system. (e.g. 'ubuntu')"
|
||||
# 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 to the guest operating system."
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
variable "build_key" {
|
||||
type = string
|
||||
description = "The SSH public key to login to the guest operating system."
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
variable "timeout" {
|
||||
description = "not sure why I need so high a timeout but here we are"
|
||||
default = "90m"
|
||||
}
|
||||
|
||||
// Ansible Credentials
|
||||
|
||||
variable "ansible_username" {
|
||||
type = string
|
||||
description = "The username for Ansible to login to the guest operating system. (e.g. 'ansible')"
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
variable "ansible_key" {
|
||||
type = string
|
||||
description = "The public key for Ansible to login to the guest operating system."
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
// HCP Packer Settings
|
||||
|
||||
variable "common_hcp_packer_registry_enabled" {
|
||||
type = bool
|
||||
description = "Enable the HCP Packer registry."
|
||||
default = false
|
||||
}
|
||||
|
||||
97
builds/linux/debian/11/data/preseed.pkrtpl.hcl
Normal file
97
builds/linux/debian/11/data/preseed.pkrtpl.hcl
Normal file
@@ -0,0 +1,97 @@
|
||||
# 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.
|
||||
|
||||
# Debian 11 (Bullseye) Preseed File
|
||||
# https://www.debian.org/releases/bullseye/amd64/
|
||||
|
||||
# Locale and Keyboard
|
||||
d-i debian-installer/locale string ${vm_os_language}
|
||||
d-i keyboard-configuration/xkb-keymap select ${vm_os_keyboard}
|
||||
|
||||
# Clock and Timezone
|
||||
d-i clock-setup/utc boolean true
|
||||
d-i clock-setup/ntp boolean true
|
||||
d-i time/zone string ${vm_os_timezone}
|
||||
|
||||
# Grub and Reboot Message
|
||||
d-i finish-install/reboot_in_progress note
|
||||
d-i grub-installer/only_debian boolean true
|
||||
|
||||
# Partitioning
|
||||
${storage}
|
||||
|
||||
# Network configuration
|
||||
d-i netcfg/choose_interface select auto
|
||||
d-i netcfg/get_hostname string unassigned-hostname
|
||||
d-i netcfg/get_domain string unassigned-domain
|
||||
|
||||
|
||||
### Apt setup
|
||||
# Choose, if you want to scan additional installation media
|
||||
# (default: false).
|
||||
d-i apt-setup/cdrom/set-first boolean false
|
||||
# You can choose to install non-free firmware.
|
||||
#d-i apt-setup/non-free-firmware boolean true
|
||||
# You can choose to install non-free and contrib software.
|
||||
#d-i apt-setup/non-free boolean true
|
||||
#d-i apt-setup/contrib boolean true
|
||||
# Uncomment the following line, if you don't want to have the sources.list
|
||||
# entry for a DVD/BD installation image active in the installed system
|
||||
# (entries for netinst or CD images will be disabled anyway, regardless of
|
||||
# this setting).
|
||||
#d-i apt-setup/disable-cdrom-entries boolean true
|
||||
# Uncomment this if you don't want to use a network mirror.
|
||||
#d-i apt-setup/use_mirror boolean false
|
||||
# Select which update services to use; define the mirrors to be used.
|
||||
# Values shown below are the normal defaults.
|
||||
#d-i apt-setup/services-select multiselect security, updates
|
||||
#d-i apt-setup/security_host string security.debian.org
|
||||
|
||||
# Mirror settings
|
||||
d-i mirror/country string manual
|
||||
d-i mirror/http/hostname string cdn-fastly.deb.debian.org
|
||||
d-i mirror/http/directory string /debian
|
||||
d-i mirror/http/proxy string
|
||||
|
||||
# User Configuration
|
||||
d-i passwd/root-login boolean false
|
||||
d-i passwd/user-fullname string ${build_username}
|
||||
d-i passwd/username string ${build_username}
|
||||
d-i passwd/user-password-crypted password ${build_password_encrypted}
|
||||
|
||||
# Package Configuration
|
||||
d-i pkgsel/run_tasksel boolean false
|
||||
d-i pkgsel/include string openssh-server qemu-guest-agent python3
|
||||
|
||||
# You can choose, if your system will report back on what software you have
|
||||
# installed, and what software you use. The default is not to report back,
|
||||
# but sending reports helps the project determine what software is most
|
||||
# popular and should be included on the first CD/DVD.
|
||||
popularity-contest popularity-contest/participate boolean false
|
||||
|
||||
### Boot loader installation
|
||||
# Grub is the boot loader (for x86).
|
||||
|
||||
# This is fairly safe to set, it makes grub install automatically to the UEFI
|
||||
# partition/boot record if no other operating system is detected on the machine.
|
||||
d-i grub-installer/only_debian boolean true
|
||||
|
||||
# Avoid that last message about the install being complete.
|
||||
d-i finish-install/reboot_in_progress note
|
||||
|
||||
# Post-install script
|
||||
# - Add User to Sudoers
|
||||
# - Remove lv_delete volume group
|
||||
d-i preseed/late_command string \
|
||||
echo '${build_username} ALL=(ALL) NOPASSWD: ALL' > /target/etc/sudoers.d/${build_username} ; \
|
||||
in-target chmod 440 /etc/sudoers.d/${build_username}%{ if length(lvm) != 0 ~} ; \
|
||||
lvremove -f /dev/%{ for volume_group in lvm ~}${volume_group.name}%{ endfor ~}/lv_delete > /dev/null 2>&1%{ endif }
|
||||
|
||||
%{ if common_data_source == "disk" ~}
|
||||
# Umount preseed media early
|
||||
d-i preseed/early_command string \
|
||||
umount /media && echo 1 > /sys/block/sr1/device/delete ;
|
||||
%{ endif ~}
|
||||
|
||||
157
builds/linux/debian/11/data/storage.pkrtpl.hcl
Normal file
157
builds/linux/debian/11/data/storage.pkrtpl.hcl
Normal file
@@ -0,0 +1,157 @@
|
||||
|
||||
%{~ if length(lvm) != 0 ~}
|
||||
d-i partman-auto/method string lvm
|
||||
d-i partman-auto-lvm/guided_size string max
|
||||
d-i partman-lvm/confirm boolean true
|
||||
d-i partman-lvm/confirm_nooverwrite boolean true
|
||||
d-i partman-lvm/device_remove_lvm boolean true
|
||||
%{~ for volume_group in lvm ~}
|
||||
d-i partman-auto-lvm/new_vg_name string ${volume_group.name}
|
||||
%{~ endfor ~}
|
||||
%{~ endif ~}
|
||||
|
||||
d-i partman-efi/non_efi_system boolean true
|
||||
|
||||
# Ensure the partition table is GPT - this is required for EFI
|
||||
d-i partman-partitioning/choose_label select gpt
|
||||
d-i partman-partitioning/default_label string gpt
|
||||
|
||||
# If there is only one partition defined and its name is 'autopart'
|
||||
# then use auto partitioning
|
||||
%{~ if length(partitions) == 1 && partitions[0].name == "autopart" ~}
|
||||
d-i partman-auto/disk string /dev/${device}
|
||||
%{~ if partitions[0].format.fstype == "lvm" ~}
|
||||
d-i partman-auto/method string lvm
|
||||
|
||||
# You can define the amount of space that will be used for the LVM volume
|
||||
# group. It can either be a size with its unit (eg. 20 GB), a percentage of
|
||||
# free space or the 'max' keyword.
|
||||
d-i partman-auto-lvm/guided_size string max
|
||||
|
||||
# If one of the disks that are going to be automatically partitioned
|
||||
# contains an old LVM configuration, the user will normally receive a
|
||||
# warning. This can be preseeded away...
|
||||
d-i partman-lvm/device_remove_lvm boolean true
|
||||
# And the same goes for the confirmation to write the lvm partitions.
|
||||
d-i partman-lvm/confirm boolean true
|
||||
d-i partman-lvm/confirm_nooverwrite boolean true
|
||||
|
||||
%{~ endif ~}
|
||||
%{~ if partitions[0].format.fstype == "simple" ~}
|
||||
d-i partman-auto/method string regular
|
||||
%{~ endif ~}
|
||||
%{ if partitions[0].format.fstype == "" ~}
|
||||
d-i partman-auto/method string regular
|
||||
%{~ endif ~}
|
||||
# You can choose one of the three predefined partitioning recipes:
|
||||
# - atomic: all files in one partition
|
||||
# - home: separate /home partition
|
||||
# - multi: separate /home, /var, and /tmp partitions
|
||||
d-i partman-auto/choose_recipe select atomic
|
||||
|
||||
%{~ else ~} # if length(partitions) == 1 && partitions[0].name == "autopart"
|
||||
%{~ if swap == false ~}
|
||||
d-i partman-basicfilesystems/no_swap boolean false
|
||||
%{~ endif ~}
|
||||
d-i partman-auto/expert_recipe string \
|
||||
custom :: \
|
||||
%{~ for partition in partitions ~}
|
||||
%{~ if lookup(partition, "volume_group", "") == "" ~}
|
||||
%{~ if partition.size != -1 ~}
|
||||
${partition.size} ${partition.size} ${partition.size} ${partition.format.fstype} \
|
||||
%{~ else ~}
|
||||
100 100 -1 ${partition.format.fstype} \
|
||||
%{~ endif ~}
|
||||
$primary{ } \
|
||||
%{~ if partition.mount.path == "/boot" ~}
|
||||
$bootable{ } \
|
||||
mountpoint{ /boot } \
|
||||
method{ format } \
|
||||
%{~ endif ~}
|
||||
%{~ if partition.mount.path == "/boot/efi" ~}
|
||||
mountpoint{ /boot/efi } \
|
||||
method{ efi } \
|
||||
%{~ endif ~}
|
||||
%{~ if partition.mount.path != "/boot" && partition.mount.path != "/boot/efi" ~}
|
||||
%{~ if partition.mount.path != "" ~}
|
||||
mountpoint{ ${partition.mount.path} } \
|
||||
%{~ endif ~}
|
||||
method{ ${partition.format.fstype} } \
|
||||
%{~ endif ~}
|
||||
format{ } \
|
||||
%{~ if partition.format.fstype != "swap" ~}
|
||||
use_filesystem{ } \
|
||||
%{~ if partition.format.fstype == "fat32" ~}
|
||||
filesystem{ vfat } \
|
||||
%{~ else ~}
|
||||
filesystem{ ${partition.format.fstype} } \
|
||||
%{~ endif ~}
|
||||
%{~ endif ~}
|
||||
label { ${partition.format.label} } \
|
||||
%{~ for option in split(",", lookup(partition.mount, "options", "")) ~}
|
||||
%{~ if option != "" ~}
|
||||
options/${option}{ ${option} } \
|
||||
%{~ endif ~}
|
||||
%{~ endfor ~}
|
||||
. \
|
||||
%{~ else /* if lookup(partition, "volume_group", "") == "" */ ~}
|
||||
%{~ for volume_group in lvm ~}
|
||||
%{~ if volume_group.name == partition.volume_group ~}
|
||||
%{~ for partition in volume_group.partitions ~}
|
||||
%{ if partition.size != -1 ~}
|
||||
%{ if partition.format.fstype == "swap" ~}
|
||||
${partition.size} ${partition.size} ${partition.size} linux-swap \
|
||||
%{~ else ~}
|
||||
${partition.size} ${partition.size} ${partition.size} ${partition.format.fstype} \
|
||||
%{~ endif ~}
|
||||
%{~ else ~}
|
||||
%{~ if partition.format.fstype != "swap" /* I don't know who would fill their disk with swap but it could happen */ ~}
|
||||
100 100 -1 ${partition.format.fstype} \
|
||||
%{~ else ~}
|
||||
100 100 -1 linux-swap \
|
||||
%{~ endif ~}
|
||||
%{ endif ~}
|
||||
$lvmok{ } \
|
||||
%{~ if partition.mount.path != "" ~}
|
||||
mountpoint{ ${partition.mount.path} } \
|
||||
%{~ endif ~}
|
||||
lv_name{ ${partition.name} } \
|
||||
in_vg { ${volume_group.name} } \
|
||||
%{~ if partition.format.fstype == "swap" ~}
|
||||
method{ swap } \
|
||||
%{~ else ~}
|
||||
method{ format } \
|
||||
%{~ endif ~}
|
||||
format{ } \
|
||||
%{~ if partition.format.fstype != "swap" ~}
|
||||
use_filesystem{ } \
|
||||
filesystem{ ${partition.format.fstype} } \
|
||||
%{~ endif ~}
|
||||
label { ${partition.format.label} } \
|
||||
%{~ for option in split(",", lookup(partition.mount, "options", "")) ~}
|
||||
%{~ if option != "" ~}
|
||||
options/${option}{ ${option} } \
|
||||
%{~ endif ~}
|
||||
%{~ endfor ~}
|
||||
. \
|
||||
%{~ endfor /* partition in volume_group.partitions */ ~}
|
||||
1024 1024 1024 ext4 \
|
||||
method{ lvm } \
|
||||
$lvmok{ } \
|
||||
lv_name{ lv_delete } \
|
||||
mountpoint{ /tmp/lv_delete } \
|
||||
. \
|
||||
%{~ endif /* volume_group.name == partition.volume_group */ ~}
|
||||
%{~ endfor /* for volume_group in lvm */ ~}
|
||||
%{~ endif /* if lookup(partition, "volume_group", "") == "" */ ~}
|
||||
%{~ endfor /* for partition in partitions */ ~}
|
||||
|
||||
%{~ endif /* if length(partitions) == 1 && partitions[0].name == "autopart" */ ~}
|
||||
|
||||
d-i partman-partitioning/confirm_write_new_label boolean true
|
||||
d-i partman/choose_partition select finish
|
||||
d-i partman/confirm boolean true
|
||||
d-i partman/confirm_nooverwrite boolean true
|
||||
|
||||
# To make sure the machine can boot we install grub on the first harddisk:
|
||||
d-i grub-installer/bootdev string /dev/${device}
|
||||
45
builds/linux/debian/11/linux-debian.auto.pkrvars.hcl
Normal file
45
builds/linux/debian/11/linux-debian.auto.pkrvars.hcl
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Ubuntu Server 22.04 LTS variables used by the Packer Plugin for Proxmox (proxmox-iso).
|
||||
*/
|
||||
|
||||
// Guest Operating System Metadata
|
||||
vm_os_language = "en_US"
|
||||
vm_os_keyboard = "us"
|
||||
vm_os_timezone = "UTC"
|
||||
vm_os_family = "linux"
|
||||
vm_os_name = "debian"
|
||||
vm_os_version = "11"
|
||||
|
||||
// Virtual Machine Guest Operating System Setting
|
||||
vm_os_type = "l26"
|
||||
|
||||
// Virtual Machine Hardware Settings
|
||||
vm_bios = "seabios"
|
||||
vm_cpu_count = 1
|
||||
vm_cpu_sockets = 1
|
||||
vm_cpu_type = "kvm64"
|
||||
vm_mem_size = 2048
|
||||
vm_disk_type = "virtio"
|
||||
vm_disk_size = "32G"
|
||||
vm_disk_format = "raw"
|
||||
vm_storage_pool = "vm-data"
|
||||
vm_disk_controller_type = "virtio-scsi-pci"
|
||||
vm_network_card_model = "virtio"
|
||||
vm_bridge_interface = "vmbr0"
|
||||
vm_vlan_tag = "102"
|
||||
|
||||
// Removable Media Settings
|
||||
iso_path = "iso"
|
||||
iso_file = "debian-11.8.0-amd64-netinst.iso"
|
||||
iso_checksum = "d7a74813a734083df30c8d35784926deaa36bc41e5c0766388e9f591ab056b72"
|
||||
|
||||
// Boot Settings
|
||||
vm_boot = "order=virtio0;ide2;net0"
|
||||
vm_boot_wait = "5s"
|
||||
|
||||
// EFI Settings
|
||||
vm_firmware_path = "./OVMF.fd"
|
||||
vm_efi_storage_pool = "vm-data"
|
||||
vm_efi_pre_enrolled_keys = false
|
||||
vm_efi_type = "4m"
|
||||
201
builds/linux/debian/11/linux-debian.pkr.hcl
Normal file
201
builds/linux/debian/11/linux-debian.pkr.hcl
Normal file
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Debian 11 template using the Packer Builder for Proxmox (proxmox-iso).
|
||||
*/
|
||||
|
||||
// BLOCK: packer
|
||||
// The Packer configuration.
|
||||
|
||||
packer {
|
||||
required_version = ">= 1.9.1"
|
||||
required_plugins {
|
||||
ansible = {
|
||||
source = "github.com/hashicorp/ansible"
|
||||
version = "~> 1"
|
||||
}
|
||||
git = {
|
||||
version = ">= 0.4.2"
|
||||
source = "github.com/ethanmdavidson/git"
|
||||
}
|
||||
proxmox = {
|
||||
version = ">= 1.0.6"
|
||||
source = "github.com/hashicorp/proxmox"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BLOCK: data
|
||||
// Defines the data sources.
|
||||
|
||||
data "git-repository" "cwd" {}
|
||||
|
||||
// BLOCK: locals
|
||||
// Defines the local variables.
|
||||
|
||||
locals {
|
||||
build_by = "Built by: HashiCorp Packer ${packer.version}"
|
||||
build_date = formatdate("DD-MM-YYYY hh:mm ZZZ", "${timestamp()}" )
|
||||
build_version = data.git-repository.cwd.head
|
||||
build_description = "Version: ${local.build_version}\nBuilt on: ${local.build_date}\n${local.build_by}\nCloud-Init: ${var.vm_cloud_init_enable}"
|
||||
vm_disk_type = var.vm_disk_type == "virtio" ? "vda" : "sda"
|
||||
manifest_date = formatdate("YYYY-MM-DD hh:mm:ss", timestamp())
|
||||
manifest_path = "${path.cwd}/manifests/"
|
||||
manifest_output = "${local.manifest_path}${local.manifest_date}.json"
|
||||
data_source_content = {
|
||||
"/preseed.cfg" = templatefile("${abspath(path.root)}/data/preseed.pkrtpl.hcl", {
|
||||
build_username = var.build_username
|
||||
build_password = var.build_password
|
||||
build_password_encrypted = var.build_password_encrypted
|
||||
vm_disk_type = local.vm_disk_type
|
||||
vm_os_language = var.vm_os_language
|
||||
vm_os_keyboard = var.vm_os_keyboard
|
||||
vm_os_timezone = var.vm_os_timezone
|
||||
common_data_source = var.common_data_source
|
||||
# lvm needs to be here so late commands can access vg names
|
||||
lvm = var.vm_disk_lvm
|
||||
storage = templatefile("${abspath(path.root)}/data/storage.pkrtpl.hcl", {
|
||||
device = var.vm_disk_device
|
||||
swap = var.vm_disk_use_swap
|
||||
partitions = var.vm_disk_partitions
|
||||
lvm = var.vm_disk_lvm
|
||||
vm_bios = var.vm_bios
|
||||
})
|
||||
})
|
||||
}
|
||||
data_source_command = var.common_data_source == "http" ? "url=http://{{.HTTPIP}}:{{.HTTPPort}}/preseed.cfg" : "file=/media/preseed.cfg"
|
||||
vm_name = "${var.vm_os_family}-${var.vm_os_name}-${var.vm_os_version}"
|
||||
vm_bios = var.vm_bios == "ovmf" ? var.vm_firmware_path : null
|
||||
}
|
||||
|
||||
// BLOCK: source
|
||||
// Defines the builder configuration blocks.
|
||||
|
||||
source "proxmox-iso" "debian" {
|
||||
|
||||
// Proxmox Connection Settings and Credentials
|
||||
proxmox_url = "https://${var.proxmox_hostname}:8006/api2/json"
|
||||
username = "${var.proxmox_api_token_id}"
|
||||
token = "${var.proxmox_api_token_secret}"
|
||||
insecure_skip_tls_verify = "${var.proxmox_insecure_connection}"
|
||||
|
||||
// Proxmox Settings
|
||||
node = "${var.proxmox_node}"
|
||||
|
||||
// Virtual Machine Settings
|
||||
vm_name = "${local.vm_name}"
|
||||
bios = "${var.vm_bios}"
|
||||
sockets = "${var.vm_cpu_sockets}"
|
||||
cores = "${var.vm_cpu_count}"
|
||||
cpu_type = "${var.vm_cpu_type}"
|
||||
memory = "${var.vm_mem_size}"
|
||||
os = "${var.vm_os_type}"
|
||||
scsi_controller = "${var.vm_disk_controller_type}"
|
||||
disks {
|
||||
disk_size = "${var.vm_disk_size}"
|
||||
type = "${var.vm_disk_type}"
|
||||
storage_pool = "${var.vm_storage_pool}"
|
||||
format = "${var.vm_disk_format}"
|
||||
}
|
||||
dynamic "efi_config" {
|
||||
for_each = var.vm_bios == "ovmf" ? [1] : []
|
||||
content {
|
||||
efi_storage_pool = var.vm_bios == "ovmf" ? var.vm_efi_storage_pool : null
|
||||
efi_type = var.vm_bios == "ovmf" ? var.vm_efi_type : null
|
||||
pre_enrolled_keys = var.vm_bios == "ovmf" ? var.vm_efi_pre_enrolled_keys : null
|
||||
}
|
||||
}
|
||||
unmount_iso = true
|
||||
ssh_username = "${var.build_username}"
|
||||
ssh_password = "${var.build_password}"
|
||||
ssh_timeout = "${var.timeout}"
|
||||
ssh_port = "22"
|
||||
iso_file = "${var.common_iso_storage}:${var.iso_path}/${var.iso_file}"
|
||||
iso_checksum = "${var.iso_checksum}"
|
||||
qemu_agent = true
|
||||
|
||||
network_adapters {
|
||||
bridge = "${var.vm_bridge_interface}"
|
||||
model = "${var.vm_network_card_model}"
|
||||
vlan_tag = "${var.vm_vlan_tag}"
|
||||
}
|
||||
|
||||
// Removable Media Settings
|
||||
http_content = "${var.common_data_source}" == "http" ? "${local.data_source_content}" : null
|
||||
|
||||
// Boot and Provisioning Settings
|
||||
http_bind_address = var.common_data_source == "http" ? var.common_http_bind_address : null
|
||||
http_port_min = var.common_data_source == "http" ? var.common_http_port_min : null
|
||||
http_port_max = var.common_data_source == "http" ? var.common_http_port_max : null
|
||||
boot = var.vm_boot
|
||||
boot_wait = var.vm_boot_wait
|
||||
boot_command = [
|
||||
"<wait><wait><wait><esc><wait><wait><wait>",
|
||||
"/install.amd/vmlinuz ",
|
||||
"initrd=/install.amd/initrd.gz ",
|
||||
"auto=true ",
|
||||
"${local.data_source_command} ",
|
||||
"netcfg/get_hostname=debian netcfg/get_domain=example.com ",
|
||||
"interface=auto ",
|
||||
"vga=788 noprompt quiet --<enter>"
|
||||
]
|
||||
|
||||
dynamic "additional_iso_files" {
|
||||
for_each = var.common_data_source == "disk" ? [1] : []
|
||||
content {
|
||||
cd_files = var.common_data_source == "disk" ? local.data_source_content : null
|
||||
cd_label = var.common_data_source == "disk" ? "cidata" : null
|
||||
iso_storage_pool = var.common_data_source == "disk" ? "local" : null
|
||||
}
|
||||
}
|
||||
|
||||
template_name = "${local.vm_name}"
|
||||
template_description = "${local.build_description}"
|
||||
|
||||
# VM Cloud Init Settings
|
||||
cloud_init = var.vm_cloud_init_enable
|
||||
cloud_init_storage_pool = var.vm_cloud_init_enable == true ? var.vm_storage_pool : null
|
||||
|
||||
}
|
||||
|
||||
# Build Definition to create the VM Template
|
||||
build {
|
||||
sources = ["source.proxmox-iso.debian"]
|
||||
|
||||
provisioner "ansible" {
|
||||
user = "${var.build_username}"
|
||||
playbook_file = "${path.cwd}/ansible/main.yml"
|
||||
roles_path = "${path.cwd}/ansible/roles"
|
||||
ansible_env_vars = [
|
||||
"ANSIBLE_CONFIG=${path.cwd}/ansible/ansible.cfg"
|
||||
]
|
||||
extra_arguments = [
|
||||
"--extra-vars", "display_skipped_hosts=false",
|
||||
"--extra-vars", "BUILD_USERNAME=${var.build_username}",
|
||||
"--extra-vars", "BUILD_SECRET='${var.build_key}'",
|
||||
"--extra-vars", "ANSIBLE_USERNAME=${var.ansible_username}",
|
||||
"--extra-vars", "ANSIBLE_SECRET='${var.ansible_key}'",
|
||||
"--extra-vars", "cloud_init='${var.vm_cloud_init_enable}'",
|
||||
]
|
||||
}
|
||||
|
||||
post-processor "manifest" {
|
||||
output = local.manifest_output
|
||||
strip_path = true
|
||||
strip_time = true
|
||||
custom_data = {
|
||||
ansible_username = "${var.ansible_username}"
|
||||
build_username = "${var.build_username}"
|
||||
build_date = "${local.build_date}"
|
||||
build_version = "${local.build_version}"
|
||||
common_data_source = "${var.common_data_source}"
|
||||
vm_cpu_sockets = "${var.vm_cpu_sockets}"
|
||||
vm_cpu_count = "${var.vm_cpu_count}"
|
||||
vm_disk_size = "${var.vm_disk_size}"
|
||||
vm_bios = "${var.vm_bios}"
|
||||
vm_os_type = "${var.vm_os_type}"
|
||||
vm_mem_size = "${var.vm_mem_size}"
|
||||
vm_network_card_model = "${var.vm_network_card_model}"
|
||||
vm_cloud_init_enable = "${var.vm_cloud_init_enable}"
|
||||
}
|
||||
}
|
||||
}
|
||||
53
builds/linux/debian/11/variables-storage.pkr.hcl
Normal file
53
builds/linux/debian/11/variables-storage.pkr.hcl
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Debian 11 storage variables used by the Packer Plugin for Proxmox (proxmox-iso).
|
||||
*/
|
||||
|
||||
// VM Storage Settings
|
||||
|
||||
variable "vm_disk_device" {
|
||||
type = string
|
||||
description = "The device for the virtual disk. (e.g. 'sda')"
|
||||
}
|
||||
|
||||
variable "vm_disk_use_swap" {
|
||||
type = bool
|
||||
description = "Whether to use a swap partition."
|
||||
}
|
||||
|
||||
variable "vm_disk_partitions" {
|
||||
type = list(object({
|
||||
name = string
|
||||
size = number
|
||||
format = object({
|
||||
label = string
|
||||
fstype = string
|
||||
})
|
||||
mount = object({
|
||||
path = string
|
||||
options = string
|
||||
})
|
||||
volume_group = string
|
||||
}))
|
||||
description = "The disk partitions for the virtual disk."
|
||||
}
|
||||
|
||||
variable "vm_disk_lvm" {
|
||||
type = list(object({
|
||||
name = string
|
||||
partitions = list(object({
|
||||
name = string
|
||||
size = number
|
||||
format = object({
|
||||
label = string
|
||||
fstype = string
|
||||
})
|
||||
mount = object({
|
||||
path = string
|
||||
options = string
|
||||
})
|
||||
}))
|
||||
}))
|
||||
description = "The LVM configuration for the virtual disk."
|
||||
default = []
|
||||
}
|
||||
297
builds/linux/debian/11/variables.pkr.hcl
Normal file
297
builds/linux/debian/11/variables.pkr.hcl
Normal file
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Debian 11 variables using the Packer Builder for Proxmox (proxmox-iso).
|
||||
*/
|
||||
|
||||
// BLOCK: variable
|
||||
// Defines the input variables.
|
||||
|
||||
// Proxmox Credentials
|
||||
|
||||
variable "proxmox_hostname" {
|
||||
type = string
|
||||
description = "The FQDN or IP address of a Proxmox node. Only one node should be specified in a cluster."
|
||||
}
|
||||
|
||||
variable "proxmox_api_token_id" {
|
||||
type = string
|
||||
description = "The token to login to the Proxmox node/cluster. The format is USER@REALM!TOKENID. (e.g. packer@pam!packer_pve_token)"
|
||||
}
|
||||
|
||||
variable "proxmox_api_token_secret" {
|
||||
type = string
|
||||
description = "The secret for the API token used to login to the Proxmox API."
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
variable "proxmox_insecure_connection" {
|
||||
description = "true/false to skip Proxmox TLS certificate checks."
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
// Proxmox Settings
|
||||
|
||||
variable "proxmox_node" {
|
||||
type = string
|
||||
description = "The name of the Proxmox node that Packer will build templates on."
|
||||
}
|
||||
|
||||
// Virtual Machine Settings
|
||||
|
||||
variable "vm_os_language" {
|
||||
type = string
|
||||
description = "The guest operating system language."
|
||||
default = "en_US"
|
||||
}
|
||||
|
||||
variable "vm_os_keyboard" {
|
||||
type = string
|
||||
description = "The guest operating system keyboard layout."
|
||||
default = "us"
|
||||
}
|
||||
|
||||
variable "vm_os_timezone" {
|
||||
type = string
|
||||
description = "The guest operating system timezone."
|
||||
default = "UTC"
|
||||
}
|
||||
|
||||
variable "vm_os_family" {
|
||||
type = string
|
||||
description = "The guest operating system family. Used for naming. (e.g. 'linux')"
|
||||
}
|
||||
|
||||
variable "vm_os_name" {
|
||||
type = string
|
||||
description = "The guest operating system name. Used for naming. (e.g. 'ubuntu')"
|
||||
}
|
||||
|
||||
variable "vm_os_version" {
|
||||
type = string
|
||||
description = "The guest operating system version. Used for naming. (e.g. '22-04-lts')"
|
||||
}
|
||||
|
||||
variable "vm_os_type" {
|
||||
type = string
|
||||
description = "The guest operating system type. (e.g. 'l26')"
|
||||
}
|
||||
|
||||
variable "vm_bios" {
|
||||
type = string
|
||||
description = "The firmware type. Allowed values 'ovmf' or 'seabios'"
|
||||
default = "OVMF"
|
||||
|
||||
validation {
|
||||
condition = contains(["ovmf", "seabios"], var.vm_bios)
|
||||
error_message = "The vm_bios value must be 'ovmf' or 'seabios'."
|
||||
}
|
||||
}
|
||||
|
||||
variable "vm_firmware_path" {
|
||||
type = string
|
||||
description = "The firmware file to be used. Needed for EFI"
|
||||
default = "/usr/share/ovmf/OVMF.fd"
|
||||
}
|
||||
|
||||
variable "vm_efi_storage_pool" {
|
||||
type = string
|
||||
description = "Set the UEFI disk storage location. (e.g. 'local-lvm')"
|
||||
}
|
||||
|
||||
variable "vm_efi_type" {
|
||||
type = string
|
||||
description = "Specifies the version of the OVMF firmware to be used. (e.g. '4m')"
|
||||
}
|
||||
|
||||
variable "vm_efi_pre_enrolled_keys" {
|
||||
type = bool
|
||||
description = "Whether Microsoft Standard Secure Boot keys should be pre-loaded on the EFI disk. (e.g. false)"
|
||||
}
|
||||
|
||||
variable "vm_cpu_count" {
|
||||
type = number
|
||||
description = "The number of virtual CPUs. (e.g. '2')"
|
||||
}
|
||||
|
||||
variable "vm_cpu_sockets" {
|
||||
type = number
|
||||
description = "The number of virtual CPU sockets. (e.g. '1')"
|
||||
}
|
||||
|
||||
variable "vm_cpu_type" {
|
||||
type = string
|
||||
description = "The CPU type to emulate. See the Proxmox API documentation for the complete list of accepted values. For best performance, set this to host. Defaults to kvm64."
|
||||
}
|
||||
|
||||
variable "vm_mem_size" {
|
||||
type = number
|
||||
description = "The size for the virtual memory in MB. (e.g. '2048')"
|
||||
}
|
||||
|
||||
variable "vm_disk_controller_type" {
|
||||
type = string
|
||||
description = "The SCSI controller model to emulate. (e.g. 'virtio-scsi-pci')"
|
||||
}
|
||||
|
||||
variable "vm_disk_type" {
|
||||
type = string
|
||||
description = "The type of disk to emulate. (e.g. 'virtio')"
|
||||
}
|
||||
|
||||
variable "vm_storage_pool" {
|
||||
type = string
|
||||
description = "The name of the Proxmox storage pool to store the VM template. (e.g. 'local-lvm')"
|
||||
}
|
||||
|
||||
variable "vm_disk_size" {
|
||||
type = string
|
||||
description = "The size for the virtual disk in GB. (e.g. '32G')"
|
||||
}
|
||||
|
||||
variable "vm_disk_format" {
|
||||
type = string
|
||||
description = "The format of the file backing the disk. (e.g. 'qcow2')"
|
||||
}
|
||||
|
||||
variable "vm_network_card_model" {
|
||||
type = string
|
||||
description = "The model of the virtual network adapter to emulate. (e.g. 'virtio')"
|
||||
}
|
||||
|
||||
variable "vm_bridge_interface" {
|
||||
type = string
|
||||
description = "The name of the Proxmox bridge to attach the adapter to."
|
||||
}
|
||||
|
||||
variable "vm_vlan_tag" {
|
||||
type = string
|
||||
description = "If the adapter should tag packets, give the VLAN ID. (e.g. '102')"
|
||||
}
|
||||
|
||||
// Cloud-Init Settings
|
||||
|
||||
variable "vm_cloud_init_enable" {
|
||||
type = bool
|
||||
description = "Enable or disable cloud-init drive in Proxmox. (e.g. false)"
|
||||
default = false
|
||||
}
|
||||
|
||||
// Removable Media Settings
|
||||
|
||||
variable "common_iso_storage" {
|
||||
type = string
|
||||
description = "The name of the source Proxmox storage location for ISO images. (e.g. 'local-lvm')"
|
||||
}
|
||||
|
||||
variable "iso_path" {
|
||||
type = string
|
||||
description = "The path on the source Proxmox storage location for ISO images. (e.g. 'iso')"
|
||||
}
|
||||
|
||||
variable "iso_file" {
|
||||
type = string
|
||||
description = "The file name of the ISO image used by the vendor. (e.g. 'ubuntu-<version>-live-server-amd64.iso')"
|
||||
}
|
||||
|
||||
variable "iso_checksum" {
|
||||
type = string
|
||||
description = "The checksum value of the ISO image provided by the vendor."
|
||||
}
|
||||
|
||||
// Boot Settings
|
||||
|
||||
variable "common_data_source" {
|
||||
type = string
|
||||
description = "The provisioning data source. (e.g. 'http' or 'disk')"
|
||||
}
|
||||
|
||||
variable "common_http_bind_address" {
|
||||
type = string
|
||||
description = "Define an IP address on the host to use for the HTTP server."
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "common_http_port_min" {
|
||||
type = number
|
||||
description = "The start of the HTTP port range."
|
||||
}
|
||||
|
||||
variable "common_http_port_max" {
|
||||
type = number
|
||||
description = "The end of the HTTP port range."
|
||||
}
|
||||
|
||||
variable "vm_boot" {
|
||||
type = string
|
||||
description = "The boot order for virtual machine devices. (e.g. 'order=virtio0;ide2;net0')"
|
||||
}
|
||||
|
||||
variable "vm_boot_wait" {
|
||||
type = string
|
||||
description = "The time to wait after booting the initial VM before typing the boot_command (e.g '10s')"
|
||||
}
|
||||
|
||||
variable "common_ip_wait_timeout" {
|
||||
type = string
|
||||
description = "Time to wait for guest operating system IP address response."
|
||||
}
|
||||
|
||||
variable "common_shutdown_timeout" {
|
||||
type = string
|
||||
description = "Time to wait for guest operating system shutdown."
|
||||
}
|
||||
|
||||
// Communicator Settings and Credentials
|
||||
|
||||
variable "build_username" {
|
||||
type = string
|
||||
description = "The username to login to the guest operating system. (e.g. 'ubuntu')"
|
||||
# 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 to the guest operating system."
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
variable "build_key" {
|
||||
type = string
|
||||
description = "The SSH public key to login to the guest operating system."
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
variable "timeout" {
|
||||
description = "not sure why I need so high a timeout but here we are"
|
||||
default = "90m"
|
||||
}
|
||||
|
||||
// Ansible Credentials
|
||||
|
||||
variable "ansible_username" {
|
||||
type = string
|
||||
description = "The username for Ansible to login to the guest operating system. (e.g. 'ansible')"
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
variable "ansible_key" {
|
||||
type = string
|
||||
description = "The public key for Ansible to login to the guest operating system."
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
// HCP Packer Settings
|
||||
|
||||
variable "common_hcp_packer_registry_enabled" {
|
||||
type = bool
|
||||
description = "Enable the HCP Packer registry."
|
||||
default = false
|
||||
}
|
||||
|
||||
97
builds/linux/debian/12/data/preseed.pkrtpl.hcl
Normal file
97
builds/linux/debian/12/data/preseed.pkrtpl.hcl
Normal file
@@ -0,0 +1,97 @@
|
||||
# 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.
|
||||
|
||||
# Debian 11 (Bullseye) Preseed File
|
||||
# https://www.debian.org/releases/bullseye/amd64/
|
||||
|
||||
# Locale and Keyboard
|
||||
d-i debian-installer/locale string ${vm_os_language}
|
||||
d-i keyboard-configuration/xkb-keymap select ${vm_os_keyboard}
|
||||
|
||||
# Clock and Timezone
|
||||
d-i clock-setup/utc boolean true
|
||||
d-i clock-setup/ntp boolean true
|
||||
d-i time/zone string ${vm_os_timezone}
|
||||
|
||||
# Grub and Reboot Message
|
||||
d-i finish-install/reboot_in_progress note
|
||||
d-i grub-installer/only_debian boolean true
|
||||
|
||||
# Partitioning
|
||||
${storage}
|
||||
|
||||
# Network configuration
|
||||
d-i netcfg/choose_interface select auto
|
||||
d-i netcfg/get_hostname string unassigned-hostname
|
||||
d-i netcfg/get_domain string unassigned-domain
|
||||
|
||||
|
||||
### Apt setup
|
||||
# Choose, if you want to scan additional installation media
|
||||
# (default: false).
|
||||
d-i apt-setup/cdrom/set-first boolean false
|
||||
# You can choose to install non-free firmware.
|
||||
#d-i apt-setup/non-free-firmware boolean true
|
||||
# You can choose to install non-free and contrib software.
|
||||
#d-i apt-setup/non-free boolean true
|
||||
#d-i apt-setup/contrib boolean true
|
||||
# Uncomment the following line, if you don't want to have the sources.list
|
||||
# entry for a DVD/BD installation image active in the installed system
|
||||
# (entries for netinst or CD images will be disabled anyway, regardless of
|
||||
# this setting).
|
||||
#d-i apt-setup/disable-cdrom-entries boolean true
|
||||
# Uncomment this if you don't want to use a network mirror.
|
||||
#d-i apt-setup/use_mirror boolean false
|
||||
# Select which update services to use; define the mirrors to be used.
|
||||
# Values shown below are the normal defaults.
|
||||
#d-i apt-setup/services-select multiselect security, updates
|
||||
#d-i apt-setup/security_host string security.debian.org
|
||||
|
||||
# Mirror settings
|
||||
d-i mirror/country string manual
|
||||
d-i mirror/http/hostname string cdn-fastly.deb.debian.org
|
||||
d-i mirror/http/directory string /debian
|
||||
d-i mirror/http/proxy string
|
||||
|
||||
# User Configuration
|
||||
d-i passwd/root-login boolean false
|
||||
d-i passwd/user-fullname string ${build_username}
|
||||
d-i passwd/username string ${build_username}
|
||||
d-i passwd/user-password-crypted password ${build_password_encrypted}
|
||||
|
||||
# Package Configuration
|
||||
d-i pkgsel/run_tasksel boolean false
|
||||
d-i pkgsel/include string openssh-server qemu-guest-agent python3
|
||||
|
||||
# You can choose, if your system will report back on what software you have
|
||||
# installed, and what software you use. The default is not to report back,
|
||||
# but sending reports helps the project determine what software is most
|
||||
# popular and should be included on the first CD/DVD.
|
||||
popularity-contest popularity-contest/participate boolean false
|
||||
|
||||
### Boot loader installation
|
||||
# Grub is the boot loader (for x86).
|
||||
|
||||
# This is fairly safe to set, it makes grub install automatically to the UEFI
|
||||
# partition/boot record if no other operating system is detected on the machine.
|
||||
d-i grub-installer/only_debian boolean true
|
||||
|
||||
# Avoid that last message about the install being complete.
|
||||
d-i finish-install/reboot_in_progress note
|
||||
|
||||
# Post-install script
|
||||
# - Add User to Sudoers
|
||||
# - Remove lv_delete volume group
|
||||
d-i preseed/late_command string \
|
||||
echo '${build_username} ALL=(ALL) NOPASSWD: ALL' > /target/etc/sudoers.d/${build_username} ; \
|
||||
in-target chmod 440 /etc/sudoers.d/${build_username}%{ if length(lvm) != 0 ~} ; \
|
||||
lvremove -f /dev/%{ for volume_group in lvm ~}${volume_group.name}%{ endfor ~}/lv_delete > /dev/null 2>&1%{ endif }
|
||||
|
||||
%{ if common_data_source == "disk" ~}
|
||||
# Umount preseed media early
|
||||
d-i preseed/early_command string \
|
||||
umount /media && echo 1 > /sys/block/sr1/device/delete ;
|
||||
%{ endif ~}
|
||||
|
||||
157
builds/linux/debian/12/data/storage.pkrtpl.hcl
Normal file
157
builds/linux/debian/12/data/storage.pkrtpl.hcl
Normal file
@@ -0,0 +1,157 @@
|
||||
|
||||
%{~ if length(lvm) != 0 ~}
|
||||
d-i partman-auto/method string lvm
|
||||
d-i partman-auto-lvm/guided_size string max
|
||||
d-i partman-lvm/confirm boolean true
|
||||
d-i partman-lvm/confirm_nooverwrite boolean true
|
||||
d-i partman-lvm/device_remove_lvm boolean true
|
||||
%{~ for volume_group in lvm ~}
|
||||
d-i partman-auto-lvm/new_vg_name string ${volume_group.name}
|
||||
%{~ endfor ~}
|
||||
%{~ endif ~}
|
||||
|
||||
d-i partman-efi/non_efi_system boolean true
|
||||
|
||||
# Ensure the partition table is GPT - this is required for EFI
|
||||
d-i partman-partitioning/choose_label select gpt
|
||||
d-i partman-partitioning/default_label string gpt
|
||||
|
||||
# If there is only one partition defined and its name is 'autopart'
|
||||
# then use auto partitioning
|
||||
%{~ if length(partitions) == 1 && partitions[0].name == "autopart" ~}
|
||||
d-i partman-auto/disk string /dev/${device}
|
||||
%{~ if partitions[0].format.fstype == "lvm" ~}
|
||||
d-i partman-auto/method string lvm
|
||||
|
||||
# You can define the amount of space that will be used for the LVM volume
|
||||
# group. It can either be a size with its unit (eg. 20 GB), a percentage of
|
||||
# free space or the 'max' keyword.
|
||||
d-i partman-auto-lvm/guided_size string max
|
||||
|
||||
# If one of the disks that are going to be automatically partitioned
|
||||
# contains an old LVM configuration, the user will normally receive a
|
||||
# warning. This can be preseeded away...
|
||||
d-i partman-lvm/device_remove_lvm boolean true
|
||||
# And the same goes for the confirmation to write the lvm partitions.
|
||||
d-i partman-lvm/confirm boolean true
|
||||
d-i partman-lvm/confirm_nooverwrite boolean true
|
||||
|
||||
%{~ endif ~}
|
||||
%{~ if partitions[0].format.fstype == "simple" ~}
|
||||
d-i partman-auto/method string regular
|
||||
%{~ endif ~}
|
||||
%{ if partitions[0].format.fstype == "" ~}
|
||||
d-i partman-auto/method string regular
|
||||
%{~ endif ~}
|
||||
# You can choose one of the three predefined partitioning recipes:
|
||||
# - atomic: all files in one partition
|
||||
# - home: separate /home partition
|
||||
# - multi: separate /home, /var, and /tmp partitions
|
||||
d-i partman-auto/choose_recipe select atomic
|
||||
|
||||
%{~ else ~} # if length(partitions) == 1 && partitions[0].name == "autopart"
|
||||
%{~ if swap == false ~}
|
||||
d-i partman-basicfilesystems/no_swap boolean false
|
||||
%{~ endif ~}
|
||||
d-i partman-auto/expert_recipe string \
|
||||
custom :: \
|
||||
%{~ for partition in partitions ~}
|
||||
%{~ if lookup(partition, "volume_group", "") == "" ~}
|
||||
%{~ if partition.size != -1 ~}
|
||||
${partition.size} ${partition.size} ${partition.size} ${partition.format.fstype} \
|
||||
%{~ else ~}
|
||||
100 100 -1 ${partition.format.fstype} \
|
||||
%{~ endif ~}
|
||||
$primary{ } \
|
||||
%{~ if partition.mount.path == "/boot" ~}
|
||||
$bootable{ } \
|
||||
mountpoint{ /boot } \
|
||||
method{ format } \
|
||||
%{~ endif ~}
|
||||
%{~ if partition.mount.path == "/boot/efi" ~}
|
||||
mountpoint{ /boot/efi } \
|
||||
method{ efi } \
|
||||
%{~ endif ~}
|
||||
%{~ if partition.mount.path != "/boot" && partition.mount.path != "/boot/efi" ~}
|
||||
%{~ if partition.mount.path != "" ~}
|
||||
mountpoint{ ${partition.mount.path} } \
|
||||
%{~ endif ~}
|
||||
method{ ${partition.format.fstype} } \
|
||||
%{~ endif ~}
|
||||
format{ } \
|
||||
%{~ if partition.format.fstype != "swap" ~}
|
||||
use_filesystem{ } \
|
||||
%{~ if partition.format.fstype == "fat32" ~}
|
||||
filesystem{ vfat } \
|
||||
%{~ else ~}
|
||||
filesystem{ ${partition.format.fstype} } \
|
||||
%{~ endif ~}
|
||||
%{~ endif ~}
|
||||
label { ${partition.format.label} } \
|
||||
%{~ for option in split(",", lookup(partition.mount, "options", "")) ~}
|
||||
%{~ if option != "" ~}
|
||||
options/${option}{ ${option} } \
|
||||
%{~ endif ~}
|
||||
%{~ endfor ~}
|
||||
. \
|
||||
%{~ else /* if lookup(partition, "volume_group", "") == "" */ ~}
|
||||
%{~ for volume_group in lvm ~}
|
||||
%{~ if volume_group.name == partition.volume_group ~}
|
||||
%{~ for partition in volume_group.partitions ~}
|
||||
%{ if partition.size != -1 ~}
|
||||
%{ if partition.format.fstype == "swap" ~}
|
||||
${partition.size} ${partition.size} ${partition.size} linux-swap \
|
||||
%{~ else ~}
|
||||
${partition.size} ${partition.size} ${partition.size} ${partition.format.fstype} \
|
||||
%{~ endif ~}
|
||||
%{~ else ~}
|
||||
%{~ if partition.format.fstype != "swap" /* I don't know who would fill their disk with swap but it could happen */ ~}
|
||||
100 100 -1 ${partition.format.fstype} \
|
||||
%{~ else ~}
|
||||
100 100 -1 linux-swap \
|
||||
%{~ endif ~}
|
||||
%{ endif ~}
|
||||
$lvmok{ } \
|
||||
%{~ if partition.mount.path != "" ~}
|
||||
mountpoint{ ${partition.mount.path} } \
|
||||
%{~ endif ~}
|
||||
lv_name{ ${partition.name} } \
|
||||
in_vg { ${volume_group.name} } \
|
||||
%{~ if partition.format.fstype == "swap" ~}
|
||||
method{ swap } \
|
||||
%{~ else ~}
|
||||
method{ format } \
|
||||
%{~ endif ~}
|
||||
format{ } \
|
||||
%{~ if partition.format.fstype != "swap" ~}
|
||||
use_filesystem{ } \
|
||||
filesystem{ ${partition.format.fstype} } \
|
||||
%{~ endif ~}
|
||||
label { ${partition.format.label} } \
|
||||
%{~ for option in split(",", lookup(partition.mount, "options", "")) ~}
|
||||
%{~ if option != "" ~}
|
||||
options/${option}{ ${option} } \
|
||||
%{~ endif ~}
|
||||
%{~ endfor ~}
|
||||
. \
|
||||
%{~ endfor /* partition in volume_group.partitions */ ~}
|
||||
1024 1024 1024 ext4 \
|
||||
method{ lvm } \
|
||||
$lvmok{ } \
|
||||
lv_name{ lv_delete } \
|
||||
mountpoint{ /tmp/lv_delete } \
|
||||
. \
|
||||
%{~ endif /* volume_group.name == partition.volume_group */ ~}
|
||||
%{~ endfor /* for volume_group in lvm */ ~}
|
||||
%{~ endif /* if lookup(partition, "volume_group", "") == "" */ ~}
|
||||
%{~ endfor /* for partition in partitions */ ~}
|
||||
|
||||
%{~ endif /* if length(partitions) == 1 && partitions[0].name == "autopart" */ ~}
|
||||
|
||||
d-i partman-partitioning/confirm_write_new_label boolean true
|
||||
d-i partman/choose_partition select finish
|
||||
d-i partman/confirm boolean true
|
||||
d-i partman/confirm_nooverwrite boolean true
|
||||
|
||||
# To make sure the machine can boot we install grub on the first harddisk:
|
||||
d-i grub-installer/bootdev string /dev/${device}
|
||||
45
builds/linux/debian/12/linux-debian.auto.pkrvars.hcl
Normal file
45
builds/linux/debian/12/linux-debian.auto.pkrvars.hcl
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Ubuntu Server 22.04 LTS variables used by the Packer Plugin for Proxmox (proxmox-iso).
|
||||
*/
|
||||
|
||||
// Guest Operating System Metadata
|
||||
vm_os_language = "en_US"
|
||||
vm_os_keyboard = "us"
|
||||
vm_os_timezone = "UTC"
|
||||
vm_os_family = "linux"
|
||||
vm_os_name = "debian"
|
||||
vm_os_version = "12"
|
||||
|
||||
// Virtual Machine Guest Operating System Setting
|
||||
vm_os_type = "l26"
|
||||
|
||||
// Virtual Machine Hardware Settings
|
||||
vm_bios = "seabios"
|
||||
vm_cpu_count = 1
|
||||
vm_cpu_sockets = 1
|
||||
vm_cpu_type = "kvm64"
|
||||
vm_mem_size = 2048
|
||||
vm_disk_type = "virtio"
|
||||
vm_disk_size = "32G"
|
||||
vm_disk_format = "raw"
|
||||
vm_storage_pool = "vm-data"
|
||||
vm_disk_controller_type = "virtio-scsi-pci"
|
||||
vm_network_card_model = "virtio"
|
||||
vm_bridge_interface = "vmbr0"
|
||||
vm_vlan_tag = "102"
|
||||
|
||||
// Removable Media Settings
|
||||
iso_path = "iso"
|
||||
iso_file = "debian-12.2.0-amd64-netinst.iso"
|
||||
iso_checksum = "file:https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/SHA512SUMS"
|
||||
|
||||
// Boot Settings
|
||||
vm_boot = "order=virtio0;ide2;net0"
|
||||
vm_boot_wait = "5s"
|
||||
|
||||
// EFI Settings
|
||||
vm_firmware_path = "./OVMF.fd"
|
||||
vm_efi_storage_pool = "vm-data"
|
||||
vm_efi_pre_enrolled_keys = false
|
||||
vm_efi_type = "4m"
|
||||
202
builds/linux/debian/12/linux-debian.pkr.hcl
Normal file
202
builds/linux/debian/12/linux-debian.pkr.hcl
Normal file
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Debian 11 template using the Packer Builder for Proxmox (proxmox-iso).
|
||||
*/
|
||||
|
||||
// BLOCK: packer
|
||||
// The Packer configuration.
|
||||
|
||||
packer {
|
||||
required_version = ">= 1.9.1"
|
||||
required_plugins {
|
||||
ansible = {
|
||||
source = "github.com/hashicorp/ansible"
|
||||
version = "~> 1"
|
||||
}
|
||||
git = {
|
||||
version = ">= 0.4.2"
|
||||
source = "github.com/ethanmdavidson/git"
|
||||
}
|
||||
proxmox = {
|
||||
version = ">= 1.0.6"
|
||||
source = "github.com/hashicorp/proxmox"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BLOCK: data
|
||||
// Defines the data sources.
|
||||
|
||||
data "git-repository" "cwd" {}
|
||||
|
||||
// BLOCK: locals
|
||||
// Defines the local variables.
|
||||
|
||||
locals {
|
||||
build_by = "Built by: HashiCorp Packer ${packer.version}"
|
||||
build_date = formatdate("DD-MM-YYYY hh:mm ZZZ", "${timestamp()}" )
|
||||
build_version = data.git-repository.cwd.head
|
||||
build_description = "Version: ${local.build_version}\nBuilt on: ${local.build_date}\n${local.build_by}\nCloud-Init: ${var.vm_cloud_init_enable}"
|
||||
vm_disk_type = var.vm_disk_type == "virtio" ? "vda" : "sda"
|
||||
manifest_date = formatdate("YYYY-MM-DD hh:mm:ss", timestamp())
|
||||
manifest_path = "${path.cwd}/manifests/"
|
||||
manifest_output = "${local.manifest_path}${local.manifest_date}.json"
|
||||
data_source_content = {
|
||||
"/preseed.cfg" = templatefile("${abspath(path.root)}/data/preseed.pkrtpl.hcl", {
|
||||
build_username = var.build_username
|
||||
build_password = var.build_password
|
||||
build_password_encrypted = var.build_password_encrypted
|
||||
vm_disk_type = local.vm_disk_type
|
||||
vm_os_language = var.vm_os_language
|
||||
vm_os_keyboard = var.vm_os_keyboard
|
||||
vm_os_timezone = var.vm_os_timezone
|
||||
common_data_source = var.common_data_source
|
||||
# lvm needs to be here so late commands can access vg names
|
||||
lvm = var.vm_disk_lvm
|
||||
storage = templatefile("${abspath(path.root)}/data/storage.pkrtpl.hcl", {
|
||||
device = var.vm_disk_device
|
||||
swap = var.vm_disk_use_swap
|
||||
partitions = var.vm_disk_partitions
|
||||
lvm = var.vm_disk_lvm
|
||||
vm_bios = var.vm_bios
|
||||
})
|
||||
})
|
||||
}
|
||||
data_source_command = var.common_data_source == "http" ? "url=http://{{.HTTPIP}}:{{.HTTPPort}}/preseed.cfg" : "file=/media/preseed.cfg"
|
||||
vm_name = "${var.vm_os_family}-${var.vm_os_name}-${var.vm_os_version}"
|
||||
vm_bios = var.vm_bios == "ovmf" ? var.vm_firmware_path : null
|
||||
}
|
||||
|
||||
// BLOCK: source
|
||||
// Defines the builder configuration blocks.
|
||||
|
||||
source "proxmox-iso" "debian" {
|
||||
|
||||
// Proxmox Connection Settings and Credentials
|
||||
proxmox_url = "https://${var.proxmox_hostname}:8006/api2/json"
|
||||
username = "${var.proxmox_api_token_id}"
|
||||
token = "${var.proxmox_api_token_secret}"
|
||||
insecure_skip_tls_verify = "${var.proxmox_insecure_connection}"
|
||||
|
||||
// Proxmox Settings
|
||||
node = "${var.proxmox_node}"
|
||||
|
||||
// Virtual Machine Settings
|
||||
vm_name = "${local.vm_name}"
|
||||
bios = "${var.vm_bios}"
|
||||
sockets = "${var.vm_cpu_sockets}"
|
||||
cores = "${var.vm_cpu_count}"
|
||||
cpu_type = "${var.vm_cpu_type}"
|
||||
memory = "${var.vm_mem_size}"
|
||||
os = "${var.vm_os_type}"
|
||||
scsi_controller = "${var.vm_disk_controller_type}"
|
||||
disks {
|
||||
disk_size = "${var.vm_disk_size}"
|
||||
type = "${var.vm_disk_type}"
|
||||
storage_pool = "${var.vm_storage_pool}"
|
||||
format = "${var.vm_disk_format}"
|
||||
}
|
||||
dynamic "efi_config" {
|
||||
for_each = var.vm_bios == "ovmf" ? [1] : []
|
||||
content {
|
||||
efi_storage_pool = var.vm_bios == "ovmf" ? var.vm_efi_storage_pool : null
|
||||
efi_type = var.vm_bios == "ovmf" ? var.vm_efi_type : null
|
||||
pre_enrolled_keys = var.vm_bios == "ovmf" ? var.vm_efi_pre_enrolled_keys : null
|
||||
}
|
||||
}
|
||||
unmount_iso = true
|
||||
ssh_username = "${var.build_username}"
|
||||
ssh_password = "${var.build_password}"
|
||||
ssh_timeout = "${var.timeout}"
|
||||
ssh_port = "22"
|
||||
iso_file = "${var.common_iso_storage}:${var.iso_path}/${var.iso_file}"
|
||||
iso_checksum = "${var.iso_checksum}"
|
||||
qemu_agent = true
|
||||
|
||||
network_adapters {
|
||||
bridge = "${var.vm_bridge_interface}"
|
||||
model = "${var.vm_network_card_model}"
|
||||
vlan_tag = "${var.vm_vlan_tag}"
|
||||
}
|
||||
|
||||
// Removable Media Settings
|
||||
http_content = "${var.common_data_source}" == "http" ? "${local.data_source_content}" : null
|
||||
|
||||
// Boot and Provisioning Settings
|
||||
http_bind_address = var.common_data_source == "http" ? var.common_http_bind_address : null
|
||||
http_port_min = var.common_data_source == "http" ? var.common_http_port_min : null
|
||||
http_port_max = var.common_data_source == "http" ? var.common_http_port_max : null
|
||||
boot = var.vm_boot
|
||||
boot_wait = var.vm_boot_wait
|
||||
boot_command = [
|
||||
"<wait><wait><wait><esc><wait><wait><wait>",
|
||||
"/install.amd/vmlinuz ",
|
||||
"initrd=/install.amd/initrd.gz ",
|
||||
"auto=true ",
|
||||
"${local.data_source_command} ",
|
||||
// "hostname=${var.vm_os_name}-${var.vm_os_version} ",
|
||||
"netcfg/get_hostname=debian netcfg/get_domain=example.com ",
|
||||
"interface=auto ",
|
||||
"vga=788 noprompt quiet --<enter>"
|
||||
]
|
||||
|
||||
dynamic "additional_iso_files" {
|
||||
for_each = var.common_data_source == "disk" ? [1] : []
|
||||
content {
|
||||
cd_files = var.common_data_source == "disk" ? local.data_source_content : null
|
||||
cd_label = var.common_data_source == "disk" ? "cidata" : null
|
||||
iso_storage_pool = var.common_data_source == "disk" ? "local" : null
|
||||
}
|
||||
}
|
||||
|
||||
template_name = "${local.vm_name}"
|
||||
template_description = "${local.build_description}"
|
||||
|
||||
# VM Cloud Init Settings
|
||||
cloud_init = var.vm_cloud_init_enable
|
||||
cloud_init_storage_pool = var.vm_cloud_init_enable == true ? var.vm_storage_pool : null
|
||||
|
||||
}
|
||||
|
||||
# Build Definition to create the VM Template
|
||||
build {
|
||||
sources = ["source.proxmox-iso.debian"]
|
||||
|
||||
provisioner "ansible" {
|
||||
user = "${var.build_username}"
|
||||
playbook_file = "${path.cwd}/ansible/main.yml"
|
||||
roles_path = "${path.cwd}/ansible/roles"
|
||||
ansible_env_vars = [
|
||||
"ANSIBLE_CONFIG=${path.cwd}/ansible/ansible.cfg"
|
||||
]
|
||||
extra_arguments = [
|
||||
"--extra-vars", "display_skipped_hosts=false",
|
||||
"--extra-vars", "BUILD_USERNAME=${var.build_username}",
|
||||
"--extra-vars", "BUILD_SECRET='${var.build_key}'",
|
||||
"--extra-vars", "ANSIBLE_USERNAME=${var.ansible_username}",
|
||||
"--extra-vars", "ANSIBLE_SECRET='${var.ansible_key}'",
|
||||
"--extra-vars", "cloud_init='${var.vm_cloud_init_enable}'",
|
||||
]
|
||||
}
|
||||
|
||||
post-processor "manifest" {
|
||||
output = local.manifest_output
|
||||
strip_path = true
|
||||
strip_time = true
|
||||
custom_data = {
|
||||
ansible_username = "${var.ansible_username}"
|
||||
build_username = "${var.build_username}"
|
||||
build_date = "${local.build_date}"
|
||||
build_version = "${local.build_version}"
|
||||
common_data_source = "${var.common_data_source}"
|
||||
vm_cpu_sockets = "${var.vm_cpu_sockets}"
|
||||
vm_cpu_count = "${var.vm_cpu_count}"
|
||||
vm_disk_size = "${var.vm_disk_size}"
|
||||
vm_bios = "${var.vm_bios}"
|
||||
vm_os_type = "${var.vm_os_type}"
|
||||
vm_mem_size = "${var.vm_mem_size}"
|
||||
vm_network_card_model = "${var.vm_network_card_model}"
|
||||
vm_cloud_init_enable = "${var.vm_cloud_init_enable}"
|
||||
}
|
||||
}
|
||||
}
|
||||
53
builds/linux/debian/12/variables-storage.pkr.hcl
Normal file
53
builds/linux/debian/12/variables-storage.pkr.hcl
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Debian 11 storage variables used by the Packer Plugin for Proxmox (proxmox-iso).
|
||||
*/
|
||||
|
||||
// VM Storage Settings
|
||||
|
||||
variable "vm_disk_device" {
|
||||
type = string
|
||||
description = "The device for the virtual disk. (e.g. 'sda')"
|
||||
}
|
||||
|
||||
variable "vm_disk_use_swap" {
|
||||
type = bool
|
||||
description = "Whether to use a swap partition."
|
||||
}
|
||||
|
||||
variable "vm_disk_partitions" {
|
||||
type = list(object({
|
||||
name = string
|
||||
size = number
|
||||
format = object({
|
||||
label = string
|
||||
fstype = string
|
||||
})
|
||||
mount = object({
|
||||
path = string
|
||||
options = string
|
||||
})
|
||||
volume_group = string
|
||||
}))
|
||||
description = "The disk partitions for the virtual disk."
|
||||
}
|
||||
|
||||
variable "vm_disk_lvm" {
|
||||
type = list(object({
|
||||
name = string
|
||||
partitions = list(object({
|
||||
name = string
|
||||
size = number
|
||||
format = object({
|
||||
label = string
|
||||
fstype = string
|
||||
})
|
||||
mount = object({
|
||||
path = string
|
||||
options = string
|
||||
})
|
||||
}))
|
||||
}))
|
||||
description = "The LVM configuration for the virtual disk."
|
||||
default = []
|
||||
}
|
||||
297
builds/linux/debian/12/variables.pkr.hcl
Normal file
297
builds/linux/debian/12/variables.pkr.hcl
Normal file
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Debian 11 variables using the Packer Builder for Proxmox (proxmox-iso).
|
||||
*/
|
||||
|
||||
// BLOCK: variable
|
||||
// Defines the input variables.
|
||||
|
||||
// Proxmox Credentials
|
||||
|
||||
variable "proxmox_hostname" {
|
||||
type = string
|
||||
description = "The FQDN or IP address of a Proxmox node. Only one node should be specified in a cluster."
|
||||
}
|
||||
|
||||
variable "proxmox_api_token_id" {
|
||||
type = string
|
||||
description = "The token to login to the Proxmox node/cluster. The format is USER@REALM!TOKENID. (e.g. packer@pam!packer_pve_token)"
|
||||
}
|
||||
|
||||
variable "proxmox_api_token_secret" {
|
||||
type = string
|
||||
description = "The secret for the API token used to login to the Proxmox API."
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
variable "proxmox_insecure_connection" {
|
||||
description = "true/false to skip Proxmox TLS certificate checks."
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
// Proxmox Settings
|
||||
|
||||
variable "proxmox_node" {
|
||||
type = string
|
||||
description = "The name of the Proxmox node that Packer will build templates on."
|
||||
}
|
||||
|
||||
// Virtual Machine Settings
|
||||
|
||||
variable "vm_os_language" {
|
||||
type = string
|
||||
description = "The guest operating system language."
|
||||
default = "en_US"
|
||||
}
|
||||
|
||||
variable "vm_os_keyboard" {
|
||||
type = string
|
||||
description = "The guest operating system keyboard layout."
|
||||
default = "us"
|
||||
}
|
||||
|
||||
variable "vm_os_timezone" {
|
||||
type = string
|
||||
description = "The guest operating system timezone."
|
||||
default = "UTC"
|
||||
}
|
||||
|
||||
variable "vm_os_family" {
|
||||
type = string
|
||||
description = "The guest operating system family. Used for naming. (e.g. 'linux')"
|
||||
}
|
||||
|
||||
variable "vm_os_name" {
|
||||
type = string
|
||||
description = "The guest operating system name. Used for naming. (e.g. 'ubuntu')"
|
||||
}
|
||||
|
||||
variable "vm_os_version" {
|
||||
type = string
|
||||
description = "The guest operating system version. Used for naming. (e.g. '22-04-lts')"
|
||||
}
|
||||
|
||||
variable "vm_os_type" {
|
||||
type = string
|
||||
description = "The guest operating system type. (e.g. 'l26')"
|
||||
}
|
||||
|
||||
variable "vm_bios" {
|
||||
type = string
|
||||
description = "The firmware type. Allowed values 'ovmf' or 'seabios'"
|
||||
default = "OVMF"
|
||||
|
||||
validation {
|
||||
condition = contains(["ovmf", "seabios"], var.vm_bios)
|
||||
error_message = "The vm_bios value must be 'ovmf' or 'seabios'."
|
||||
}
|
||||
}
|
||||
|
||||
variable "vm_firmware_path" {
|
||||
type = string
|
||||
description = "The firmware file to be used. Needed for EFI"
|
||||
default = "/usr/share/ovmf/OVMF.fd"
|
||||
}
|
||||
|
||||
variable "vm_efi_storage_pool" {
|
||||
type = string
|
||||
description = "Set the UEFI disk storage location. (e.g. 'local-lvm')"
|
||||
}
|
||||
|
||||
variable "vm_efi_type" {
|
||||
type = string
|
||||
description = "Specifies the version of the OVMF firmware to be used. (e.g. '4m')"
|
||||
}
|
||||
|
||||
variable "vm_efi_pre_enrolled_keys" {
|
||||
type = bool
|
||||
description = "Whether Microsoft Standard Secure Boot keys should be pre-loaded on the EFI disk. (e.g. false)"
|
||||
}
|
||||
|
||||
variable "vm_cpu_count" {
|
||||
type = number
|
||||
description = "The number of virtual CPUs. (e.g. '2')"
|
||||
}
|
||||
|
||||
variable "vm_cpu_sockets" {
|
||||
type = number
|
||||
description = "The number of virtual CPU sockets. (e.g. '1')"
|
||||
}
|
||||
|
||||
variable "vm_cpu_type" {
|
||||
type = string
|
||||
description = "The CPU type to emulate. See the Proxmox API documentation for the complete list of accepted values. For best performance, set this to host. Defaults to kvm64."
|
||||
}
|
||||
|
||||
variable "vm_mem_size" {
|
||||
type = number
|
||||
description = "The size for the virtual memory in MB. (e.g. '2048')"
|
||||
}
|
||||
|
||||
variable "vm_disk_controller_type" {
|
||||
type = string
|
||||
description = "The SCSI controller model to emulate. (e.g. 'virtio-scsi-pci')"
|
||||
}
|
||||
|
||||
variable "vm_disk_type" {
|
||||
type = string
|
||||
description = "The type of disk to emulate. (e.g. 'virtio')"
|
||||
}
|
||||
|
||||
variable "vm_storage_pool" {
|
||||
type = string
|
||||
description = "The name of the Proxmox storage pool to store the VM template. (e.g. 'local-lvm')"
|
||||
}
|
||||
|
||||
variable "vm_disk_size" {
|
||||
type = string
|
||||
description = "The size for the virtual disk in GB. (e.g. '32G')"
|
||||
}
|
||||
|
||||
variable "vm_disk_format" {
|
||||
type = string
|
||||
description = "The format of the file backing the disk. (e.g. 'qcow2')"
|
||||
}
|
||||
|
||||
variable "vm_network_card_model" {
|
||||
type = string
|
||||
description = "The model of the virtual network adapter to emulate. (e.g. 'virtio')"
|
||||
}
|
||||
|
||||
variable "vm_bridge_interface" {
|
||||
type = string
|
||||
description = "The name of the Proxmox bridge to attach the adapter to."
|
||||
}
|
||||
|
||||
variable "vm_vlan_tag" {
|
||||
type = string
|
||||
description = "If the adapter should tag packets, give the VLAN ID. (e.g. '102')"
|
||||
}
|
||||
|
||||
// Cloud-Init Settings
|
||||
|
||||
variable "vm_cloud_init_enable" {
|
||||
type = bool
|
||||
description = "Enable or disable cloud-init drive in Proxmox. (e.g. false)"
|
||||
default = false
|
||||
}
|
||||
|
||||
// Removable Media Settings
|
||||
|
||||
variable "common_iso_storage" {
|
||||
type = string
|
||||
description = "The name of the source Proxmox storage location for ISO images. (e.g. 'local-lvm')"
|
||||
}
|
||||
|
||||
variable "iso_path" {
|
||||
type = string
|
||||
description = "The path on the source Proxmox storage location for ISO images. (e.g. 'iso')"
|
||||
}
|
||||
|
||||
variable "iso_file" {
|
||||
type = string
|
||||
description = "The file name of the ISO image used by the vendor. (e.g. 'ubuntu-<version>-live-server-amd64.iso')"
|
||||
}
|
||||
|
||||
variable "iso_checksum" {
|
||||
type = string
|
||||
description = "The checksum value of the ISO image provided by the vendor."
|
||||
}
|
||||
|
||||
// Boot Settings
|
||||
|
||||
variable "common_data_source" {
|
||||
type = string
|
||||
description = "The provisioning data source. (e.g. 'http' or 'disk')"
|
||||
}
|
||||
|
||||
variable "common_http_bind_address" {
|
||||
type = string
|
||||
description = "Define an IP address on the host to use for the HTTP server."
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "common_http_port_min" {
|
||||
type = number
|
||||
description = "The start of the HTTP port range."
|
||||
}
|
||||
|
||||
variable "common_http_port_max" {
|
||||
type = number
|
||||
description = "The end of the HTTP port range."
|
||||
}
|
||||
|
||||
variable "vm_boot" {
|
||||
type = string
|
||||
description = "The boot order for virtual machine devices. (e.g. 'order=virtio0;ide2;net0')"
|
||||
}
|
||||
|
||||
variable "vm_boot_wait" {
|
||||
type = string
|
||||
description = "The time to wait after booting the initial VM before typing the boot_command (e.g '10s')"
|
||||
}
|
||||
|
||||
variable "common_ip_wait_timeout" {
|
||||
type = string
|
||||
description = "Time to wait for guest operating system IP address response."
|
||||
}
|
||||
|
||||
variable "common_shutdown_timeout" {
|
||||
type = string
|
||||
description = "Time to wait for guest operating system shutdown."
|
||||
}
|
||||
|
||||
// Communicator Settings and Credentials
|
||||
|
||||
variable "build_username" {
|
||||
type = string
|
||||
description = "The username to login to the guest operating system. (e.g. 'ubuntu')"
|
||||
# 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 to the guest operating system."
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
variable "build_key" {
|
||||
type = string
|
||||
description = "The SSH public key to login to the guest operating system."
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
variable "timeout" {
|
||||
description = "not sure why I need so high a timeout but here we are"
|
||||
default = "90m"
|
||||
}
|
||||
|
||||
// Ansible Credentials
|
||||
|
||||
variable "ansible_username" {
|
||||
type = string
|
||||
description = "The username for Ansible to login to the guest operating system. (e.g. 'ansible')"
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
variable "ansible_key" {
|
||||
type = string
|
||||
description = "The public key for Ansible to login to the guest operating system."
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
// HCP Packer Settings
|
||||
|
||||
variable "common_hcp_packer_registry_enabled" {
|
||||
type = bool
|
||||
description = "Enable the HCP Packer registry."
|
||||
default = false
|
||||
}
|
||||
|
||||
0
builds/linux/ubuntu/20-04-lts/data/meta-data
Normal file
0
builds/linux/ubuntu/20-04-lts/data/meta-data
Normal file
109
builds/linux/ubuntu/20-04-lts/data/storage.pkrtpl.hcl
Normal file
109
builds/linux/ubuntu/20-04-lts/data/storage.pkrtpl.hcl
Normal file
@@ -0,0 +1,109 @@
|
||||
%{~ if length(partitions) == 1 && partitions[0].name == "autopart" ~}
|
||||
%{~ if partitions[0].format.fstype == "lvm" ~}
|
||||
storage:
|
||||
layout:
|
||||
name: lvm
|
||||
%{~ endif ~}
|
||||
%{~ if partitions[0].format.fstype == "simple" ~}
|
||||
storage:
|
||||
layout:
|
||||
name: direct
|
||||
%{~ endif ~}
|
||||
%{~ if partitions[0].format.fstype == "" ~}
|
||||
storage:
|
||||
layout:
|
||||
name: direct
|
||||
%{~ endif ~}
|
||||
%{~ else ~}
|
||||
storage:
|
||||
config:
|
||||
- ptable: gpt
|
||||
path: /dev/${device}
|
||||
wipe: superblock
|
||||
preserve: false
|
||||
name: ''
|
||||
%{ if vm_bios == "ovmf" ~}
|
||||
grub_device: false
|
||||
%{ endif ~}
|
||||
%{ if vm_bios == "seabios" ~}
|
||||
grub_device: true
|
||||
%{ endif ~}
|
||||
type: disk
|
||||
id: disk-${device}
|
||||
# BIOS boot partition
|
||||
%{ for index, partition in partitions ~}
|
||||
- device: disk-${device}
|
||||
%{ if partition.size != -1 ~}
|
||||
size: ${partition.size}M
|
||||
%{ else ~}
|
||||
size: ${partition.size}
|
||||
%{ endif ~}
|
||||
wipe: superblock
|
||||
preserve: false
|
||||
%{ if partition.name == "bios_grub" && vm_bios == "seabios" && index == 0 ~}
|
||||
flag: bios_grub
|
||||
grub_device: false
|
||||
%{ endif ~}
|
||||
%{ if partition.mount.path == "/boot/efi" && index == 0 ~}
|
||||
flag: boot
|
||||
grub_device: true
|
||||
%{ endif ~}
|
||||
type: partition
|
||||
id: partition-${partition.name}
|
||||
%{ if partition.format.fstype != "" ~}
|
||||
- id: format-${partition.name}
|
||||
type: format
|
||||
volume: partition-${partition.name}
|
||||
label: ${partition.format.label}
|
||||
fstype: ${partition.format.fstype}
|
||||
%{ endif ~}
|
||||
# Don't create a mount for the GRUB partition when using BIOS
|
||||
%{ if partition.volume_group == "" && partition.name != "bios_grub" ~}
|
||||
- id: mount-${partition.name}
|
||||
type: mount
|
||||
%{ if partition.mount.path == "" ~}
|
||||
path: none
|
||||
%{ else ~}
|
||||
path: ${partition.mount.path}
|
||||
%{ endif ~}
|
||||
device: format-${partition.name}
|
||||
%{ if partition.mount.options != "" ~}
|
||||
options: ${partition.mount.options}
|
||||
%{ endif ~}
|
||||
%{ endif ~}
|
||||
%{ endfor ~}
|
||||
%{ for index, volume_group in lvm ~}
|
||||
- id: volgroup-${volume_group.name}
|
||||
type: lvm_volgroup
|
||||
name: ${volume_group.name}
|
||||
devices:
|
||||
%{ for index, partition in partitions ~}
|
||||
%{ if lookup(partition, "volume_group", "") == volume_group.name ~}
|
||||
- partition-${partition.name}
|
||||
%{ endif ~}
|
||||
%{ endfor ~}
|
||||
%{ for index, partition in volume_group.partitions ~}
|
||||
- id: partition-${partition.name}
|
||||
type: lvm_partition
|
||||
name: ${partition.name}
|
||||
size: ${partition.size}M
|
||||
volgroup: volgroup-${volume_group.name}
|
||||
- id: format-${partition.name}
|
||||
type: format
|
||||
volume: partition-${partition.name}
|
||||
label: ${partition.format.label}
|
||||
fstype: ${partition.format.fstype}
|
||||
- id: mount-${partition.name}
|
||||
type: mount
|
||||
%{ if partition.mount.path == "" ~}
|
||||
path: none
|
||||
%{ else ~}
|
||||
path: ${partition.mount.path}
|
||||
%{ endif ~}
|
||||
device: format-${partition.name}
|
||||
%{ if partition.mount.options != "" ~}
|
||||
options: ${partition.mount.options}
|
||||
%{ endif ~}
|
||||
%{ endfor ~}
|
||||
%{ endfor ~}
|
||||
%{~ endif ~}
|
||||
35
builds/linux/ubuntu/20-04-lts/data/user-data.pkrtpl.hcl
Normal file
35
builds/linux/ubuntu/20-04-lts/data/user-data.pkrtpl.hcl
Normal file
@@ -0,0 +1,35 @@
|
||||
#cloud-config
|
||||
autoinstall:
|
||||
version: 1
|
||||
apt:
|
||||
geoip: true
|
||||
preserve_sources_list: false
|
||||
primary:
|
||||
- arches: [amd64, i386]
|
||||
uri: http://archive.ubuntu.com/ubuntu
|
||||
- arches: [default]
|
||||
uri: http://ports.ubuntu.com/ubuntu-ports
|
||||
early-commands:
|
||||
- sudo systemctl stop ssh
|
||||
locale: ${vm_os_language}
|
||||
keyboard:
|
||||
layout: ${vm_os_keyboard}
|
||||
${storage}
|
||||
identity:
|
||||
hostname: ubuntu-server
|
||||
username: ${build_username}
|
||||
password: ${build_password_encrypted}
|
||||
ssh:
|
||||
install-server: true
|
||||
allow-pw: true
|
||||
packages:
|
||||
- openssh-server
|
||||
- qemu-guest-agent
|
||||
- cloud-init
|
||||
user-data:
|
||||
disable_root: false
|
||||
timezone: ${vm_os_timezone}
|
||||
late-commands:
|
||||
- sed -i -e 's/^#\?PasswordAuthentication.*/PasswordAuthentication yes/g' /target/etc/ssh/sshd_config
|
||||
- echo '${build_username} ALL=(ALL) NOPASSWD:ALL' > /target/etc/sudoers.d/${build_username}
|
||||
- curtin in-target --target=/target -- chmod 440 /etc/sudoers.d/${build_username}
|
||||
45
builds/linux/ubuntu/20-04-lts/linux-ubuntu.auto.pkrvars.hcl
Normal file
45
builds/linux/ubuntu/20-04-lts/linux-ubuntu.auto.pkrvars.hcl
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Ubuntu Server 20.04 LTS variables used by the Packer Plugin for Proxmox (proxmox-iso).
|
||||
*/
|
||||
|
||||
// Guest Operating System Metadata
|
||||
vm_os_language = "en_US"
|
||||
vm_os_keyboard = "us"
|
||||
vm_os_timezone = "UTC"
|
||||
vm_os_family = "linux"
|
||||
vm_os_name = "ubuntu"
|
||||
vm_os_version = "20.04-lts"
|
||||
|
||||
// Virtual Machine Guest Operating System Setting
|
||||
vm_os_type = "l26"
|
||||
|
||||
// Virtual Machine Hardware Settings
|
||||
vm_bios = "seabios"
|
||||
vm_cpu_count = 1
|
||||
vm_cpu_sockets = 1
|
||||
vm_cpu_type = "kvm64"
|
||||
vm_mem_size = 2048
|
||||
vm_disk_type = "virtio"
|
||||
vm_disk_size = "32G"
|
||||
vm_disk_format = "raw"
|
||||
vm_storage_pool = "vm-data"
|
||||
vm_disk_controller_type = "virtio-scsi-pci"
|
||||
vm_network_card_model = "virtio"
|
||||
vm_bridge_interface = "vmbr0"
|
||||
vm_vlan_tag = "102"
|
||||
|
||||
// Removable Media Settings
|
||||
iso_path = "iso"
|
||||
iso_file = "ubuntu-20.04-live-server-amd64.iso"
|
||||
iso_checksum = "caf3fd69c77c439f162e2ba6040e9c320c4ff0d69aad1340a514319a9264df9f"
|
||||
|
||||
// Boot Settings
|
||||
vm_boot = "order=virtio0;ide2;net0"
|
||||
vm_boot_wait = "5s"
|
||||
|
||||
// EFI Settings
|
||||
vm_firmware_path = "./OVMF.fd"
|
||||
vm_efi_storage_pool = "vm-data"
|
||||
vm_efi_pre_enrolled_keys = false
|
||||
vm_efi_type = "4m"
|
||||
200
builds/linux/ubuntu/20-04-lts/linux-ubuntu.pkr.hcl
Normal file
200
builds/linux/ubuntu/20-04-lts/linux-ubuntu.pkr.hcl
Normal file
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Ubuntu Server 20.04 LTS template using the Packer Builder for Proxmox (proxmox-iso).
|
||||
*/
|
||||
|
||||
// BLOCK: packer
|
||||
// The Packer configuration.
|
||||
|
||||
packer {
|
||||
required_version = ">= 1.9.1"
|
||||
required_plugins {
|
||||
ansible = {
|
||||
source = "github.com/hashicorp/ansible"
|
||||
version = "~> 1"
|
||||
}
|
||||
git = {
|
||||
version = ">= 0.4.2"
|
||||
source = "github.com/ethanmdavidson/git"
|
||||
}
|
||||
proxmox = {
|
||||
version = ">= 1.0.6"
|
||||
source = "github.com/hashicorp/proxmox"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BLOCK: data
|
||||
// Defines the data sources.
|
||||
|
||||
data "git-repository" "cwd" {}
|
||||
|
||||
// BLOCK: locals
|
||||
// Defines the local variables.
|
||||
|
||||
locals {
|
||||
build_by = "Built by: HashiCorp Packer ${packer.version}"
|
||||
build_date = formatdate("DD-MM-YYYY hh:mm ZZZ", "${timestamp()}" )
|
||||
build_version = data.git-repository.cwd.head
|
||||
build_description = "Version: ${local.build_version}\nBuilt on: ${local.build_date}\n${local.build_by}\nCloud-Init: ${var.vm_cloud_init_enable}"
|
||||
vm_disk_type = var.vm_disk_type == "virtio" ? "vda" : "sda"
|
||||
manifest_date = formatdate("YYYY-MM-DD hh:mm:ss", timestamp())
|
||||
manifest_path = "${path.cwd}/manifests/"
|
||||
manifest_output = "${local.manifest_path}${local.manifest_date}.json"
|
||||
data_source_content = {
|
||||
"/meta-data" = file("${abspath(path.root)}/data/meta-data")
|
||||
"/user-data" = templatefile("${abspath(path.root)}/data/user-data.pkrtpl.hcl", {
|
||||
build_username = var.build_username
|
||||
build_password = var.build_password
|
||||
build_password_encrypted = var.build_password_encrypted
|
||||
vm_disk_type = local.vm_disk_type
|
||||
vm_os_language = var.vm_os_language
|
||||
vm_os_keyboard = var.vm_os_keyboard
|
||||
vm_os_timezone = var.vm_os_timezone
|
||||
storage = templatefile("${abspath(path.root)}/data/storage.pkrtpl.hcl", {
|
||||
device = var.vm_disk_device
|
||||
swap = var.vm_disk_use_swap
|
||||
partitions = var.vm_disk_partitions
|
||||
lvm = var.vm_disk_lvm
|
||||
vm_bios = var.vm_bios
|
||||
})
|
||||
})
|
||||
}
|
||||
# For some reason 20.04 doesn't like quotes in the boot commands
|
||||
data_source_command = var.common_data_source == "http" ? "ds=nocloud-net;seedfrom=http://{{.HTTPIP}}:{{.HTTPPort}}/" : "ds=nocloud"
|
||||
vm_name = "${var.vm_os_family}-${var.vm_os_name}-${var.vm_os_version}"
|
||||
vm_bios = var.vm_bios == "ovmf" ? var.vm_firmware_path : null
|
||||
}
|
||||
|
||||
// BLOCK: source
|
||||
// Defines the builder configuration blocks.
|
||||
|
||||
source "proxmox-iso" "ubuntu" {
|
||||
|
||||
// Proxmox Connection Settings and Credentials
|
||||
proxmox_url = "https://${var.proxmox_hostname}:8006/api2/json"
|
||||
username = "${var.proxmox_api_token_id}"
|
||||
token = "${var.proxmox_api_token_secret}"
|
||||
insecure_skip_tls_verify = "${var.proxmox_insecure_connection}"
|
||||
|
||||
// Proxmox Settings
|
||||
node = "${var.proxmox_node}"
|
||||
|
||||
// Virtual Machine Settings
|
||||
vm_name = "${local.vm_name}"
|
||||
bios = "${var.vm_bios}"
|
||||
sockets = "${var.vm_cpu_sockets}"
|
||||
cores = "${var.vm_cpu_count}"
|
||||
cpu_type = "${var.vm_cpu_type}"
|
||||
memory = "${var.vm_mem_size}"
|
||||
os = "${var.vm_os_type}"
|
||||
scsi_controller = "${var.vm_disk_controller_type}"
|
||||
disks {
|
||||
disk_size = "${var.vm_disk_size}"
|
||||
type = "${var.vm_disk_type}"
|
||||
storage_pool = "${var.vm_storage_pool}"
|
||||
format = "${var.vm_disk_format}"
|
||||
}
|
||||
dynamic "efi_config" {
|
||||
for_each = var.vm_bios == "ovmf" ? [1] : []
|
||||
content {
|
||||
efi_storage_pool = var.vm_bios == "ovmf" ? var.vm_efi_storage_pool : null
|
||||
efi_type = var.vm_bios == "ovmf" ? var.vm_efi_type : null
|
||||
pre_enrolled_keys = var.vm_bios == "ovmf" ? var.vm_efi_pre_enrolled_keys : null
|
||||
}
|
||||
}
|
||||
unmount_iso = true
|
||||
ssh_username = "${var.build_username}"
|
||||
ssh_password = "${var.build_password}"
|
||||
ssh_timeout = "${var.timeout}"
|
||||
ssh_port = "22"
|
||||
iso_file = "${var.common_iso_storage}:${var.iso_path}/${var.iso_file}"
|
||||
iso_checksum = "${var.iso_checksum}"
|
||||
qemu_agent = true
|
||||
|
||||
network_adapters {
|
||||
bridge = "${var.vm_bridge_interface}"
|
||||
model = "${var.vm_network_card_model}"
|
||||
vlan_tag = "${var.vm_vlan_tag}"
|
||||
}
|
||||
|
||||
// Removable Media Settings
|
||||
http_content = "${var.common_data_source}" == "http" ? "${local.data_source_content}" : null
|
||||
|
||||
// Boot and Provisioning Settings
|
||||
http_bind_address = var.common_data_source == "http" ? var.common_http_bind_address : null
|
||||
http_port_min = var.common_data_source == "http" ? var.common_http_port_min : null
|
||||
http_port_max = var.common_data_source == "http" ? var.common_http_port_max : null
|
||||
boot = var.vm_boot
|
||||
boot_wait = var.vm_boot_wait
|
||||
boot_command = [
|
||||
"<esc><esc><esc>",
|
||||
"<enter><wait>",
|
||||
"/casper/vmlinuz ",
|
||||
"root=/dev/sr0 ",
|
||||
"initrd=/casper/initrd ",
|
||||
"autoinstall ",
|
||||
"${local.data_source_command}",
|
||||
"<enter>"
|
||||
]
|
||||
|
||||
dynamic "additional_iso_files" {
|
||||
for_each = var.common_data_source == "disk" ? [1] : []
|
||||
content {
|
||||
cd_files = var.common_data_source == "disk" ? local.data_source_content : null
|
||||
cd_label = var.common_data_source == "disk" ? "cidata" : null
|
||||
iso_storage_pool = var.common_data_source == "disk" ? "local" : null
|
||||
}
|
||||
}
|
||||
|
||||
template_name = "${local.vm_name}"
|
||||
template_description = "${local.build_description}"
|
||||
|
||||
# VM Cloud Init Settings
|
||||
cloud_init = var.vm_cloud_init_enable
|
||||
cloud_init_storage_pool = var.vm_cloud_init_enable == true ? var.vm_storage_pool : null
|
||||
|
||||
}
|
||||
|
||||
# Build Definition to create the VM Template
|
||||
build {
|
||||
sources = ["source.proxmox-iso.ubuntu"]
|
||||
|
||||
provisioner "ansible" {
|
||||
user = "${var.build_username}"
|
||||
playbook_file = "${path.cwd}/ansible/main.yml"
|
||||
roles_path = "${path.cwd}/ansible/roles"
|
||||
ansible_env_vars = [
|
||||
"ANSIBLE_CONFIG=${path.cwd}/ansible/ansible.cfg"
|
||||
]
|
||||
extra_arguments = [
|
||||
"--extra-vars", "display_skipped_hosts=false",
|
||||
"--extra-vars", "BUILD_USERNAME=${var.build_username}",
|
||||
"--extra-vars", "BUILD_SECRET='${var.build_key}'",
|
||||
"--extra-vars", "ANSIBLE_USERNAME=${var.ansible_username}",
|
||||
"--extra-vars", "ANSIBLE_SECRET='${var.ansible_key}'",
|
||||
"--extra-vars", "cloud_init='${var.vm_cloud_init_enable}'",
|
||||
]
|
||||
}
|
||||
|
||||
post-processor "manifest" {
|
||||
output = local.manifest_output
|
||||
strip_path = true
|
||||
strip_time = true
|
||||
custom_data = {
|
||||
ansible_username = "${var.ansible_username}"
|
||||
build_username = "${var.build_username}"
|
||||
build_date = "${local.build_date}"
|
||||
build_version = "${local.build_version}"
|
||||
common_data_source = "${var.common_data_source}"
|
||||
vm_cpu_sockets = "${var.vm_cpu_sockets}"
|
||||
vm_cpu_count = "${var.vm_cpu_count}"
|
||||
vm_disk_size = "${var.vm_disk_size}"
|
||||
vm_bios = "${var.vm_bios}"
|
||||
vm_os_type = "${var.vm_os_type}"
|
||||
vm_mem_size = "${var.vm_mem_size}"
|
||||
vm_network_card_model = "${var.vm_network_card_model}"
|
||||
vm_cloud_init_enable = "${var.vm_cloud_init_enable}"
|
||||
}
|
||||
}
|
||||
}
|
||||
53
builds/linux/ubuntu/20-04-lts/variables-storage.pkr.hcl
Normal file
53
builds/linux/ubuntu/20-04-lts/variables-storage.pkr.hcl
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Ubuntu Server 20.04 LTS storage variables used by the Packer Plugin for Proxmox (proxmox-iso).
|
||||
*/
|
||||
|
||||
// VM Storage Settings
|
||||
|
||||
variable "vm_disk_device" {
|
||||
type = string
|
||||
description = "The device for the virtual disk. (e.g. 'sda')"
|
||||
}
|
||||
|
||||
variable "vm_disk_use_swap" {
|
||||
type = bool
|
||||
description = "Whether to use a swap partition."
|
||||
}
|
||||
|
||||
variable "vm_disk_partitions" {
|
||||
type = list(object({
|
||||
name = string
|
||||
size = number
|
||||
format = object({
|
||||
label = string
|
||||
fstype = string
|
||||
})
|
||||
mount = object({
|
||||
path = string
|
||||
options = string
|
||||
})
|
||||
volume_group = string
|
||||
}))
|
||||
description = "The disk partitions for the virtual disk."
|
||||
}
|
||||
|
||||
variable "vm_disk_lvm" {
|
||||
type = list(object({
|
||||
name = string
|
||||
partitions = list(object({
|
||||
name = string
|
||||
size = number
|
||||
format = object({
|
||||
label = string
|
||||
fstype = string
|
||||
})
|
||||
mount = object({
|
||||
path = string
|
||||
options = string
|
||||
})
|
||||
}))
|
||||
}))
|
||||
description = "The LVM configuration for the virtual disk."
|
||||
default = []
|
||||
}
|
||||
297
builds/linux/ubuntu/20-04-lts/variables.pkr.hcl
Normal file
297
builds/linux/ubuntu/20-04-lts/variables.pkr.hcl
Normal file
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Ubuntu Server 20.04 LTS variables using the Packer Builder for Proxmox (proxmox-iso).
|
||||
*/
|
||||
|
||||
// BLOCK: variable
|
||||
// Defines the input variables.
|
||||
|
||||
// Proxmox Credentials
|
||||
|
||||
variable "proxmox_hostname" {
|
||||
type = string
|
||||
description = "The FQDN or IP address of a Proxmox node. Only one node should be specified in a cluster."
|
||||
}
|
||||
|
||||
variable "proxmox_api_token_id" {
|
||||
type = string
|
||||
description = "The token to login to the Proxmox node/cluster. The format is USER@REALM!TOKENID. (e.g. packer@pam!packer_pve_token)"
|
||||
}
|
||||
|
||||
variable "proxmox_api_token_secret" {
|
||||
type = string
|
||||
description = "The secret for the API token used to login to the Proxmox API."
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
variable "proxmox_insecure_connection" {
|
||||
description = "true/false to skip Proxmox TLS certificate checks."
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
// Proxmox Settings
|
||||
|
||||
variable "proxmox_node" {
|
||||
type = string
|
||||
description = "The name of the Proxmox node that Packer will build templates on."
|
||||
}
|
||||
|
||||
// Virtual Machine Settings
|
||||
|
||||
variable "vm_os_language" {
|
||||
type = string
|
||||
description = "The guest operating system language."
|
||||
default = "en_US"
|
||||
}
|
||||
|
||||
variable "vm_os_keyboard" {
|
||||
type = string
|
||||
description = "The guest operating system keyboard layout."
|
||||
default = "us"
|
||||
}
|
||||
|
||||
variable "vm_os_timezone" {
|
||||
type = string
|
||||
description = "The guest operating system timezone."
|
||||
default = "UTC"
|
||||
}
|
||||
|
||||
variable "vm_os_family" {
|
||||
type = string
|
||||
description = "The guest operating system family. Used for naming. (e.g. 'linux')"
|
||||
}
|
||||
|
||||
variable "vm_os_name" {
|
||||
type = string
|
||||
description = "The guest operating system name. Used for naming. (e.g. 'ubuntu')"
|
||||
}
|
||||
|
||||
variable "vm_os_version" {
|
||||
type = string
|
||||
description = "The guest operating system version. Used for naming. (e.g. '22-04-lts')"
|
||||
}
|
||||
|
||||
variable "vm_os_type" {
|
||||
type = string
|
||||
description = "The guest operating system type. (e.g. 'l26')"
|
||||
}
|
||||
|
||||
variable "vm_bios" {
|
||||
type = string
|
||||
description = "The firmware type. Allowed values 'ovmf' or 'seabios'"
|
||||
default = "OVMF"
|
||||
|
||||
validation {
|
||||
condition = contains(["ovmf", "seabios"], var.vm_bios)
|
||||
error_message = "The vm_bios value must be 'ovmf' or 'seabios'."
|
||||
}
|
||||
}
|
||||
|
||||
variable "vm_firmware_path" {
|
||||
type = string
|
||||
description = "The firmware file to be used. Needed for EFI"
|
||||
default = "/usr/share/ovmf/OVMF.fd"
|
||||
}
|
||||
|
||||
variable "vm_efi_storage_pool" {
|
||||
type = string
|
||||
description = "Set the UEFI disk storage location. (e.g. 'local-lvm')"
|
||||
}
|
||||
|
||||
variable "vm_efi_type" {
|
||||
type = string
|
||||
description = "Specifies the version of the OVMF firmware to be used. (e.g. '4m')"
|
||||
}
|
||||
|
||||
variable "vm_efi_pre_enrolled_keys" {
|
||||
type = bool
|
||||
description = "Whether Microsoft Standard Secure Boot keys should be pre-loaded on the EFI disk. (e.g. false)"
|
||||
}
|
||||
|
||||
variable "vm_cpu_count" {
|
||||
type = number
|
||||
description = "The number of virtual CPUs. (e.g. '2')"
|
||||
}
|
||||
|
||||
variable "vm_cpu_sockets" {
|
||||
type = number
|
||||
description = "The number of virtual CPU sockets. (e.g. '1')"
|
||||
}
|
||||
|
||||
variable "vm_cpu_type" {
|
||||
type = string
|
||||
description = "The CPU type to emulate. See the Proxmox API documentation for the complete list of accepted values. For best performance, set this to host. Defaults to kvm64."
|
||||
}
|
||||
|
||||
variable "vm_mem_size" {
|
||||
type = number
|
||||
description = "The size for the virtual memory in MB. (e.g. '2048')"
|
||||
}
|
||||
|
||||
variable "vm_disk_controller_type" {
|
||||
type = string
|
||||
description = "The SCSI controller model to emulate. (e.g. 'virtio-scsi-pci')"
|
||||
}
|
||||
|
||||
variable "vm_disk_type" {
|
||||
type = string
|
||||
description = "The type of disk to emulate. (e.g. 'virtio')"
|
||||
}
|
||||
|
||||
variable "vm_storage_pool" {
|
||||
type = string
|
||||
description = "The name of the Proxmox storage pool to store the VM template. (e.g. 'local-lvm')"
|
||||
}
|
||||
|
||||
variable "vm_disk_size" {
|
||||
type = string
|
||||
description = "The size for the virtual disk in GB. (e.g. '32G')"
|
||||
}
|
||||
|
||||
variable "vm_disk_format" {
|
||||
type = string
|
||||
description = "The format of the file backing the disk. (e.g. 'qcow2')"
|
||||
}
|
||||
|
||||
variable "vm_network_card_model" {
|
||||
type = string
|
||||
description = "The model of the virtual network adapter to emulate. (e.g. 'virtio')"
|
||||
}
|
||||
|
||||
variable "vm_bridge_interface" {
|
||||
type = string
|
||||
description = "The name of the Proxmox bridge to attach the adapter to."
|
||||
}
|
||||
|
||||
variable "vm_vlan_tag" {
|
||||
type = string
|
||||
description = "If the adapter should tag packets, give the VLAN ID. (e.g. '102')"
|
||||
}
|
||||
|
||||
// Cloud-Init Settings
|
||||
|
||||
variable "vm_cloud_init_enable" {
|
||||
type = bool
|
||||
description = "Enable or disable cloud-init drive in Proxmox. (e.g. false)"
|
||||
default = false
|
||||
}
|
||||
|
||||
// Removable Media Settings
|
||||
|
||||
variable "common_iso_storage" {
|
||||
type = string
|
||||
description = "The name of the source Proxmox storage location for ISO images. (e.g. 'local-lvm')"
|
||||
}
|
||||
|
||||
variable "iso_path" {
|
||||
type = string
|
||||
description = "The path on the source Proxmox storage location for ISO images. (e.g. 'iso')"
|
||||
}
|
||||
|
||||
variable "iso_file" {
|
||||
type = string
|
||||
description = "The file name of the ISO image used by the vendor. (e.g. 'ubuntu-<version>-live-server-amd64.iso')"
|
||||
}
|
||||
|
||||
variable "iso_checksum" {
|
||||
type = string
|
||||
description = "The checksum value of the ISO image provided by the vendor."
|
||||
}
|
||||
|
||||
// Boot Settings
|
||||
|
||||
variable "common_data_source" {
|
||||
type = string
|
||||
description = "The provisioning data source. (e.g. 'http' or 'disk')"
|
||||
}
|
||||
|
||||
variable "common_http_bind_address" {
|
||||
type = string
|
||||
description = "Define an IP address on the host to use for the HTTP server."
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "common_http_port_min" {
|
||||
type = number
|
||||
description = "The start of the HTTP port range."
|
||||
}
|
||||
|
||||
variable "common_http_port_max" {
|
||||
type = number
|
||||
description = "The end of the HTTP port range."
|
||||
}
|
||||
|
||||
variable "vm_boot" {
|
||||
type = string
|
||||
description = "The boot order for virtual machine devices. (e.g. 'order=virtio0;ide2;net0')"
|
||||
}
|
||||
|
||||
variable "vm_boot_wait" {
|
||||
type = string
|
||||
description = "The time to wait after booting the initial VM before typing the boot_command (e.g '10s')"
|
||||
}
|
||||
|
||||
variable "common_ip_wait_timeout" {
|
||||
type = string
|
||||
description = "Time to wait for guest operating system IP address response."
|
||||
}
|
||||
|
||||
variable "common_shutdown_timeout" {
|
||||
type = string
|
||||
description = "Time to wait for guest operating system shutdown."
|
||||
}
|
||||
|
||||
// Communicator Settings and Credentials
|
||||
|
||||
variable "build_username" {
|
||||
type = string
|
||||
description = "The username to login to the guest operating system. (e.g. 'ubuntu')"
|
||||
# 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 to the guest operating system."
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
variable "build_key" {
|
||||
type = string
|
||||
description = "The SSH public key to login to the guest operating system."
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
variable "timeout" {
|
||||
description = "not sure why I need so high a timeout but here we are"
|
||||
default = "90m"
|
||||
}
|
||||
|
||||
// Ansible Credentials
|
||||
|
||||
variable "ansible_username" {
|
||||
type = string
|
||||
description = "The username for Ansible to login to the guest operating system. (e.g. 'ansible')"
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
variable "ansible_key" {
|
||||
type = string
|
||||
description = "The public key for Ansible to login to the guest operating system."
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
// HCP Packer Settings
|
||||
|
||||
variable "common_hcp_packer_registry_enabled" {
|
||||
type = bool
|
||||
description = "Enable the HCP Packer registry."
|
||||
default = false
|
||||
}
|
||||
|
||||
0
builds/linux/ubuntu/22-04-lts/data/meta-data
Normal file
0
builds/linux/ubuntu/22-04-lts/data/meta-data
Normal file
109
builds/linux/ubuntu/22-04-lts/data/storage.pkrtpl.hcl
Normal file
109
builds/linux/ubuntu/22-04-lts/data/storage.pkrtpl.hcl
Normal file
@@ -0,0 +1,109 @@
|
||||
%{~ if length(partitions) == 1 && partitions[0].name == "autopart" ~}
|
||||
%{~ if partitions[0].format.fstype == "lvm" ~}
|
||||
storage:
|
||||
layout:
|
||||
name: lvm
|
||||
%{~ endif ~}
|
||||
%{~ if partitions[0].format.fstype == "simple" ~}
|
||||
storage:
|
||||
layout:
|
||||
name: direct
|
||||
%{~ endif ~}
|
||||
%{~ if partitions[0].format.fstype == "" ~}
|
||||
storage:
|
||||
layout:
|
||||
name: direct
|
||||
%{~ endif ~}
|
||||
%{~ else ~}
|
||||
storage:
|
||||
config:
|
||||
- ptable: gpt
|
||||
path: /dev/${device}
|
||||
wipe: superblock
|
||||
preserve: false
|
||||
name: ''
|
||||
%{ if vm_bios == "ovmf" ~}
|
||||
grub_device: false
|
||||
%{ endif ~}
|
||||
%{ if vm_bios == "seabios" ~}
|
||||
grub_device: true
|
||||
%{ endif ~}
|
||||
type: disk
|
||||
id: disk-${device}
|
||||
# BIOS boot partition
|
||||
%{ for index, partition in partitions ~}
|
||||
- device: disk-${device}
|
||||
%{ if partition.size != -1 ~}
|
||||
size: ${partition.size}M
|
||||
%{ else ~}
|
||||
size: ${partition.size}
|
||||
%{ endif ~}
|
||||
wipe: superblock
|
||||
preserve: false
|
||||
%{ if partition.name == "bios_grub" && vm_bios == "seabios" && index == 0 ~}
|
||||
flag: bios_grub
|
||||
grub_device: false
|
||||
%{ endif ~}
|
||||
%{ if partition.mount.path == "/boot/efi" && index == 0 ~}
|
||||
flag: boot
|
||||
grub_device: true
|
||||
%{ endif ~}
|
||||
type: partition
|
||||
id: partition-${partition.name}
|
||||
%{ if partition.format.fstype != "" ~}
|
||||
- id: format-${partition.name}
|
||||
type: format
|
||||
volume: partition-${partition.name}
|
||||
label: ${partition.format.label}
|
||||
fstype: ${partition.format.fstype}
|
||||
%{ endif ~}
|
||||
# Don't create a mount for the GRUB partition when using BIOS
|
||||
%{ if partition.volume_group == "" && partition.name != "bios_grub" ~}
|
||||
- id: mount-${partition.name}
|
||||
type: mount
|
||||
%{ if partition.mount.path == "" ~}
|
||||
path: none
|
||||
%{ else ~}
|
||||
path: ${partition.mount.path}
|
||||
%{ endif ~}
|
||||
device: format-${partition.name}
|
||||
%{ if partition.mount.options != "" ~}
|
||||
options: ${partition.mount.options}
|
||||
%{ endif ~}
|
||||
%{ endif ~}
|
||||
%{ endfor ~}
|
||||
%{ for index, volume_group in lvm ~}
|
||||
- id: volgroup-${volume_group.name}
|
||||
type: lvm_volgroup
|
||||
name: ${volume_group.name}
|
||||
devices:
|
||||
%{ for index, partition in partitions ~}
|
||||
%{ if lookup(partition, "volume_group", "") == volume_group.name ~}
|
||||
- partition-${partition.name}
|
||||
%{ endif ~}
|
||||
%{ endfor ~}
|
||||
%{ for index, partition in volume_group.partitions ~}
|
||||
- id: partition-${partition.name}
|
||||
type: lvm_partition
|
||||
name: ${partition.name}
|
||||
size: ${partition.size}M
|
||||
volgroup: volgroup-${volume_group.name}
|
||||
- id: format-${partition.name}
|
||||
type: format
|
||||
volume: partition-${partition.name}
|
||||
label: ${partition.format.label}
|
||||
fstype: ${partition.format.fstype}
|
||||
- id: mount-${partition.name}
|
||||
type: mount
|
||||
%{ if partition.mount.path == "" ~}
|
||||
path: none
|
||||
%{ else ~}
|
||||
path: ${partition.mount.path}
|
||||
%{ endif ~}
|
||||
device: format-${partition.name}
|
||||
%{ if partition.mount.options != "" ~}
|
||||
options: ${partition.mount.options}
|
||||
%{ endif ~}
|
||||
%{ endfor ~}
|
||||
%{ endfor ~}
|
||||
%{~ endif ~}
|
||||
27
builds/linux/ubuntu/22-04-lts/data/user-data.pkrtpl.hcl
Normal file
27
builds/linux/ubuntu/22-04-lts/data/user-data.pkrtpl.hcl
Normal file
@@ -0,0 +1,27 @@
|
||||
#cloud-config
|
||||
autoinstall:
|
||||
version: 1
|
||||
early-commands:
|
||||
- sudo systemctl stop ssh
|
||||
locale: ${vm_os_language}
|
||||
keyboard:
|
||||
layout: ${vm_os_keyboard}
|
||||
${storage}
|
||||
identity:
|
||||
hostname: ubuntu-server
|
||||
username: ${build_username}
|
||||
password: ${build_password_encrypted}
|
||||
ssh:
|
||||
install-server: true
|
||||
allow-pw: true
|
||||
packages:
|
||||
- openssh-server
|
||||
- qemu-guest-agent
|
||||
- cloud-init
|
||||
user-data:
|
||||
disable_root: false
|
||||
timezone: ${vm_os_timezone}
|
||||
late-commands:
|
||||
- sed -i -e 's/^#\?PasswordAuthentication.*/PasswordAuthentication yes/g' /target/etc/ssh/sshd_config
|
||||
- echo '${build_username} ALL=(ALL) NOPASSWD:ALL' > /target/etc/sudoers.d/${build_username}
|
||||
- curtin in-target --target=/target -- chmod 440 /etc/sudoers.d/${build_username}
|
||||
45
builds/linux/ubuntu/22-04-lts/linux-ubuntu.auto.pkrvars.hcl
Normal file
45
builds/linux/ubuntu/22-04-lts/linux-ubuntu.auto.pkrvars.hcl
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Ubuntu Server 22.04 LTS variables used by the Packer Plugin for Proxmox (proxmox-iso).
|
||||
*/
|
||||
|
||||
// Guest Operating System Metadata
|
||||
vm_os_language = "en_US"
|
||||
vm_os_keyboard = "us"
|
||||
vm_os_timezone = "UTC"
|
||||
vm_os_family = "linux"
|
||||
vm_os_name = "ubuntu"
|
||||
vm_os_version = "22.04-lts"
|
||||
|
||||
// Virtual Machine Guest Operating System Setting
|
||||
vm_os_type = "l26"
|
||||
|
||||
// Virtual Machine Hardware Settings
|
||||
vm_bios = "seabios"
|
||||
vm_cpu_count = 1
|
||||
vm_cpu_sockets = 1
|
||||
vm_cpu_type = "kvm64"
|
||||
vm_mem_size = 2048
|
||||
vm_disk_type = "virtio"
|
||||
vm_disk_size = "32G"
|
||||
vm_disk_format = "raw"
|
||||
vm_storage_pool = "vm-data"
|
||||
vm_disk_controller_type = "virtio-scsi-pci"
|
||||
vm_network_card_model = "virtio"
|
||||
vm_bridge_interface = "vmbr0"
|
||||
vm_vlan_tag = "102"
|
||||
|
||||
// Removable Media Settings
|
||||
iso_path = "iso"
|
||||
iso_file = "ubuntu-22.04-live-server-amd64.iso"
|
||||
iso_checksum = "84aeaf7823c8c61baa0ae862d0a06b03409394800000b3235854a6b38eb4856f"
|
||||
|
||||
// Boot Settings
|
||||
vm_boot = "order=virtio0;ide2;net0"
|
||||
vm_boot_wait = "5s"
|
||||
|
||||
// EFI Settings
|
||||
vm_firmware_path = "./OVMF.fd"
|
||||
vm_efi_storage_pool = "vm-data"
|
||||
vm_efi_pre_enrolled_keys = false
|
||||
vm_efi_type = "4m"
|
||||
198
builds/linux/ubuntu/22-04-lts/linux-ubuntu.pkr.hcl
Normal file
198
builds/linux/ubuntu/22-04-lts/linux-ubuntu.pkr.hcl
Normal file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Ubuntu Server 22.04 LTS template using the Packer Builder for VMware vSphere (vsphere-iso).
|
||||
*/
|
||||
|
||||
// BLOCK: packer
|
||||
// The Packer configuration.
|
||||
|
||||
packer {
|
||||
required_version = ">= 1.9.1"
|
||||
required_plugins {
|
||||
ansible = {
|
||||
source = "github.com/hashicorp/ansible"
|
||||
version = "~> 1"
|
||||
}
|
||||
git = {
|
||||
version = ">= 0.4.2"
|
||||
source = "github.com/ethanmdavidson/git"
|
||||
}
|
||||
proxmox = {
|
||||
version = ">= 1.0.6"
|
||||
source = "github.com/hashicorp/proxmox"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BLOCK: data
|
||||
// Defines the data sources.
|
||||
|
||||
data "git-repository" "cwd" {}
|
||||
|
||||
// BLOCK: locals
|
||||
// Defines the local variables.
|
||||
|
||||
locals {
|
||||
build_by = "Built by: HashiCorp Packer ${packer.version}"
|
||||
build_date = formatdate("DD-MM-YYYY hh:mm ZZZ", "${timestamp()}" )
|
||||
build_version = data.git-repository.cwd.head
|
||||
build_description = "Version: ${local.build_version}\nBuilt on: ${local.build_date}\n${local.build_by}\nCloud-Init: ${var.vm_cloud_init_enable}"
|
||||
vm_disk_type = var.vm_disk_type == "virtio" ? "vda" : "sda"
|
||||
manifest_date = formatdate("YYYY-MM-DD hh:mm:ss", timestamp())
|
||||
manifest_path = "${path.cwd}/manifests/"
|
||||
manifest_output = "${local.manifest_path}${local.manifest_date}.json"
|
||||
data_source_content = {
|
||||
"/meta-data" = file("${abspath(path.root)}/data/meta-data")
|
||||
"/user-data" = templatefile("${abspath(path.root)}/data/user-data.pkrtpl.hcl", {
|
||||
build_username = var.build_username
|
||||
build_password = var.build_password
|
||||
build_password_encrypted = var.build_password_encrypted
|
||||
vm_disk_type = local.vm_disk_type
|
||||
vm_os_language = var.vm_os_language
|
||||
vm_os_keyboard = var.vm_os_keyboard
|
||||
vm_os_timezone = var.vm_os_timezone
|
||||
storage = templatefile("${abspath(path.root)}/data/storage.pkrtpl.hcl", {
|
||||
device = var.vm_disk_device
|
||||
swap = var.vm_disk_use_swap
|
||||
partitions = var.vm_disk_partitions
|
||||
lvm = var.vm_disk_lvm
|
||||
vm_bios = var.vm_bios
|
||||
})
|
||||
})
|
||||
}
|
||||
data_source_command = var.common_data_source == "http" ? "ds=\"nocloud-net;seedfrom=http://{{.HTTPIP}}:{{.HTTPPort}}/\"" : "ds=\"nocloud\""
|
||||
vm_name = "${var.vm_os_family}-${var.vm_os_name}-${var.vm_os_version}"
|
||||
vm_bios = var.vm_bios == "ovmf" ? var.vm_firmware_path : null
|
||||
}
|
||||
|
||||
// BLOCK: source
|
||||
// Defines the builder configuration blocks.
|
||||
|
||||
source "proxmox-iso" "ubuntu" {
|
||||
|
||||
// Proxmox Connection Settings and Credentials
|
||||
proxmox_url = "https://${var.proxmox_hostname}:8006/api2/json"
|
||||
username = "${var.proxmox_api_token_id}"
|
||||
token = "${var.proxmox_api_token_secret}"
|
||||
insecure_skip_tls_verify = "${var.proxmox_insecure_connection}"
|
||||
|
||||
// Proxmox Settings
|
||||
node = "${var.proxmox_node}"
|
||||
|
||||
// Virtual Machine Settings
|
||||
vm_name = "${local.vm_name}"
|
||||
bios = "${var.vm_bios}"
|
||||
sockets = "${var.vm_cpu_sockets}"
|
||||
cores = "${var.vm_cpu_count}"
|
||||
cpu_type = "${var.vm_cpu_type}"
|
||||
memory = "${var.vm_mem_size}"
|
||||
os = "${var.vm_os_type}"
|
||||
scsi_controller = "${var.vm_disk_controller_type}"
|
||||
disks {
|
||||
disk_size = "${var.vm_disk_size}"
|
||||
type = "${var.vm_disk_type}"
|
||||
storage_pool = "${var.vm_storage_pool}"
|
||||
format = "${var.vm_disk_format}"
|
||||
}
|
||||
dynamic "efi_config" {
|
||||
for_each = var.vm_bios == "ovmf" ? [1] : []
|
||||
content {
|
||||
efi_storage_pool = var.vm_bios == "ovmf" ? var.vm_efi_storage_pool : null
|
||||
efi_type = var.vm_bios == "ovmf" ? var.vm_efi_type : null
|
||||
pre_enrolled_keys = var.vm_bios == "ovmf" ? var.vm_efi_pre_enrolled_keys : null
|
||||
}
|
||||
}
|
||||
unmount_iso = true
|
||||
ssh_username = "${var.build_username}"
|
||||
ssh_password = "${var.build_password}"
|
||||
ssh_timeout = "${var.timeout}"
|
||||
ssh_port = "22"
|
||||
iso_file = "${var.common_iso_storage}:${var.iso_path}/${var.iso_file}"
|
||||
iso_checksum = "${var.iso_checksum}"
|
||||
qemu_agent = true
|
||||
|
||||
network_adapters {
|
||||
bridge = "${var.vm_bridge_interface}"
|
||||
model = "${var.vm_network_card_model}"
|
||||
vlan_tag = "${var.vm_vlan_tag}"
|
||||
}
|
||||
|
||||
// Removable Media Settings
|
||||
http_content = "${var.common_data_source}" == "http" ? "${local.data_source_content}" : null
|
||||
|
||||
// Boot and Provisioning Settings
|
||||
http_bind_address = var.common_data_source == "http" ? var.common_http_bind_address : null
|
||||
http_port_min = var.common_data_source == "http" ? var.common_http_port_min : null
|
||||
http_port_max = var.common_data_source == "http" ? var.common_http_port_max : null
|
||||
boot = var.vm_boot
|
||||
boot_wait = var.vm_boot_wait
|
||||
boot_command = [
|
||||
"c<wait5>",
|
||||
"linux /casper/vmlinuz --- autoinstall ${local.data_source_command}",
|
||||
"<enter><wait10>",
|
||||
"initrd /casper/initrd",
|
||||
"<enter><wait10>",
|
||||
"boot",
|
||||
"<enter>"
|
||||
]
|
||||
|
||||
dynamic "additional_iso_files" {
|
||||
for_each = var.common_data_source == "disk" ? [1] : []
|
||||
content {
|
||||
cd_files = var.common_data_source == "disk" ? local.data_source_content : null
|
||||
cd_label = var.common_data_source == "disk" ? "cidata" : null
|
||||
iso_storage_pool = var.common_data_source == "disk" ? "local" : null
|
||||
}
|
||||
}
|
||||
|
||||
template_name = "${local.vm_name}"
|
||||
template_description = "${local.build_description}"
|
||||
|
||||
# VM Cloud Init Settings
|
||||
cloud_init = var.vm_cloud_init_enable
|
||||
cloud_init_storage_pool = var.vm_cloud_init_enable == true ? var.vm_storage_pool : null
|
||||
|
||||
}
|
||||
|
||||
# Build Definition to create the VM Template
|
||||
build {
|
||||
sources = ["source.proxmox-iso.ubuntu"]
|
||||
|
||||
provisioner "ansible" {
|
||||
user = "${var.build_username}"
|
||||
playbook_file = "${path.cwd}/ansible/main.yml"
|
||||
roles_path = "${path.cwd}/ansible/roles"
|
||||
ansible_env_vars = [
|
||||
"ANSIBLE_CONFIG=${path.cwd}/ansible/ansible.cfg"
|
||||
]
|
||||
extra_arguments = [
|
||||
"--extra-vars", "display_skipped_hosts=false",
|
||||
"--extra-vars", "BUILD_USERNAME=${var.build_username}",
|
||||
"--extra-vars", "BUILD_SECRET='${var.build_key}'",
|
||||
"--extra-vars", "ANSIBLE_USERNAME=${var.ansible_username}",
|
||||
"--extra-vars", "ANSIBLE_SECRET='${var.ansible_key}'",
|
||||
"--extra-vars", "cloud_init='${var.vm_cloud_init_enable}'",
|
||||
]
|
||||
}
|
||||
|
||||
post-processor "manifest" {
|
||||
output = local.manifest_output
|
||||
strip_path = true
|
||||
strip_time = true
|
||||
custom_data = {
|
||||
ansible_username = "${var.ansible_username}"
|
||||
build_username = "${var.build_username}"
|
||||
build_date = "${local.build_date}"
|
||||
build_version = "${local.build_version}"
|
||||
common_data_source = "${var.common_data_source}"
|
||||
vm_cpu_sockets = "${var.vm_cpu_sockets}"
|
||||
vm_cpu_count = "${var.vm_cpu_count}"
|
||||
vm_disk_size = "${var.vm_disk_size}"
|
||||
vm_bios = "${var.vm_bios}"
|
||||
vm_os_type = "${var.vm_os_type}"
|
||||
vm_mem_size = "${var.vm_mem_size}"
|
||||
vm_network_card_model = "${var.vm_network_card_model}"
|
||||
vm_cloud_init_enable = "${var.vm_cloud_init_enable}"
|
||||
}
|
||||
}
|
||||
}
|
||||
53
builds/linux/ubuntu/22-04-lts/variables-storage.pkr.hcl
Normal file
53
builds/linux/ubuntu/22-04-lts/variables-storage.pkr.hcl
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Ubuntu Server 22.04 LTS storage variables used by the Packer Plugin for VMware vSphere (vsphere-iso).
|
||||
*/
|
||||
|
||||
// VM Storage Settings
|
||||
|
||||
variable "vm_disk_device" {
|
||||
type = string
|
||||
description = "The device for the virtual disk. (e.g. 'sda')"
|
||||
}
|
||||
|
||||
variable "vm_disk_use_swap" {
|
||||
type = bool
|
||||
description = "Whether to use a swap partition."
|
||||
}
|
||||
|
||||
variable "vm_disk_partitions" {
|
||||
type = list(object({
|
||||
name = string
|
||||
size = number
|
||||
format = object({
|
||||
label = string
|
||||
fstype = string
|
||||
})
|
||||
mount = object({
|
||||
path = string
|
||||
options = string
|
||||
})
|
||||
volume_group = string
|
||||
}))
|
||||
description = "The disk partitions for the virtual disk."
|
||||
}
|
||||
|
||||
variable "vm_disk_lvm" {
|
||||
type = list(object({
|
||||
name = string
|
||||
partitions = list(object({
|
||||
name = string
|
||||
size = number
|
||||
format = object({
|
||||
label = string
|
||||
fstype = string
|
||||
})
|
||||
mount = object({
|
||||
path = string
|
||||
options = string
|
||||
})
|
||||
}))
|
||||
}))
|
||||
description = "The LVM configuration for the virtual disk."
|
||||
default = []
|
||||
}
|
||||
297
builds/linux/ubuntu/22-04-lts/variables.pkr.hcl
Normal file
297
builds/linux/ubuntu/22-04-lts/variables.pkr.hcl
Normal file
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Ubuntu Server 22.04 LTS variables using the Packer Builder for Proxmox (proxmox-iso).
|
||||
*/
|
||||
|
||||
// BLOCK: variable
|
||||
// Defines the input variables.
|
||||
|
||||
// Proxmox Credentials
|
||||
|
||||
variable "proxmox_hostname" {
|
||||
type = string
|
||||
description = "The FQDN or IP address of a Proxmox node. Only one node should be specified in a cluster."
|
||||
}
|
||||
|
||||
variable "proxmox_api_token_id" {
|
||||
type = string
|
||||
description = "The token to login to the Proxmox node/cluster. The format is USER@REALM!TOKENID. (e.g. packer@pam!packer_pve_token)"
|
||||
}
|
||||
|
||||
variable "proxmox_api_token_secret" {
|
||||
type = string
|
||||
description = "The secret for the API token used to login to the Proxmox API."
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
variable "proxmox_insecure_connection" {
|
||||
description = "true/false to skip Proxmox TLS certificate checks."
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
// Proxmox Settings
|
||||
|
||||
variable "proxmox_node" {
|
||||
type = string
|
||||
description = "The name of the Proxmox node that Packer will build templates on."
|
||||
}
|
||||
|
||||
// Virtual Machine Settings
|
||||
|
||||
variable "vm_os_language" {
|
||||
type = string
|
||||
description = "The guest operating system language."
|
||||
default = "en_US"
|
||||
}
|
||||
|
||||
variable "vm_os_keyboard" {
|
||||
type = string
|
||||
description = "The guest operating system keyboard layout."
|
||||
default = "us"
|
||||
}
|
||||
|
||||
variable "vm_os_timezone" {
|
||||
type = string
|
||||
description = "The guest operating system timezone."
|
||||
default = "UTC"
|
||||
}
|
||||
|
||||
variable "vm_os_family" {
|
||||
type = string
|
||||
description = "The guest operating system family. Used for naming. (e.g. 'linux')"
|
||||
}
|
||||
|
||||
variable "vm_os_name" {
|
||||
type = string
|
||||
description = "The guest operating system name. Used for naming. (e.g. 'ubuntu')"
|
||||
}
|
||||
|
||||
variable "vm_os_version" {
|
||||
type = string
|
||||
description = "The guest operating system version. Used for naming. (e.g. '22-04-lts')"
|
||||
}
|
||||
|
||||
variable "vm_os_type" {
|
||||
type = string
|
||||
description = "The guest operating system type. (e.g. 'l26')"
|
||||
}
|
||||
|
||||
variable "vm_bios" {
|
||||
type = string
|
||||
description = "The firmware type. Allowed values 'ovmf' or 'seabios'"
|
||||
default = "OVMF"
|
||||
|
||||
validation {
|
||||
condition = contains(["ovmf", "seabios"], var.vm_bios)
|
||||
error_message = "The vm_bios value must be 'ovmf' or 'seabios'."
|
||||
}
|
||||
}
|
||||
|
||||
variable "vm_firmware_path" {
|
||||
type = string
|
||||
description = "The firmware file to be used. Needed for EFI"
|
||||
default = "/usr/share/ovmf/OVMF.fd"
|
||||
}
|
||||
|
||||
variable "vm_efi_storage_pool" {
|
||||
type = string
|
||||
description = "Set the UEFI disk storage location. (e.g. 'local-lvm')"
|
||||
}
|
||||
|
||||
variable "vm_efi_type" {
|
||||
type = string
|
||||
description = "Specifies the version of the OVMF firmware to be used. (e.g. '4m')"
|
||||
}
|
||||
|
||||
variable "vm_efi_pre_enrolled_keys" {
|
||||
type = bool
|
||||
description = "Whether Microsoft Standard Secure Boot keys should be pre-loaded on the EFI disk. (e.g. false)"
|
||||
}
|
||||
|
||||
variable "vm_cpu_count" {
|
||||
type = number
|
||||
description = "The number of virtual CPUs. (e.g. '2')"
|
||||
}
|
||||
|
||||
variable "vm_cpu_sockets" {
|
||||
type = number
|
||||
description = "The number of virtual CPU sockets. (e.g. '1')"
|
||||
}
|
||||
|
||||
variable "vm_cpu_type" {
|
||||
type = string
|
||||
description = "The CPU type to emulate. See the Proxmox API documentation for the complete list of accepted values. For best performance, set this to host. Defaults to kvm64."
|
||||
}
|
||||
|
||||
variable "vm_mem_size" {
|
||||
type = number
|
||||
description = "The size for the virtual memory in MB. (e.g. '2048')"
|
||||
}
|
||||
|
||||
variable "vm_disk_controller_type" {
|
||||
type = string
|
||||
description = "The SCSI controller model to emulate. (e.g. 'virtio-scsi-pci')"
|
||||
}
|
||||
|
||||
variable "vm_disk_type" {
|
||||
type = string
|
||||
description = "The type of disk to emulate. (e.g. 'virtio')"
|
||||
}
|
||||
|
||||
variable "vm_storage_pool" {
|
||||
type = string
|
||||
description = "The name of the Proxmox storage pool to store the VM template. (e.g. 'local-lvm')"
|
||||
}
|
||||
|
||||
variable "vm_disk_size" {
|
||||
type = string
|
||||
description = "The size for the virtual disk in GB. (e.g. '32G')"
|
||||
}
|
||||
|
||||
variable "vm_disk_format" {
|
||||
type = string
|
||||
description = "The format of the file backing the disk. (e.g. 'qcow2')"
|
||||
}
|
||||
|
||||
variable "vm_network_card_model" {
|
||||
type = string
|
||||
description = "The model of the virtual network adapter to emulate. (e.g. 'virtio')"
|
||||
}
|
||||
|
||||
variable "vm_bridge_interface" {
|
||||
type = string
|
||||
description = "The name of the Proxmox bridge to attach the adapter to."
|
||||
}
|
||||
|
||||
variable "vm_vlan_tag" {
|
||||
type = string
|
||||
description = "If the adapter should tag packets, give the VLAN ID. (e.g. '102')"
|
||||
}
|
||||
|
||||
// Cloud-Init Settings
|
||||
|
||||
variable "vm_cloud_init_enable" {
|
||||
type = bool
|
||||
description = "Enable or disable cloud-init drive in Proxmox. (e.g. false)"
|
||||
default = false
|
||||
}
|
||||
|
||||
// Removable Media Settings
|
||||
|
||||
variable "common_iso_storage" {
|
||||
type = string
|
||||
description = "The name of the source Proxmox storage location for ISO images. (e.g. 'local-lvm')"
|
||||
}
|
||||
|
||||
variable "iso_path" {
|
||||
type = string
|
||||
description = "The path on the source Proxmox storage location for ISO images. (e.g. 'iso')"
|
||||
}
|
||||
|
||||
variable "iso_file" {
|
||||
type = string
|
||||
description = "The file name of the ISO image used by the vendor. (e.g. 'ubuntu-<version>-live-server-amd64.iso')"
|
||||
}
|
||||
|
||||
variable "iso_checksum" {
|
||||
type = string
|
||||
description = "The checksum value of the ISO image provided by the vendor."
|
||||
}
|
||||
|
||||
// Boot Settings
|
||||
|
||||
variable "common_data_source" {
|
||||
type = string
|
||||
description = "The provisioning data source. (e.g. 'http' or 'disk')"
|
||||
}
|
||||
|
||||
variable "common_http_bind_address" {
|
||||
type = string
|
||||
description = "Define an IP address on the host to use for the HTTP server."
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "common_http_port_min" {
|
||||
type = number
|
||||
description = "The start of the HTTP port range."
|
||||
}
|
||||
|
||||
variable "common_http_port_max" {
|
||||
type = number
|
||||
description = "The end of the HTTP port range."
|
||||
}
|
||||
|
||||
variable "vm_boot" {
|
||||
type = string
|
||||
description = "The boot order for virtual machine devices. (e.g. 'order=virtio0;ide2;net0')"
|
||||
}
|
||||
|
||||
variable "vm_boot_wait" {
|
||||
type = string
|
||||
description = "The time to wait after booting the initial VM before typing the boot_command (e.g '10s')"
|
||||
}
|
||||
|
||||
variable "common_ip_wait_timeout" {
|
||||
type = string
|
||||
description = "Time to wait for guest operating system IP address response."
|
||||
}
|
||||
|
||||
variable "common_shutdown_timeout" {
|
||||
type = string
|
||||
description = "Time to wait for guest operating system shutdown."
|
||||
}
|
||||
|
||||
// Communicator Settings and Credentials
|
||||
|
||||
variable "build_username" {
|
||||
type = string
|
||||
description = "The username to login to the guest operating system. (e.g. 'ubuntu')"
|
||||
# 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 to the guest operating system."
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
variable "build_key" {
|
||||
type = string
|
||||
description = "The SSH public key to login to the guest operating system."
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
variable "timeout" {
|
||||
description = "not sure why I need so high a timeout but here we are"
|
||||
default = "90m"
|
||||
}
|
||||
|
||||
// Ansible Credentials
|
||||
|
||||
variable "ansible_username" {
|
||||
type = string
|
||||
description = "The username for Ansible to login to the guest operating system. (e.g. 'ansible')"
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
variable "ansible_key" {
|
||||
type = string
|
||||
description = "The public key for Ansible to login to the guest operating system."
|
||||
# sensitive = true
|
||||
}
|
||||
|
||||
// HCP Packer Settings
|
||||
|
||||
variable "common_hcp_packer_registry_enabled" {
|
||||
type = bool
|
||||
description = "Enable the HCP Packer registry."
|
||||
default = false
|
||||
}
|
||||
|
||||
14
builds/proxmox.pkrvars.hcl.example
Normal file
14
builds/proxmox.pkrvars.hcl.example
Normal file
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Proxmox Virtual Environment variables used for all builds.
|
||||
- Variables are use by the source blocks.
|
||||
*/
|
||||
|
||||
// Proxmox Credentials
|
||||
proxmox_api_url = "<FQDN or IP of proxmox server>"
|
||||
proxmox_api_token_id = "name@realm!token"
|
||||
proxmox_api_token_secret = "<token secret>"
|
||||
proxmox_insecure_connection = false
|
||||
|
||||
// Proxmox Settings
|
||||
proxmox_node = "<proxmox node name>"
|
||||
9
common.sh
Normal file
9
common.sh
Normal file
@@ -0,0 +1,9 @@
|
||||
follow_link() {
|
||||
FILE="$1"
|
||||
while [ -h "$FILE" ]; do
|
||||
# On macOS, readlink -f doesn't work.
|
||||
FILE="$(readlink "$FILE")"
|
||||
done
|
||||
echo "$FILE"
|
||||
}
|
||||
|
||||
30
config.sh
Executable file
30
config.sh
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
source common.sh
|
||||
|
||||
SCRIPT_PATH=$(realpath "$(dirname "$(follow_link "$0")")")
|
||||
CONFIG_PATH=${1:-${SCRIPT_PATH}/config}
|
||||
|
||||
mkdir -p "$CONFIG_PATH"
|
||||
### Copy the example input variables.
|
||||
echo
|
||||
echo "> Copying the example input variables..."
|
||||
cp -av "$SCRIPT_PATH"/builds/*.pkrvars.hcl.example "$CONFIG_PATH"
|
||||
|
||||
### Rename the example input variables.
|
||||
echo
|
||||
echo "> Renaming the example input variables..."
|
||||
srcext=".pkrvars.hcl.example"
|
||||
dstext=".pkrvars.hcl"
|
||||
|
||||
for f in "$CONFIG_PATH"/*"${srcext}"; do
|
||||
bname="${f%"${srcext}"}"
|
||||
echo "${bname}{${srcext} → ${dstext}}"
|
||||
mv "${f}" "${bname}${dstext}"
|
||||
done
|
||||
|
||||
echo
|
||||
echo "> Done."
|
||||
|
||||
0
manifests/.gitkeep
Normal file
0
manifests/.gitkeep
Normal file
@@ -1,8 +0,0 @@
|
||||
# Your Proxmox Hostname or IP Address
|
||||
proxmox_api_url = "https://{proxmox.hostname}:8006/api2/json"
|
||||
|
||||
# API Token ID
|
||||
proxmox_api_token_id = "packer@pve!packer"
|
||||
|
||||
# API Token Secret
|
||||
proxmox_api_token_secret = "{token_goes_here}"
|
||||
Reference in New Issue
Block a user