Autoinstalling ubuntu-server 20.04.3 from the live-iso

@bastian-src ,

Sorry for the late reply, but I’m currently very busy with other urgent things for the company.
As already said, this was also very difficult for me to build something temporary that works for me as I’m not a developer and had not that much experience regarding defaults, coding, … in foreman.
So, after Canonical decided to use another way of autoinstall as of version 20.04.2 (I guess), I was somehow happy to work out a solution in order to install Ubuntu 20.04.3 with foreman on a systems as we decided to move from CentOS to Ubuntu (OS requirements for some products were Alma and Rocky are not supported (yet)).
That is why I provided my temporary solution to the community in hope that the Foreman’s die-hard developers-team could work out a final version.

Regarding root user for Ubuntu:
By default Ubuntu is always installed with root disabled for login during installation, that’s why we are asked for a password and user during manual installation.

This way is configured in my template “preseed_cloud-init-autoinstall-user-data” I created, more specific:
identity: {hostname: <%= @host.shortname %>, password: <%= userpassword_to_create %>,
realname: <%= realname_to_create %>, username: <%= username_to_create %>}
These fields (username, realname and password) are configured on the host or hostgroup.

Beside this, I have seen following mistake in that file:
<%= indent 4 do snippet ‘preseed_cloud-init-autoinstall-user-data custom sources_list’ end -%>
should be replaced by:
<%= indent 4 do snippet ‘preseed_cloud-init-autoinstall-user-data custom sources_list’ end %>

Remove “-” at the end.

Regarding the netplan setup:
In our case, as we also use bond-interfaces with vlans for which we define static addresses, I always configure/modify the network interfaces manually before starting the provisioning of the system.
However, we also have a separate pxe-vlan linked to a specific interface.
For this interface the ip is provided by foreman by dhcp and the network identifier is always filled in with the name discovered during the discovery-process.
So for this interface I never encountered any problems during provisioning.

Hope this will help you further and otherwise do not hesitate to ask further details.


I would like to use these endpoints in my templates, but I can’t seem to find how to do it in the docs. I know we have the new autoinstall templates in 3.2, but I can’t seem to find how to enable the endpoints that the cloud-init templates should be available at. Is there a configuration file for these?

Hi, I’ve tried your tutorial but since I’m using bootdisk as boot method, it does not work as expected
Any ideas on where I can dig to look into this issue ?
The error message I get:

ERF42-8554 [Foreman::Exception]: Unable to download boot file http://foreman-server.local/pub/installation_media/ubuntu/amd64/20-04//dists/focal/main/installer-amd64/current/legacy-images/netboot/ubuntu-installer/amd64/linux, HTTP return code 404"

It makes sense since in the ISO image this path does not exists, but I don’t know why the bootdisk method search for this path exactly

That path is for the now deprecated “old” Ubuntu installer, based on d-i. That is the location that the old installer is in the usual Ubuntu mirrors. For my environment, not using a bootdisk, using the latest templates in 3.2, the “Preseed default PXELinux Autoinstall” PXELinux template has the following line:

APPEND ip=dhcp url=http://<%= @preseed_server %><%= @preseed_path %> autoinstall ds=nocloud-net;s=http://<%= @preseed_server %>/pub/preseed/autoinstall/<%= @host.shortname %>/ root=/dev/ram0 ramdisk_size=1500000 fsck.mode=skip

The url value is the location of the installer iso (configured in installation media as just the ISO, no folders).

This is how I understand it, but I don’t even have a working configuration so it is probably incorrect. I hope it is a good starting point though.

To get around the network identifier being unknown for newly created hosts I changed the preseed_netplan_generic_interface template to match on mac address like this


@Zedeau ,

Sorry for the late reply, but was to bussy with other things.

I worked out a this solution in order to pxe-install ubunto 20.04, but this error does not affect the installation.
As I’m not a developer, I have no idea from where this comes, but I will make some time to find out why it refers to this location.
Initially I extracted the ISO in this path “installation_media/ubuntu”, but it should not be necessary as the installation should be done using the ISO-file.

As @upeter metioned, you need to apply the method in the “Preseed default PXELinux Autoinstall” PXELinux template.

Today I was able to autoinstall ubuntu 22.04 as well with my workaround, and even without having an extract of the ISO for this version the installation, I get the same message in the apache log, but the installation went also well.
Only problem with ubuntu 22.04 is that the subscription-manager packages from atix ends up in an error (dependency for python3 version which is higher in 22.04).
I already informed @maximilian about this issue, so it is just a matter of waiting till they provide a new repo for ubuntu 22.04.

1 Like

Sorry for the delay, here comes an update on the current development status:

I have currently multiple PRs open which bring Ubuntu 20.04.3+ support to Foreman and reduce the manual steps necessary (see here). I hope, if they are all done, that we can also cherry-pick them for 3.1.

