1

I am coming from debian-installer and now trying to setup an environment for generell installation of new Servers and VMs with Ubuntu 20.04 and seeing, that debian-installer (d-i) is deprecated and will not be supported any longer, I'd started to deal with autoinstall and cloud-init, but still have some struggle.

After installing a server and copying the install-file from /var/log/installer and adjusting it a litte, I can set up a very primitive system, but that still lacks the following things, that I can easyily do with d-i.

So what I have done so far is: Set up tftp with Apache2 so I can serve a PXE Image and cloud-init user-data.

 cat /srv/tftp/pxelinux.cfg/default
DEFAULT vesamenu.c32
TIMEOUT 100
ONTIMEOUT local
PROMPT 0

NOESCAPE 1

LABEL local
        MENU DEFAULT
        MENU LABEL boot-from-local-disk
        LOCALBOOT 0

LABEL focal-live-install
        MENU label Install focal
        KERNEL vmlinuz
        INITRD initrd
        APPEND root=/dev/ram0 ramdisk_size=1500000 ip=dhcp url=http://172.16.16.41/tftp/ubuntu-20.04.1-live-server-amd64.iso

LABEL focal-live-install-autoinstall
        MENU label Install focal - autoinstall
        KERNEL vmlinuz
        INITRD initrd
        APPEND root=/dev/ram0 ramdisk_size=1500000 ip=dhcp url=http://172.16.16.41/tftp/ubuntu-20.04.1-live-server-amd64.iso autoinstall ds=nocloud-net;s=http://172.16.16.41/tftp/cloud-init/
 cat /etc/apache2/conf-enabled/tftp.conf
<Directory /srv/tftp>
        Options +FollowSymLinks +Indexes
        Require all granted
</Directory>
Alias /tftp /srv/tftp
cat /srv/tftp/cloud-init/user-data
#cloud-config
autoinstall:
  apt:
    geoip: true
    preserve_sources_list: false
    primary:
    - arches: [amd64, i386]
      uri: http://de.archive.ubuntu.com/ubuntu
    - arches: [default]
      uri: http://ports.ubuntu.com/ubuntu-ports
  identity: {hostname: localhost, password: <>,
    realname: ka_de_ae, username: ka_de_ae}
  keyboard: {layout: de, toggle: null, variant: ''}
  locale: en_GB
  network:
    ethernets:
      enp3s0: {dhcp4: true}
    version: 2
  ssh:
    allow-pw: true
    authorized-keys: []
    install-server: true
  user-data:
    disable_root: false
    chpasswd:
      root:<>
  storage:
    config:
    - {ptable: gpt, path: /dev/sda, wipe: superblock-recursive, preserve: false, name: '', grub_device: true, type: disk, id: disk-sda}
    - {device: disk-sda, size: 1048576, flag: bios_grub, number: 1, preserve: false,
      grub_device: false, type: partition, id: partition-sda1}
    - {device: disk-sda, size: 2147483648, wipe: superblock, flag: linux, number: 2,
      preserve: false, grub_device: false, type: partition, id: partition-sda2}
    - {fstype: ext4, volume: partition-sda2, preserve: false, type: format, id: format-0}
    - {device: disk-sda, size: -1, wipe: superblock, flag: linux, number: 3,
      preserve: false, grub_device: false, type: partition, id: partition-sda3}
    - name: vg0
      devices: [partition-sda3]
      preserve: false
      type: lvm_volgroup
      id: lvm_volgroup-0
    - {name: root, volgroup: lvm_volgroup-0, size: 5368709120B, preserve: false, type: lvm_partition,
      id: lvm_partition-0}
    - {fstype: ext4, volume: lvm_partition-0, preserve: false, type: format, id: format-1}
    - {device: format-1, path: /, type: mount, id: mount-1}
    - {name: swap, volgroup: lvm_volgroup-0, size: 4294967296B, preserve: false, type: lvm_partition,
      id: lvm_partition-1}
    - {fstype: swap, volume: lvm_partition-1, preserve: false, type: format, id: format-2}
    - {device: format-2, path: '', type: mount, id: mount-2}
    - {name: tmp, volgroup: lvm_volgroup-0, size: 4294967296B, preserve: false, type: lvm_partition,
      id: lvm_partition-2}
    - {fstype: ext4, volume: lvm_partition-2, preserve: false, type: format, id: format-3}
    - {device: format-3, path: /tmp, type: mount, id: mount-3}
    - {name: usr, volgroup: lvm_volgroup-0, size: 16106127360B, preserve: false, type: lvm_partition,
      id: lvm_partition-3}
    - {fstype: ext4, volume: lvm_partition-3, preserve: false, type: format, id: format-4}
    - {device: format-4, path: /usr, type: mount, id: mount-4}
    - {name: var, volgroup: lvm_volgroup-0, size: 10737418240B, preserve: false, type: lvm_partition,
      id: lvm_partition-4}
    - {fstype: ext4, volume: lvm_partition-4, preserve: false, type: format, id: format-5}
    - {device: format-5, path: /var, type: mount, id: mount-5}
    - {name: varlog, volgroup: lvm_volgroup-0, size: 4294967296B, preserve: false,
      type: lvm_partition, id: lvm_partition-5}
    - {fstype: ext4, volume: lvm_partition-5, preserve: false, type: format, id: format-6}
    - {device: format-6, path: /var/log, type: mount, id: mount-6}
    - {device: format-0, path: /boot, type: mount, id: mount-0}
    swap: {swap: 0}
  version: 1
  users:
    - name: ka_de_ae
      shell: /bin/bash
      ssh-authorized-keys:
        - ssh-rsa <key + comment>
        - ssh-rsa <key + comment>
        - ssh-rsa <key + comment>
        - ssh-rsa <key + comment>
  runcmd:
    - sed -i -e '/^#PermitRootLogin/s/^.*$/PermitRootLogin yes/' /etc/ssh/sshd_config
    - restart ssh

