> For the complete documentation index, see [llms.txt](https://docs.glesys.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.glesys.com/products/compute/vmware-cloud-director-as-a-service/how-tos/customizing-a-vm-using-cloud-init-in-vmware-cloud-director.md).

# Customizing a VM using cloud-init in VMware Cloud Director

***

Here, you will learn how to customize a VM using **cloud-init** in a VMware Cloud Director environment.

If you are deploying a VM from a Glesys template in VMware Cloud Director, then follow the instructions outlined in this document.

However, if you are deploying a VM from a custom-built template, then the steps outlined here do not apply, and you can continue using existing workflows for customization.

## Brief overview of guest OS customization in VMware Cloud Director

Historically, VMs deployed from a Glesys template in VMware Cloud Director have been customized using the **vmware-imc method**, the default method supported in the platform.

The vmware-imc method leverages customization scripts bundled with VMware Cloud Director, which are copied onto the guest operating system and then executed by the `vmtools` service running in the guest.

From now on, VMs deployed from a Glesys template in VMware Cloud Director will be customized using `cloud-init`.

The **cloud-init method** has become the de facto industry standard for customizing VMs in the cloud. In a VMware environment, the cloud-init configuration data supplied to a VM is read using vmtools. The cloud-init service running in the guest then customizes the guest operating system according to that configuration.

There are many benefits to using the cloud-init method over the vmware-imc method:

* cloud-init offers more capabilities with the potential to automate the entire initial setup of a VM.
* cloud-init offers better security as it does not rely on default root/admin accounts like vmware-imc.
* cloud-init offers broader guest operating system support. vmware-imc can be limited, and it can take a long time after a new OS is released before it is officially supported.

## How to customize a VM using cloud-init

The following steps apply to all GleSYS templates in VMware Cloud Director.

### Step 1 ­– Generating a VMware Cloud Director API token

1. In the top right corner of the navigation bar, click your user name, select **User preferences** → **API Tokens**, and click **New**.
2. Enter a **Name** for the token, and click **Create**. The generated API token appears. You must copy the token because it appears only once.

<figure><img src="/files/RSWX7foehnsBPZE0A47H" alt=""><figcaption></figcaption></figure>

### Step 2 – Creating a cloud-init metadata file

The metadata file is a plain-text file formatted as YAML, where you can define the hostname, instance ID, and network configuration of your VM.

1. Create a `metadata.yaml` file on your local machine and paste the following configuration:

{% code title="metadata.yaml" %}

```yaml
instance-id: demo.example.com # a unique identifier or UUID for the instance
local-hostname: demo.example.com # replace with your own FQDN
network:
  version: 2
  ethernets:
    ens192:
      dhcp4: yes
```

{% endcode %}

### Step 3 – Creating a cloud-init userdata file

The userdata file is a plain-text file formatted as YAML, where you can define many options to customize your VM, including options to create user accounts, install software packages, execute commands, and create files.

1. Create a `userdata.yaml` file on your local machine and paste the following configuration:

{% code title="userdata.yaml" %}

```yaml
#cloud-config
users:
- name: demo
  shell: /bin/bash
  sudo: ALL=(ALL) NOPASSWD:ALL
  lock_passwd: true
  ssh_authorized_keys: 
    - # Paste your public SSH key here
manage_etc_hosts: true
```

{% endcode %}

### Step 4 – Creating a VM from a template

* Navigate to **Compute** → **Virtual Machines** and click **New VM**.
* Enter a **Name** and a **Computer Name**.
* Select **From Template**.
* Uncheck the **Power on** check box.
* Select a VM template from the list of available templates. For this article, choose **ubuntu-2204**.
* Select a **Storage Policy**.
* Specify the settings for the network adapter, such as **Connected**, **Network**, and **IP Mode**.
* Click **OK** to create the VM.

<figure><img src="/files/1WAP3IZ12lUc5TWep1eq" alt=""><figcaption></figcaption></figure>

Unfortunately, supplying the cloud-init configuration in the **New VM** wizard is not currently possible. Therefore, an additional step is required to provide the cloud-init configuration using the VMware Cloud Director API.

### Step 5 – Supplying a cloud-init configuration to a VM

1. Supply the cloud-init configuration to the VM using the `set_vcd_vm_extraconfig` binary, which you can download from [GitHub](https://github.com/jaymzmac/set_vcd_vm_extraconfig/releases). Then, run the commands below on your local machine:

{% code title="Multiple commands in Linux/macOS" %}

```
export METADATA=$(gzip -c9 <metadata.yaml | { base64 -w0 2>/dev/null || base64; })
export USERDATA=$(gzip -c9 <userdata.yaml | { base64 -w0 2>/dev/null || base64; })

./set_vcd_vm_extraconfig \
 -url vcd.dc-####.glesys.net \
 -token ABC12345678 \
 -org vdo-##### \
 -vdc vdc-##### \
 -vm demo \
 -e guestinfo.metadata="${METADATA}" \
 -e guestinfo.metadata.encoding="gzip+base64" \
 -e guestinfo.userdata="${USERDATA}" \
 -e guestinfo.userdata.encoding="gzip+base64"
```

{% endcode %}

The above commands assume your local machine is running Linux/macOS. If your local machine is running Windows, you can run the following command in PowerShell:

{% code title="Multiple commands in Windows PowerShell" %}

```
$metadata = [convert]::ToBase64String((Get-Content -path "metadata.yaml" -Encoding byte))
$userdata = [convert]::ToBase64String((Get-Content -path "userdata.yaml" -Encoding byte))

.\set_vcd_vm_extraconfig.exe `
 -url vcd.dc-####.glesys.net `
 -token ABC12345678 `
 -org vdo-##### `
 -vdc vdc-##### `
 -vm demo `
 -e guestinfo.metadata="$metadata" `
 -e guestinfo.metadata.encoding="base64" `
 -e guestinfo.userdata="$userdata" `
 -e guestinfo.userdata.encoding="base64"


```

{% endcode %}

### Step 6 – Powering on the VM

1. Navigate to **Compute** → **Virtual Machines**. Choose the specific VM and click **Actions** → **Power** → **Power On**.

You should now be able to SSH to your VM and verify that cloud-init has customized the instance according to the configuration specified in metadata and userdata.

<figure><img src="/files/1VhiGFmgVO5eFDxqMG9x" alt=""><figcaption></figcaption></figure>

## Additional information regarding Windows virtual machines

As mentioned, all the steps outlined in this article apply to both Linux and Windows-based Glesys templates.

However, there is a difference regarding the contents of the userdata file when comparing Windows and Linux deployments that is worth highlighting.

### Windows userdata file

Here is a sample `userdata.yaml` file for Windows-based VMs:

{% code title="userdata.yaml" %}

```yaml
#cloud-config
users:
  - name: Administrator
    no_create_home: True
    inactive: True
  - name: demo
    groups: Administrators
    passwd: passw0rdIsPlainText
```

{% endcode %}

Please be aware that user passwords are specified in plaintext in the userdata file. The userdata configuration is concealed on the VM after creation as a security measure. However, we recommend changing the user password in the VM after its creation to ensure maximum security.

## Further reading

[cloud-init - Official Documentation](https://cloudinit.readthedocs.io/en/latest/)

[cloud-init - Userdata Examples](https://cloudinit.readthedocs.io/en/latest/reference/examples.html)

[cloudbase-init (cloud-init equivalent for Windows) - Official Documentation](https://cloudbase-init.readthedocs.io/en/latest/)

[cloudbase-init (cloud-init equivalent for Windows) - Userdata Examples](https://cloudbase-init.readthedocs.io/en/latest/userdata.html#cloud-config)


---

# 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:

```
GET https://docs.glesys.com/products/compute/vmware-cloud-director-as-a-service/how-tos/customizing-a-vm-using-cloud-init-in-vmware-cloud-director.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