@Zedeau regarding the installation media problem: Ubuntu does not deliver the legacy images any more. Accordingly, the path for the boot files (and their names) changed and has to be adapted by foreman (see this PR).
Even if you would create a symbolic link to the new path, foreman searches still for the wrong file names. This is fixed by this PR which has already been merged.

@acittlau Thanks for your fix regarding the preseed_netplan_generic_interface snippet. AFAIK, there is a scenario where we don’t have the MAC address beforehand. Therefore, I’d set ens160 as a default interface name here.
If my doubts about the MAC are wrong, I’d also favour your approach!

The other PRs fix some more problems which came up:

  • Smart Proxy deployment: PR 9227
  • registering to the Foreman via sub-man: PR 9216
  • enabling root as a default user: PR 9169

We are also working on documentation for the (still necessary) manual steps. They relate to providing the .iso image and the extracted files. We would like to provide a default path on how to handle it. I’ll post a link here if the docs are available.

Thanks all for your help and patience!

1 Like

Hi @langesmalle @acittlau @upeter @Zedeau :slight_smile:

I have created a draft PR to document the procedure to provision hosts running Ubuntu 22.04. I will keep you posted once this is merged.



I’ve followed langesmalle initial instructions on provisoning Ubuntu 20.04.3. I may be mistaken but based on this line in the “Preseed default PXELinux Autoinstall” template …

APPEND ip=dhcp url=http://<%= @preseed_server %><%= @preseed_path %> autoinstall ds=nocloud-net;s=http://<%= @preseed_server %>/pub/preseed/autoinstall/<%= @host.shortname %>/ root=/dev/ram0 ramdisk_size=1500000 fsck.mode=skip

… the following 2 settings …

  • url=http://<%= @preseed_server %><%= @preseed_path %>
  • s=http://<%= @preseed_server %>/pub/preseed/autoinstall/<%= @host.shortname %>/

… dictates where the iso file is and where the meta-data and user-data files are. The provisioning process depends on these 3 files, irrespective of what is configured in the following templates:

  • Preseed Autoinstall cloud-init user data
  • preseed_netplan_generic_interface
  • preseed_netplan_setup

I’ve installed Ubuntu 20.04.4 in a VM manually setting all the required configurations, copied its autoinstall-user-data file as the user-data file for provisioning and have provisiond an Ubuntu 20.04.4 VM successfully (fully unattended) through Foreman’s discovery process using a Host Group.

But I’m trying to find a way to update the user-data file before the Build process (namely static ip address) but without the Provisioning template coming into play, I lose the ability to override host parameters in the “Preseed Autoinstall cloud-init user data” template.

Unless I’ve mis-interpreted the contents in this thread as it has a lot of information and I could have done the provisioning process all wrong.


1 Like

Hey @tlauwk!
In order to re-enable the Provisioning template, you can make use of the userdata interface of Foreman. Have a look at these changes. Then, you have to define a userdata template for the OS and select it for the host. This gives you the option to make use of provisioning templates as usually. This line must be changed accordingly:

APPEND ip=dhcp url=http://<%= @preseed_server %><%= preseed_path %> autoinstall ds=nocloud-net;s=http://<%= userdata_server %>/userdata/ root=/dev/ram0 ramdisk_size=1500000 fsck.mode=skip

It references the userdata interface instead of pointing to a static file. The variable userdata_server points to the corresponding smart proxy and must be initialized as followed:

userdata_server = foreman_url('').sub(/.*:\/\//, '').split('/').first
userdata_server = @preseed_server if userdata_server.split(':').first == foreman_server_fqdn

Be aware that this won’t be the final state of the template - the PR is still in review and might change, but it should fix your problem for now.

1 Like

Hi @bastian-src,

Thanks for the heads up, it works a treat.

I had to make a slight adjustment as I’ve got a remote site with a Smart Proxy installed (DHCP, TFTP, Discovery, Templates and Logs). The VM at the remote site resolves …

http://<%= userdata_server %>/userdata/

… to …


… which doesn’t work. I had to swap <%= userdata_server %> with <%= @preseed_server %> and the build would continue successfully as it now resolves to …


All good so far. What I would like though if for the VMs to download the iso from their respective site smart proxy.

Something like …

http://<%= @smart-proxy %><%= port 80 %><%= preseed_path %>

… so it doesn’t have to cross the WAN.

And if possible get the user-data template from their respective site proxy as well:

http://<%= @smart-proxy %><%= port 80 %>/userdata/

I was wondering if this was possible with a different foreman variable in the paths?


1 Like

The @preseed_server resolves to the domain defined in the corresponding Installation Media of the host. So, I’d suggest creating an Installation Media (or even better, also an additional Host Group) for every of your Smart Proxies, and use the @preseed_server variable to reference the iso image in the template. Then, you can just associate the corresponding host group with the installation media & the hosts are gonna use that respective proxy (aka preseed_server) in the template.

In order to get the userdata from the respective Smart Proxy as well, I’d recommend using the userdata_server variable as described earlier. Depending on your Foreman version, your Smart Proxies forwards http://remote-smart-proxy:8000/userdata/ requests to http://foreman-master:80/userdata/ - Therefore, you have to check that:

  • a) port 8000 is open on your Smart Proxy and that you have /etc/foreman-proxy/settings.d/templates.yml is configured accordingly
  • b) you configured :trusted_proxies on your foreman

