Deploy Photon OS 3.0 with cloud-init using PowerShell

This article explains how to deploy the official Photon OS 3.0 image provided by VMware with cloud-init using PowerShell. Cloud-init allows OS customization after the OVA deployment. You can configure the hostname, network setting, deploy SSH keys, install packages or just run any commands.

To use cloud-init in Photon OS, you have two options. You can either provide the cloud-init user-data configuration as a seed ISO, or as vApp options. In this article, I'm using the second option: vApp Options. The cloud-config is a YAML formatted configuration file that needs to be added as base64 encoded string to the vApp Options with the user-data key.

Cloud Config Example:

#cloud-config
hostname: photon
fqdn: photon.virten.lab
timezone: Europe/Berlin
write_files:
  - path: /etc/systemd/network/10-static.network
    permissions: 0644
    content: |
      [Match]
      Name=eth0

      [Network]
      Address=192.168.1.10/24
      Gateway=192.168.1.1
      DNS=8.8.8.8
runcmd: 
  - systemctl restart systemd-networkd
  - tdnf update -y
ssh_authorized_keys:
  - ssh-rsa AAAAB3NzaC1yc2EAA[...] fgr

Check the official Cloud-Init on Photon OS documentation for further options.

I've deployed Photon OS 3.0 with the following modifications:

  • Hostname and FQDN
  • Timezone
  • Static IP Address configuration
  • Update all packages to the latest version
  • Deploy SSH-Key for root
  • Change vCPU count to 2
  • Change Memory to 4 GB

When the deployment is finished, you should be able to log in as root with your SSH key. For security reasons, you have to change the root password at the first login. The default root password is "changeme".

Please also make sure that Cloud-Init is finished before you start any further modifications. You can already log in when it is still updating packages in the background. Check the status with the cloud-init status command.

# cloud-init status
status: done

Download: Photon OS 3.0 Rev 3 OVA (Direct Link | Download Page)

PowerShell Script:

$cloud_config=@"
#cloud-config
hostname: photon
fqdn: photon.virten.lab
timezone: Europe/Berlin
write_files:
  - path: /etc/systemd/network/10-static.network
    permissions: 0644
    content: |
      [Match]
      Name=eth0

      [Network]
      Address=192.168.1.10/24
      Gateway=192.168.1.1
      DNS=8.8.8.8
runcmd: 
  - systemctl restart systemd-networkd
  - tdnf update -y
ssh_authorized_keys:
  - ssh-rsa AAAAB3NzaC1yc2EAA[...] fgr
"@

$ovf = 'Z:\images\Linux\Photon\photon-hw11-3.0-a383732.ova'
$ovfConfig = Get-OvfConfiguration $ovf
$ovfConfig.NetworkMapping.None.Value = "vS-VLAN222"      # Portgroup for Management Network
$userDataBase64 = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($cloud_config))

$VMName = "photon.virten.lab"                  # Virtual Machine Display Name
$vmhost = "esx2.virten.lab"                  # ESXi Host to deploy the VM
$datastore = "bort-red01"               # Datastore to deploy the VM
$diskStorageFormat = "Thin"  # Thin or Thick provisionig of virtual disks

$vm = Import-VApp -Source $ovf -OvfConfiguration $ovfconfig -Name $VMName -VMHost (Get-VMHost -Name $VMHost) -Datastore $datastore -DiskStorageFormat $diskStorageFormat
$vm | Set-VM -NumCpu 2 -Confirm:$false |Out-Null
$vm | Set-VM -MemoryGB 4 -Confirm:$false  |Out-Null

$spec = New-Object VMware.Vim.VirtualMachineConfigSpec
$spec.VAppConfig = New-Object VMware.Vim.VmConfigSpec
$spec.VAppConfig.OvfEnvironmentTransport = @('com.vmware.guestInfo')
$spec.VAppConfig.Property = New-Object VMware.Vim.VAppPropertySpec[] (1)
$spec.VAppConfig.Property[0] = New-Object VMware.Vim.VAppPropertySpec
$spec.VAppConfig.Property[0].Operation = 'add'
$spec.VAppConfig.Property[0].Info = New-Object VMware.Vim.VAppPropertyInfo
$spec.VAppConfig.Property[0].Info.Category = "cloud-init"
$spec.VAppConfig.Property[0].Info.Id = 'user-data'
$spec.VAppConfig.Property[0].Info.Value = $userDataBase64

$vm.ExtensionData.ReconfigVM_Task($spec)
$vm | Start-VM

The deployment example is also available in my PowerShell OVF Helper Library: OVF Template for VMware Photon OS 3.0 (cloud-init)

 

Change Photon OS Password with Cloud-Init

Changing the root password, or disabling the forced password change "You are required to change your password immediately (administrator enforced)" does not work with Photon OS 3.0. When you try to configure a user with password, plain_text_passwd or hashed_passwd, cloud-init fails with the following error:

2021-11-16 13:18:23,540 - util.py[WARNING]: Failed to set password for root
2021-11-16 13:18:23,541 - util.py[DEBUG]: Failed to set password for root

Workaround to disable forced password change. Add this to your cloud-config:

bootcmd:
  - /bin/sed -E -i 's/^root:([^:]+):.*$/root:\1:18947:0:99999:0:::/' /etc/shadow

18947 is the number of days since 1970-01-01 as of today (2021-11-16). The value states when the password has been changed. You can get the current day-count with the following PowerShell command:

PS> [int](New-TimeSpan -Start (Get-Date "01/01/1970") -End (Get-Date)).TotalDays
18947

Of course, it's a bad idea to not change the default password. If you want to set the password to a custom password, generate a password on Linux with mkpasswd -m sha-512 [PASSWOR] [SALT]:

# mkpasswd -m sha-512 VMware1! 12345678
$6$12345678$OL6tobbYjQZa/M33gui7vWXxkJSoRcXdPSPWbLoaUpox5vQgWtudYjSilBijcBOWiid/Dgg00fzsIPhBT8GFo/

To get this to your cloud-config, make sure to correctly escape. For the sed command, you have to escape the slashes "/" with backslashes "\".

bootcmd:
  - /bin/sed -E -i 's/^root:.*$/root:$6$12345678$OL6tobbYjQZa\/M33gui7vWXxkJSoRcXdPSPWbLoaUpox5vQgWtudYjSilBijcBOWiid\/Dgg00fzsIPhBT8GFo\/:18947:0:99999:0:::/' /etc/shadow

Additionally, if you are using the OVF Helper script, you have to escape the dollars "$" from the output of mkpasswd with a single backtick "`". With correct escaping, your cloud-config should look like this (This will set your root password to "VMware1!":

bootcmd:
  - /bin/sed -E -i 's/^root:.*$/root:`$6`$12345678`$OL6tobbYjQZa\/M33gui7vWXxkJSoRcXdPSPWbLoaUpox5vQgWtudYjSilBijcBOWiid\/Dgg00fzsIPhBT8GFo\/:18947:0:99999:0:::/' /etc/shadow

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.