---
title: "Automatically provision database nodes for on-premises providers"
url: "https://docs.yugabyte.com/stable/yugabyte-platform/prepare/server-nodes-software/software-on-prem/"
---

# Automatically provision database nodes for on-premises providers

Prepare a VM for deploying universes on-premises.

Prepare a VM for deploying universes on-premises

When deploying universes using an on-premises provider, YugabyteDB Anywhere relies on you to manually create the VMs for the database nodes and provide these pre-created VMs to YugabyteDB Anywhere.

Using the `node-agent-provision.sh` script, you can automatically provision a VM, create the on-premises provider, and add the VM to the provider free pool of nodes.

## Prerequisites

- Provide one, three, five, or more VM(s) with the following installed:
  
  - [Supported Linux OS](/stable/yugabyte-platform/prepare/server-nodes-software/#linux-os "Supported Linux OS")
  - [Additional software](/stable/yugabyte-platform/prepare/server-nodes-software/#additional-software "Additional software")
  - If you are not connected to the Internet, [additional software for airgapped](/stable/yugabyte-platform/prepare/server-nodes-software/#additional-software-for-airgapped-deployment "additional software for airgapped")
- YugabyteDB Anywhere is [installed and running](/stable/yugabyte-platform/install-yugabyte-platform/ "installed and running").
- VMs are accessible to YugabyteDB Anywhere over ports 9070 and 443. See [Networking requirements](/stable/yugabyte-platform/prepare/networking/ "Networking requirements") for more information.

### Create data directories or mount points

Configure data directories or mount points for the node (typically `/data`). If you have multiple data drives, these might be for example `/mnt/d0`, `/mnt/d1`, and so on. The data drives must be accessible to the `yugabyte` user that will be created by the script.

## How to prepare the nodes for use in a database cluster

After you have created the VMs with the operating system and additional software, you must further prepare the VMs as follows:

1. Download the YugabyteDB Anywhere node agent package to the VM.
2. Modify the configuration file.
3. Run the provisioning script (as root or via sudo).

These steps prepare the node for use by YugabyteDB Anywhere, including setting ulimits and transparent hugepages. If you have already [installed YugabyteDB Anywhere](/stable/yugabyte-platform/install-yugabyte-platform/ "installed YugabyteDB Anywhere") and it is running (recommended), the script additionally creates (or updates) an [on-premises provider](/stable/yugabyte-platform/configure-yugabyte-platform/on-premises/ "on-premises provider") with the node already added.

Brownfield provisioning (Re-provision existing nodes)

For brownfield use cases where the nodes are already added to the node instances of the provider, you can generate config files. See [Generate configuration files](#generate-configuration-files "Generate configuration files").

Root or sudo privileges are only required to provision the nodes. After the node is provisioned (with [YugabyteDB Anywhere node agent](/stable/faq/yugabyte-platform/#what-is-a-node-agent "YugabyteDB Anywhere node agent") installed), sudo is no longer required.

For existing universes (v2026.1.2.0 and later) that lack THP or have THP mis-configured, you can re-apply provisioning on nodes, see [Reprovision universe nodes](/stable/yugabyte-platform/manage-deployments/reprovision-nodes/ "Reprovision universe nodes").

### Download the package

To begin, download the YugabyteDB Anywhere node agent package to the node you want to provision.

#### Use the API

If you have already installed YugabyteDB Anywhere and it is running, you can download the node agent package from YugabyteDB Anywhere using the [Download node agent API](https://api-docs.yugabyte.com/docs/yugabyte-platform/22174ba86f880-download-node-agent-installer-or-package "Download node agent API").

```sh
curl -k https://<yba_address>/api/v1/node_agents/download\?downloadType\=package\&os\=LINUX\&arch\=AMD64 --fail --header 'X-AUTH-YW-API-TOKEN: <api_token>'  > node-agent.tar.gz
```

- `<yba_address>` is the address of your YugabyteDB Anywhere installation.
- `<api_token>` is an API token you created. For information on creating an API token, refer to [API authentication](/stable/yugabyte-platform/anywhere-automation/#authentication "API authentication"). The user creating the API token must have [Admin role](/stable/yugabyte-platform/administer-yugabyte-platform/anywhere-rbac/#built-in-roles "Admin role") privileges or better.
- You can change the architecture from AMD64 to ARM64 as appropriate.

Use this method if you don't have internet connectivity. This downloads the same version of node agent as the version of YugabyteDB Anywhere you are running.

Extract the package and go to the `scripts` directory.

```sh
tar -xvzf node-agent.tar.gz && cd 2026.1.2.0-b137/scripts/
```

#### Direct download

Alternatively, obtain the node agent package from the YBA Installer package.

1. Download and extract the YBA Installer by entering the following commands:
   
   ```sh
   wget https://downloads.yugabyte.com/releases/2026.1.2.0/yba_installer_full-2026.1.2.0-b137-linux-x86_64.tar.gz
   tar -xf yba_installer_full-2026.1.2.0-b137-linux-x86_64.tar.gz
   cd yba_installer_full-2026.1.2.0-b137/
   ```
2. Extract the yugabundle package:
   
   ```sh
   tar -xf yugabundle-2026.1.2.0-b137-centos-x86_64.tar.gz
   cd yugabyte-2026.1.2.0-b137/
   ```
3. Extract the node agent package and go to the `scripts` directory:
   
   ```sh
   tar -xf node_agent-2026.1.2.0-b137-linux-amd64.tar.gz && cd 2026.1.2.0-b137/scripts/
   ```
   
   On ARM, run:
   
   ```sh
   tar -xf node_agent-2026.1.2.0-b137-linux-arm64.tar.gz && cd 2026.1.2.0-b137/scripts/
   ```

### Modify the configuration file

Edit the `node-agent-provision.yaml` file in the scripts directory.

The following table describes options that are changed for a typical installation. The file is commented; you can [review the file](https://github.com/yugabyte/yugabyte-db/blob/2026.1.2/managed/node-agent/resources/node-agent-provision.yaml "review the file") and its default settings on GitHub.

Option Value 

`yb_home_dir` The directory on the node where YugabyteDB will be installed. 

`yb_user_home` Home directory for the `yugabyte` user. If not set, defaults to `yb_home_dir`. v2025.2.4.0 and later. 

`chrony_servers` The addresses of your Network Time Protocol servers. 

`yb_user_id` Provide a UID to be used for the `yugabyte` user. The script creates the `yugabyte` user, and providing the same UID for each node ensures consistency across nodes. 

`is_airgap` If you are performing an airgapped installation, set to true. 

`use_system_level_systemd` Defaults to false (which uses user-level systemd for service management). 

`node_ip` The fully-qualified domain name or IP address of the node you are provisioning. Must be accessible to other nodes. 

`tmp_directory` The directory on the node to use for storing temporary files during provisioning. 

`is_configure_clockbound` [ClockBound](https://github.com/aws/clock-bound "ClockBound") improves clock accuracy and reduces read-restart errors in YSQL. ClockBound requires [chrony](https://chrony-project.org/ "chrony") to be configured.  
The provisioning script installs ClockBound as a systemd unit and configures it to communicate with chronyd.  
The script also configures the on-premises provider configuration (see the following options) so that universes created using the provider automatically have the [time\_source](/stable/reference/configuration/yb-master/#time-source "time_source") flag set to `clockbound`.

Set the following options to have node agent create (or update) the [on-premises provider configuration](/stable/yugabyte-platform/configure-yugabyte-platform/on-premises-provider/ "on-premises provider configuration") where you want to add the node. (YugabyteDB Anywhere must be installed and running.)

| Option               | Value                                                                                                                                                                                                                                                                                                                                          |
|----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `url`                | The base URL of your YugabyteDB Anywhere instance.                                                                                                                                                                                                                                                                                             |
| `customer_uuid`      | Your customer ID. To view your customer ID, in YugabyteDB Anywhere, click the **Profile** icon in the top right corner of the window, and choose **User Profile**.                                                                                                                                                                             |
| `api_key`            | Your API token. To obtain this, in YugabyteDB Anywhere, click the Profile icon in the top right corner of the window, and choose **User Profile**. Then click **Generate Key**. The user creating the API token must have [Admin role](/stable/yugabyte-platform/administer-yugabyte-platform/anywhere-rbac/#built-in-roles "Admin role") privileges or better. |
| `node_name`          | A name for the node.                                                                                                                                                                                                                                                                                                                           |
| `node_external_fqdn` | The fully qualified domain name (FQDN) or IP address of the node, must be accessible from the YugabyteDB Anywhere server.                                                                                                                                                                                                                      |

Enter the following on-premises provider configuration details. If the provider does not exist, node agent creates it; otherwise, it adds the node instance to the existing provider.

| Option               | Value                                                                                                                                                                                                                                                             |
|----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `provider name`      | Name for the provider configuration (if new) or of the existing provider where you want to add the node.                                                                                                                                                          |
| `region name`        | Name of the region where the node is located. For example, `us-west-1`.                                                                                                                                                                                           |
| `zone name`          | Name of the zone where the node is located. For example, `us-west-1a`.                                                                                                                                                                                            |
| `instance_type name` | Name of the instance type to use. If you are creating a new instance type, provide a name to be used internally to identify the type of VM. For example, for cloud provider VMs, you might name the instance type 'c5.large' for AWS, or 'n1-standard-4' for GCP. |
| `cores`              | The number of cores. Optional if the node is using an existing instance type.                                                                                                                                                                                     |
| `memory_size`        | The amount of memory (in GB) allocated to the instance. Optional if the node is using an existing instance type.                                                                                                                                                  |
| `volume_size`        | The size of the storage volume (in GB). Optional if the node is using an existing instance type.                                                                                                                                                                  |
| `mount_points`       | List the mount points for data storage. This is where the data directories are mounted. You need to add the directories before running the script. Optional if the node is using an existing instance type.                                                       |

The following options are used for logging the provisioning itself.

| Option              | Value                                                               |
|---------------------|---------------------------------------------------------------------|
| `logging level`     | Set the logging level for the node provisioning.                    |
| `logging directory` | Set the directory where node provisioning log files will be stored. |
| `logging file`      | Name of the node provisioning log file.                             |

### Run the provisioning script

Run the script either as a root user, or via sudo as follows:

```sh
sudo ./node-agent-provision.sh
```

The script provisions the node and installs node agent, and runs preflight checks to ensure the node is ready for provisioning.

If specified, node agent also creates the on-premises provider configuration; or, if the provider configuration already exists, adds the instance to the provider.

After the node is provisioned, reboot the node.

If the preflight check fails, rebooting the node may solve some issues (for example, incorrect ulimit settings).

### Split-team provisioning

By default (no flag), `sudo ./node-agent-provision.sh` performs a full provision as root. Use this when a single administrator can run the entire flow.

To separate privileged OS work from user-scoped YugabyteDB Anywhere onboarding, you can split provisioning between two teams using the `--root` and `--noroot` flags:

1. **OS / infrastructure**: Has root or sudo on the VM. Opens the [required ports](/stable/yugabyte-platform/prepare/networking/ "required ports") and installs the [additional software](/stable/yugabyte-platform/prepare/server-nodes-software/#additional-software "additional software"), then runs `--root`.
2. **DB / platform**: Runs as `yugabyte` with no sudo. Installs and registers node agent with YugabyteDB Anywhere.

This way, DB operators never need sudo after OS prep, and both teams use the same tooling.

**How it works**

Both teams download the node agent package from the running YugabyteDB Anywhere instance and use the same `node-agent-provision.sh` script and configuration file (with YugabyteDB Anywhere URL, API token, node identity, and provider details).

1. The OS team runs the script as root using the `--root` flag. This runs only modules that need elevated privileges (create the `yugabyte` user, chrony/THP/ulimits/sysctl, sudoers, and root systemd units). Non-root modules are skipped.
   
   ```sh
   sudo ./node-agent-provision.sh --root
   ```
2. The DB team runs `--noroot` as the `yugabyte` user. This runs only user-scoped work (user systemd, cgroups where applicable, network/node-agent setup, and registering the node with YugabyteDB Anywhere). Root modules are skipped.
   
   ```sh
   ./node-agent-provision.sh --noroot
   ```

### Per-node overrides

Using the `--config_override` flag (available in v2025.2.4.0 and later), you can use a single `node-agent-provision.yaml` configuration file for a fleet (for specifying YugabyteDB Anywhere URL, API token, chrony servers, home directories, provider defaults, and so on), while varying only a few fields per VM (such as node IP/FQDN, node name, zone, mount points, and so on) from the command line.

You can pass as many overrides as needed.

Without `--config_override`, per-node changes require either:

- Maintaining a separate YAML copy per node, or
- Editing the shared file before every run (error-prone and awkward for automation).

**How it works**

1. Keep one common provision YAML checked into ops tooling or shared across the OS/DB teams.
2. For each node, run the script with that file and pass only the node-specific deltas:
   
   ```sh
   ./node-agent-provision.sh \
       --config_override yba.node_external_fqdn=\"db-node-03.example.com\" \
       --config_override ynp.node_ip=\"10.1.2.3\" \
       --config_override yba.node_name=\"db-node-03\"
   ```

The value after `=` is JSON, and it must match that field's type in the provision configuration: a quoted string, a number, `true` or `false`, or a JSON array. Nested fields use dotted paths, such as `yba.instance_type.name`.

For example:

- Override chrony servers (list of strings) under ynp:
  
  ```sh
  ./node-agent-provision.sh --config_override ynp.chrony_servers=[\"s1\",\"s2\"]
  ```
- Override FQDN and YugabyteDB Anywhere URL at the same time:
  
  ```sh
  ./node-agent-provision.sh --config_override yba.node_external_fqdn=\"my-new-fqdn\" --config_override yba.url=\"https://new-yba-url.com\"
  ```

## Verify provisioning

After running the script and rebooting the VM, you can verify that provisioning was successful and YugabyteDB Anywhere can communicate with the node by navigating to `https://<yugabytedbanywhere-host-ip>/nodeagent`, where `yugabytedbanywhere-host-ip` is the IP address hosting your YugabyteDB Anywhere instance.

The page lists the node agents that have been activated and their status.

## Generate configuration files

Use the `--generate_config` flag to generate a new YAML config by pulling information from YugabyteDB Anywhere without actually executing any other command. Use this for brownfield use cases where the nodes are already added to the node instances of the provider and they need to be *re-provisioned*. This option allows you to generate the configuration YAML file without having to manually create it. The YugabyteDB Anywhere URL, API token, and the node FQDN/IP added to node instances in the provider minimally are required in `node-agent-provision.yaml`. (Available in v2025.2.4.0 and later.)

When you combine [--config\_override](#per-node-overrides "--config_override") with `--generate_config`, overrides apply to fields used to contact YugabyteDB Anywhere (for example, `yba.url`), not to values that YugabyteDB Anywhere returns into the generated file.

The generated file is named `node-agent-provision-generated.yaml`.

Use the `--generate_and_run` flag to generate the new configuration file *and* run the provisioning script.

For example, to run provision with the generated configuration file:

```sh
./node-agent-provision.sh  --generate_and_run --provision
```

To do a dry run with the generated configuration file:

```sh
./node-agent-provision.sh  --generate_and_run --dry_run
```

## Preflight check

For troubleshooting, you can run the script's preflight checks separately as follows:

```sh
sudo ./node-agent-provision.sh --preflight_check
```

Use the `--preflight_check_out_file` flag (v2025.2.4.0 and later) to specify the file path for the preflight\_check output. Only the check JSON output is saved. You can read and parse the files for automation.

## sudo whitelist

If security restrictions require you to explicitly list the commands that you'll be running as root under sudo, you can add the following commands to the sudo whitelist:

```sh
sudo ./node-agent-provision.sh --preflight_check
sudo ./node-agent-provision.sh
```

The underlying fine-grained commands that the script runs during provisioning depend on the version of YugabyteDB Anywhere, and are updated as newer capabilities are incorporated.

To audit the commands that are run by the script, do the following:

1. [Run the preflight check](#preflight-check "Run the preflight check").
   
   The preflight check renders templates containing all the bash commands that the script will execute for provisioning.
2. Identify the rendered templates using grep as follows:
   
   ```sh
   sudo ./node-agent-provision.sh --preflight_check 2>&1 | grep "INFO - /tmp/tmp.*$"
   ```
   
   You should see output similar to the following:
   
   ```output
   2025-02-20 23:01:37,290 - commands.provision_command - INFO - /tmp/tmp0ey61a1c
   
   2025-02-20 23:01:37,290 - commands.provision_command - INFO - /tmp/tmppri1g4r_
   ```
3. Use `cat` or any other CLI tool to inspect the content of these files to understand the code that the script will execute when provisioning a node.
   
   - The first file in the log is the precheck template.
   - The second file in the log is the actual execution template.
   
   Note that these files are specific to the operating system and YugabyteDB Anywhere release, and can vary between releases.

## Next steps

If you did not provide details for the provider configuration, you will need to do the following:

1. If the on-premises provider has not been created, create one.
   
   Refer to [Create the provider configuration](/stable/yugabyte-platform/configure-yugabyte-platform/on-premises-provider/ "Create the provider configuration").
2. Add the node to the provider.
   
   Refer to [Add nodes to the on-premises provider](/stable/yugabyte-platform/configure-yugabyte-platform/on-premises-nodes/ "Add nodes to the on-premises provider").