In order to configure the trusted proxies, run the following command on your foreman:

# foreman-installer --foreman-trusted-proxies "" --foreman-trusted-proxies "::1" --foreman-trusted-proxies "<Your_Proxy_IP>"

It adds a field trusted_proxies in your /etc/foreman/settings.yaml. Let me know if this works for you!


creating an Installation Media (or even better, also an additional Host Group) for every of your Smart Proxies

I was hoping to avoid doing the above as I actually have 2 remote proxies (may be more later) so that would mean 3 installation medias and 3 host groups. So triple the chance of my engineers selecting the wrong option during deployment. I’ll have to think about this … iso download time vs administrative simplicity.

Port 8000 isn’t listening on the remote smart proxies. Just to clarify on the remote smart proxies, I should run foreman-installer -i and set the following:

5. Set http, current value: true
6. Set http_port, current value: 8000

On the foreman-master, the foreman-installer -i says:

55. Set trusted_proxies, current value: []
localhost addresses (, ::1) need to be in trusted_proxies

Is the /8 mask required for configuring localhost addresses in foreman-trusted-proxies?


Ah okay, yeah makes sense. Maybe, you can limit the host groups visible to your engineers by adapting their access rights via location and organization?

Yep, that’s right. You should also check your firewall settings to enable port 8000.

That description is wrong, it must be an address and not a subnet. So, the mask shouldn’t be here.

Thanks bastian-src.

Its all working well now using the variable userdata_server.


1 Like

Has anyone been able to get an autoinstall working via UEFI?

I have cloned the “Preseed default PXEGrub2” template and replaced the menuentry value with the following, based on the working “Preseed default PXELinux Autoinstall” template:

menuentry '<%= template_name %>' {
  linux<%= efi_suffix %>  ubuntu/focal/vmlinuz ip=dhcp url=http://<%= @preseed_server %><%= @preseed_path %> autoinstall ds=nocloud-net\;s=http://<%= @preseed_server %>/userdata/ cloud-config-url=/dev/null root=/dev/ram0 ramdisk_size=1500000 fsck.mode=skip
  initrd<%= efi_suffix %> ubuntu/focal/initrd

This seems to work, right up until it should be loading the userdata and starting the automated cloud-init process. Instead, it starts asking questions beginning with language and keyboard layout, which are answered in the user-data file.

Looking at my webserver logs, it is requesting the user-data and meta-data files, but it seems to be ignoring them and asking for information instead.

Any ideas, or anyone have a working UEFI PXE template I can copy? We have newer hardware which won’t boot in legacy BIOS mode, and so we have to use UEFI to provision them.

This is an issue that also affects my environment. I have not yet found a solution.

My issue turned out to be a missing interface identifier in Foreman, which was causing the user-data YAML to be invalid:

  version: 2
    : # <-- Note the missing hash key
      dhcp4: true
      dhcp6: false

Didn’t catch it on my other test nodes because those were rebuilds of existing machines which already had the interface values populated via Puppet. This was a new build, and previously our builds didn’t require setting a specific interface name so we’ve left it blank. Time to update our docs!

Just to note, filling out the IP Address is required as well, because Foreman uses that to authenticate requests to the /userdata/ endpoints, based off the IP of the request, so the host entry IP and the IP of the machine PXE booting have to match. If you have a reverse proxy in front of Foreman, be sure you are correctly setting the X-Forwarded-For header, and are passing that to Foreman correctly. We had to add the mod_remoteip module to Apache and configure it to trust our load balancer.

All working now!


Make sure to file a PR to our templates if you spot a bug. THanks!

@ncstate-mafields ,

I have been able to make it work for UEFI systems by having this in my PXEGrub2 template:

Note, this is still with the solution I have worked out on our bootstrap system, so pobably some variables needs to be changed.

menuentry "Install Ubuntu Server <%= @host.operatingsystem.release_name %>" {
    set gfxpayload=keep
    linux ubuntu/<%= @host.operatingsystem.release_name %>/vmlinuz ip=dhcp url=http://<%= @preseed_server %><%= @preseed_path %> autoinstall ds=nocloud-net\;s=http://<%= @preseed_server %>/pub/preseed/autoinstall/<%= @host.shortname %>/ root=/dev/ram0 ramdisk_size=1500000 fsck.mode=skip
    initrd ubuntu/<%= @host.operatingsystem.release_name %>/initrd

As you can see it contains the extra line “set gfxpayload=keep”, and the line starting with linux does not contain “cloud-config-url=/dev/null”.

Hope this will help you further.