> For the complete documentation index, see [llms.txt](https://docs.platform9.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.platform9.com/private-cloud-director/getting-started/platform9-os/unattended-install-kickstart.md).

# Unattended Installation (Kickstart)

## Overview

This guide explains how to install a Platform9 OS host with no interactive prompts and with fully custom network and system configuration, by supplying your own kickstart file. It is intended for administrators who provision many hosts at scale.

By default, the ISO boots into an interactive setup wizard that asks for the keyboard layout, root password, target disk, and hostname. This guide replaces that wizard with a standard Anaconda kickstart, so the install runs hands-off. The shared Platform9 OS setup (`pcdctl`, the Host Boot Console, Host Management Console, the Platform9 package repository, and CIS hardening) is reused verbatim from the ISO, so an unattended host is configured identically to an interactively installed one.

This guide is a companion to [Network Boot (PXE)](/private-cloud-director/getting-started/platform9-os/network-boot-pxe.md). You set up PXE exactly as described there, and then use the kickstart below in place of the interactive wizard. It does not cover connecting the installed host to your management plane. For that, see [Platform9 OS](/private-cloud-director/getting-started/platform9-os.md).

In this guide, you will populate a kickstart template with your own network, disk, and password settings, serve it over HTTP, and boot a host that installs with no prompts.

## Prerequisites

* A working network-boot environment for the Platform9 OS ISO, set up as described in [Network Boot (PXE)](/private-cloud-director/getting-started/platform9-os/network-boot-pxe.md). This covers DHCP, TFTP, and the full ISO tree served over HTTP.
* An HTTP location from which to serve your populated kickstart file.
* The root password hash, and the network, disk, and hostname settings for your hosts.

## How an Unattended Install Works

1. You boot the installer over the network as described in [Network Boot (PXE)](/private-cloud-director/getting-started/platform9-os/network-boot-pxe.md), but point `inst.ks=` at your own kickstart instead of the one built into the ISO.
2. The `%pre` section of your kickstart fetches the Platform9 OS payload (`pcd-payload.tar.gz`) from the served tree, so the installer has everything it needs with no local media.
3. Anaconda partitions the disk and configures the network from the directives in your kickstart, with no wizard.
4. The shared Platform9 OS setup runs by way of `%include /tmp/pcd-post.cfg`, reused from the ISO, and the host reboots into the Host Boot Console.

You edit only the front matter of the template: the root password, network, disk, and hostname.

{% hint style="warning" %}
The `%pre` section and the `%include` directive are fixed. Do not change them. The `%pre` section is what stages `pcd-post.cfg` for the `%include` to find.
{% endhint %}

## The Kickstart Template

Save the following as `pcd-unattended.cfg` and edit only the block marked **EDIT BELOW**.

```
#version=RHEL10
cmdline

%pre
# Stage the PCD payload (pcd-iso-ui, kickstart_components/, and everything %post
# installs). Media: it lives at the install-source root. Network/PXE: fetch the
# payload tarball from the install tree URL. Writes /tmp/pcd-src for %post.
SRC=""
for d in /run/install/repo /mnt/install/repo; do
    [ -e "$d/pcd-iso-ui" ] && { SRC="$d"; break; }
done
if [ -z "$SRC" ]; then
    url=""
    for kv in $(cat /proc/cmdline); do
        case "$kv" in
            inst.stage2=http://*|inst.stage2=https://*|inst.stage2=ftp://*) url=${kv#inst.stage2=} ;;
            inst.repo=http://*|inst.repo=https://*|inst.repo=ftp://*) [ -z "$url" ] && url=${kv#inst.repo=} ;;
        esac
    done
    url=${url%/}
    mkdir -p /tmp/pcdsrc
    curl -fsS "$url/pcd-payload.tar.gz" -o /tmp/pcd-payload.tar.gz && tar xzf /tmp/pcd-payload.tar.gz -C /tmp/pcdsrc && SRC=/tmp/pcdsrc
fi
echo "$SRC" > /tmp/pcd-src
cp "$SRC"/kickstart_components/pcd-post.cfg /tmp/
%end

# ============================ EDIT BELOW ============================
lang en_US.UTF-8
keyboard --vckeymap=us
timezone Etc/UTC --utc

# Root password. Generate a hash with:  openssl passwd -6
rootpw --iscrypted $6$REPLACE_WITH_YOUR_HASH

# --- Network ---
# Static:
network --bootproto=static --device=ens3 --ip=10.0.0.50 --netmask=255.255.255.0 \
        --gateway=10.0.0.1 --nameserver=10.0.0.2 --hostname=pcd-host-01 --onboot=on
# Bond:  network --device=bond0 --bootproto=static --ip=... --bondslaves=ens3,ens4 --bondopts=mode=802.3ad --hostname=... --onboot=on
# VLAN:  network --device=bond0.100 --vlanid=100 --bootproto=static --ip=... --hostname=... --onboot=on
# DHCP:  network --bootproto=dhcp --device=link --hostname=pcd-host-01 --onboot=on
firewall --disabled

# --- Disk: single GPT disk, LVM VG "pcd", grow-to-fill root ---
ignoredisk --only-use=sda
zerombr
clearpart --all --initlabel --disklabel=gpt --drives=sda
part /boot/efi --fstype=efi --size=600 --ondisk=sda
part /boot --fstype=xfs --size=1024 --ondisk=sda
part pv.01 --grow --ondisk=sda
volgroup pcd pv.01
logvol swap --vgname=pcd --name=swap --fstype=swap --size=8192
logvol / --vgname=pcd --name=root --fstype=xfs --size=1024 --grow
bootloader --boot-drive=sda
# ============================ EDIT ABOVE ============================

%packages
@^minimal-environment
@core
curl
python3
nfs-utils
device-mapper-multipath
iscsi-initiator-utils
cockpit
%end

selinux --permissive
skipx

# Shared PCD setup: pcdctl, boot console, Host Management Console, private repo, CIS hardening.
# Reused verbatim from the ISO. Carries its own reboot. Do not edit.
%include /tmp/pcd-post.cfg
```

## Customize the Front Matter

| Setting              | What to change                                                                                                                                                                                                          |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Root password**    | Run `openssl passwd -6` and paste the resulting `$6$...` hash into `rootpw --iscrypted`.                                                                                                                                |
| **Network (static)** | Set `--device`, `--ip`, `--netmask`, `--gateway`, `--nameserver`, and `--hostname`.                                                                                                                                     |
| **Network (bond)**   | Use `--device=bond0 --bondslaves=<nic1>,<nic2> --bondopts=mode=...`, as shown in the commented line.                                                                                                                    |
| **Network (VLAN)**   | Use `--device=<parent>.<id> --vlanid=<id>`, as shown in the commented line.                                                                                                                                             |
| **Network (DHCP)**   | Use the `--bootproto=dhcp` line in place of the static one.                                                                                                                                                             |
| **Disk**             | Change `--drives`, `--ondisk`, and `--boot-drive` from `sda` to your target device, and adjust the sizes. The layout (GPT, an LVM volume group named `pcd`, and a grow-to-fill root) mirrors the interactive installer. |
| **Hostname**         | Set `--hostname=` on the `network` line.                                                                                                                                                                                |

Per-host installs typically template this file, either as one kickstart per host or as a single kickstart parameterized by MAC address through your provisioning framework.

## Serve the Kickstart and Boot

1. Serve your populated `pcd-unattended.cfg` at an HTTP URL reachable from the host, for example alongside the served ISO tree.
2. Network-boot the host with the kernel arguments described in [Network Boot (PXE)](/private-cloud-director/getting-started/platform9-os/network-boot-pxe.md#required-kernel-arguments), but point `inst.ks=` at your kickstart:

```
inst.stage2=<HTTP_BASE_URL>  inst.repo=<HTTP_BASE_URL>  inst.ks=<URL>pcd-unattended.cfg  ip=dhcp  enforcing=0
```

{% hint style="info" %}
`ip=dhcp` brings up the installer's own networking so that it can fetch the tree. The `network` directive inside your kickstart configures the **installed** system, and the two are independent. If the install VLAN has no DHCP, use a static `ip=<client-ip>::<gw>:<mask>::<iface>:none` kernel argument instead.
{% endhint %}

The installer then runs with no prompts and reboots into the Host Boot Console.

## Verify the Installed Host

From the Host Boot Console, or from the Host Management Console at `https://<host-ip>:9090`, confirm the following:

* The host shows the hostname and IP address you supplied.
* **PCD Connectivity** reads **Not connected**, because onboarding is a separate step.
* The Host Management Console is reachable, and the Platform9 package repository is configured at `/etc/yum.repos.d/platform9.repo`.
* CIS hardening has been applied, which you can confirm by checking that the `pcd-hardening-*` services ran on first boot.

An unattended host is configuration-identical to an interactively installed one, apart from the values you supplied.

## Troubleshooting

| Symptom                                                                                     | Cause                                                                        | Fix                                                                                                                                                         |
| ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| The install starts, but the Host Boot Console, `pcdctl`, or hardening are missing afterward | The `%pre` section could not fetch `pcd-payload.tar.gz`                      | Confirm that the full ISO tree, including `pcd-payload.tar.gz`, is served and reachable from the client, using `curl -sfI <url>pcd-payload.tar.gz`          |
| The install fails because `/tmp/pcd-post.cfg` is not found                                  | The `%pre` block was edited or omitted                                       | Keep the `%pre` block exactly as it appears in the template, because it is what stages `pcd-post.cfg`                                                       |
| The installer stalls, and `systemd` reports `Freezing execution`                            | `enforcing=0` is missing from the kernel arguments                           | Add `enforcing=0`, as described in [Network Boot (PXE)](/private-cloud-director/getting-started/platform9-os/network-boot-pxe.md#required-kernel-arguments) |
| The installer cannot fetch the tree or the kickstart                                        | `ip=dhcp` is missing, or HTTP is not reachable on the install VLAN           | Add `ip=dhcp`, and confirm that the HTTP host is reachable from the client                                                                                  |
| `cloud-init`, the OpenStack CLI, or OpenSCAP are missing on the installed host              | The host could not reach the Platform9 package repository during the install | Ensure that the install network can reach the Platform9 package repository, because the shared setup installs these packages from it                        |

## Related Pages

* [Platform9 OS](/private-cloud-director/getting-started/platform9-os.md): connect the installed host to your management plane and authorize it.
* [Network Boot (PXE)](/private-cloud-director/getting-started/platform9-os/network-boot-pxe.md): the PXE environment this guide builds on.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.platform9.com/private-cloud-director/getting-started/platform9-os/unattended-install-kickstart.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