This is already some steps ahead of the initial simple install, but there are a lot of things not working.

  • hostname: I don't want to put a fixed hostname there, I'd like to get this filled in from DNS, like d-i did it. But if I leave this blank, the installer stops and I have to do it manually, which is not what I want to do. Using "localhost" as some suggest on the internet just sets it to localhost instead of using the DNS-name from the DNS server. How to achieve this?
  • Getting the ssh-public keys to an authorized_keyfile doesn't work. I've tried several ways but still I don't get any user with any public keys attached.
  • Getting root user to work with authorized_keys directly after install. Would be fine, but as long as we have an user with root-rights, we can go on from there with Ansible. But still would be nicer to have root working.
  • Have others users after initial install other than the one in "identity" still doesn't work for me.
  • network interfaces: the server I am testing on has 4 devices, just one of them currently has a link (enp3s0), but this will not always be the interface name and I still lack a way to just say the server "take the first one with a link, try DHCP on it and when this works, use it and ignore all other interfaces for now". Kind of missing eth0 here...
  • Probably better to put that into an own thread, but in case it's just easy to answer: We also want an own mirror for the servers, so we have to download everything only once to a central mirror instead of every server doing it on itself. But using the mirror (just simple apt-mirror) doesn't work with cloud-init, because there seems to be missing some folders, that are needed for that.

I guess, from what I read, that most of these things should be quite doable, but I definitely miss something in doing it right, so any help is appreciated.

0

For some of the points I found the correct syntax meanwhile.

  • hostname: still not working. For that I would need some suggestions
  • ssh public keys: at least for the one user for installation, I have working ssh pubkeys now. I am not sure why the exact syntax from earlier tries now works, perhaps it's the first time of combination with the right mix (ssh -> authorized-keys without an users part). See config further down
  • root: We gave up on having a working root user and decided that having an user with admin rights will be enough and take it with Ansible from here.
  • other users: Did not try that part again, due to having one user is enough.
  • network interfaces: Just not putting anything for that in the config did the part with "Take the first one working".
  • own mirror: still to be done, not sure what we are missing here. To be clear, how to configure this in cloud-init is known, but how to use an own mirror for that, not.

For the LVM config of your HDD, I recommend that you install one server from scratch manually with configuring your disk to your wishes and then take the install log to get the disk part right. Had some days of trial and error until I did that, just to find out, that you can't name the partitions like you want and better use the numbers, the system would give them, instead of anything else. When doing this, switch all preserve parts to false and the size of the last partition to -1 to use entire disk space.

Current, working user-data:

#cloud-config
autoinstall:
  package_upgrade: true
  packages:
    - zsh
    - tmux
    - nmap
    - curl
    - wget
    - git
    - htop
    - iperf
    - fail2ban
    - vim
    - net-tools
  apt:
    geoip: true
    preserve_sources_list: false
    primary:
    - arches: [amd64, i386]
      uri: http://de.archive.ubuntu.com/ubuntu
    - arches: [default]
      uri: http://ports.ubuntu.com/ubuntu-ports
  identity: {hostname: localhost, password: <password>,
    username: ansible, realname: ansible}
  keyboard: {layout: de, toggle: null, variant: ''}
  locale: en_GB
  ssh:
    allow-pw: true
    install-server: true
    authorized-keys:
      - ssh-rsa ...
      - ssh-rsa ...
  user-data:
    disable_root: true
  storage:
    config:
    - {ptable: gpt, path: /dev/sda, wipe: superblock-recursive, preserve: false, name: '', grub_device: true, type: disk, id: disk-sda}
    - {device: disk-sda, size: 1048576, flag: bios_grub, number: 1, preserve: false,
      grub_device: false, type: partition, id: partition-sda1}
    - {device: disk-sda, size: 2147483648, wipe: superblock, flag: linux, number: 2,
      preserve: false, grub_device: false, type: partition, id: partition-sda2}
    - {fstype: ext4, volume: partition-sda2, preserve: false, type: format, id: format-0}
    - {device: disk-sda, size: -1, wipe: superblock, flag: linux, number: 3,
      preserve: false, grub_device: false, type: partition, id: partition-sda3}
    - name: vg0
      devices: [partition-sda3]
      preserve: false
      type: lvm_volgroup
      id: lvm_volgroup-0
    - {name: root, volgroup: lvm_volgroup-0, size: 5368709120B, preserve: false, type: lvm_partition,
      id: lvm_partition-0}
    - {fstype: ext4, volume: lvm_partition-0, preserve: false, type: format, id: format-1}
    - {device: format-1, path: /, type: mount, id: mount-1}
    - {name: swap, volgroup: lvm_volgroup-0, size: 4294967296B, preserve: false, type: lvm_partition,
      id: lvm_partition-1}
    - {fstype: swap, volume: lvm_partition-1, preserve: false, type: format, id: format-2}
    - {device: format-2, path: '', type: mount, id: mount-2}
    - {name: tmp, volgroup: lvm_volgroup-0, size: 4294967296B, preserve: false, type: lvm_partition,
      id: lvm_partition-2}
    - {fstype: ext4, volume: lvm_partition-2, preserve: false, type: format, id: format-3}
    - {device: format-3, path: /tmp, type: mount, id: mount-3}
    - {name: usr, volgroup: lvm_volgroup-0, size: 16106127360B, preserve: false, type: lvm_partition,
      id: lvm_partition-3}
    - {fstype: ext4, volume: lvm_partition-3, preserve: false, type: format, id: format-4}
    - {device: format-4, path: /usr, type: mount, id: mount-4}
    - {name: var, volgroup: lvm_volgroup-0, size: 10737418240B, preserve: false, type: lvm_partition,
      id: lvm_partition-4}
    - {fstype: ext4, volume: lvm_partition-4, preserve: false, type: format, id: format-5}
    - {device: format-5, path: /var, type: mount, id: mount-5}
    - {name: varlog, volgroup: lvm_volgroup-0, size: 4294967296B, preserve: false,
      type: lvm_partition, id: lvm_partition-5}
    - {fstype: ext4, volume: lvm_partition-5, preserve: false, type: format, id: format-6}
    - {device: format-6, path: /var/log, type: mount, id: mount-6}
    - {device: format-0, path: /boot, type: mount, id: mount-0}
    swap: {swap: 0}
  version: 1
  late-commands:
    - echo 'ansible ALL=(ALL) NOPASSWD:ALL' > /target/etc/sudoers.d/ansible
2
  • Found the problem with our own apt-mirror. The package is no longer maintained and therefore buggy: askubuntu.com/questions/1252828/… – shecki Jan 14 at 10:56
  • Yes apt-mirror was the problem. Found a patched version, updated our mirror and can now use it to install new servers. so this is also fixed. Only getting hostname from DNS is still an open issue for us. – shecki Jan 14 at 13:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.