Set default cloud-init

I have a MAAS server that deploys Ubuntu workstations.

When I deploy, I paste in a bash script I made:

Is there a way to set this bash script as default? So that MAAS would always use this cloud-init on machines I deploy?

Thanks ahead!

Hi there, while the UI and API do not explicitly have a mechanism for setting a custom default cloud-init at the moment, you can set default templates on the controller’s server. See the docs here on these templates and how they work with curtin and cloud-init https://maas.io/docs/snap/2.9/ui/custom-machine-setup#heading--templates

We’ve done something similar by updating curtin files in maas in /etc/maas/preseed. here is an example where we have a generic post deployment process pushed to hosts;

early_commands:
  1_cca: [mkdir, '-p', '/var/lib/cloud/scripts/per-instance']

write_files:
  cca_customboot:
    path: /var/lib/cloud/scripts/per-instance/customboot.sh
    content: |
      #!/bin/bash
      FIRSTBOOT_FILE="/root/firstboot.log"

      function tweak_cloudinit() {
         echo "timezone: America/Montreal" > /etc/cloud/cloud.cfg.d/99_timezone.cfg
         echo "warnings:" >> /etc/cloud/cloud.cfg.d/99_timezone.cfg
         echo "  dsid_missing_source: off" >> /etc/cloud/cloud.cfg.d/99_timezone.cfg
      }

      if [ -f $FIRSTBOOT_FILE ]; then
        touch $FIRSTBOOT_FILE
      else
        sed -i '/proxy/d' /etc/yum.conf
        tweak_cloudinit
        date > $FIRSTBOOT_FILE
        reboot
      fi
    permissions: '0755'

You can also place custom script un per-boot folder of cloud-init if you want it execute every reboot. but keep in mind those files will be removed if you run a cloud-init clean

That is great, thank you so much!

I’m a little embraced by the confusion but is /etc/maas/preseed supposed to be located in the machine that hosts maas? The machine that hosts MAAS doesn’t seem to have an /etc/maas directory.

Am I missing something? Thanks ahead!

Thanks for the response!

These are the files in the /var/snap/maas/current/preseeds/ directory:

curtin_userdata_centos.sample  curtin_userdata_custom.sample  curtin_userdata.sample  curtin_userdata_windows.sample

So in my case, I could create a file called curtin_userdata_custom and have it contain the following? (took an example from @pdion891 and the documentation):

 early_commands:
  bash_script: [mkdir, '-p', '/root/script.sh']

write_files:
  bash_script:
    path: /root/script.sh
    content: |
      #!/bin/bash
      ...
      # ...My bash script here...
      ...
      ...
    permissions: '0755'

late_commands:
  run_script: ["/bin/bash /root/script.sh"]

Thanks ahead!

Yes, that is correct.

Thanks for the response!

Will that Curtin file run on all future installations automatically? Or is there an additional task that has to be done in the webgui?

Thanks ahead.

Curtin will pull it for each subsequent deployment.

I deployed the workstation as usual, but left the cloud-init blank.

It seems like it didn’t do anything. It rebooted midway. Is there a way to troubleshoot it? When clicking the machine-name, and then Logs, I see no mentionening of the /root/script.sh script.

Sorry for the complication, and big thanks for the help.

HI @rogersjoshmac

Please try again renaming your file to curtin_userdata_ubuntu .
Here is the documentation about template naming: https://maas.io/docs/snap/2.9/ui/custom-machine-setup#heading--template-naming

Also, you could check in /var/snap/maas/common/log/rsyslog/ for the logs.

Let me know if this helps you.

1 Like

Thank you so much, I’ll update the next time I test it.

It’s incredible how the logs are neatly orginized by machine name! I see that it’s essentially the machine’s messages. I’m not sure what to look for to see if it executed the script or not. I’ll test it on the next machine.

Your reply was so helpful, huge thanks!

Looking at the log, it seems like it has an error executing the script:

 known-caiman cloud-init[1372]: Command: ['/bin/bash /root/script.sh']
 known-caiman cloud-init[1372]: Exit code: -
 known-caiman cloud-init[1372]: Reason: [Errno 2] No such file or directory: '/bin/bash /root/script.sh': '/bin/bash /root/script.sh'

The bash script I’m executing is really long. Right now I’m appending it within the curtin file. Is it possible to store the bash script locally in the MAAS machine, and have curtin upload the script to the machine it deploys, and then execute it?

Huge thanks ahead!

@rogersjoshmac, see if this doc helps you at all.

Whoops wrong thread might be useful since other thread is locked for setting default user.

I just did this by using user_data encoded base64. In my opinion this is the easiest way to do this. Here is how, create a file in this case called user_data.yaml with exact content below obviously changing user info as needed. Might be a good idea to check for valid yaml using yamllint /tmp/user_data.yaml. Once it is created you have to supply the base64 encoded version of this file for maas cli. maas admin machine deploy {system_id} user_data=$(base64 -w 0 /tmp/user_data.yaml). I’m sure this can also be done by supplying the below file to the GUI at the deployment page by checking “Cloud-init user-data…” and uploading this file. Important to remember MUST be valid yaml and also the first line MUST be ‘#cloud-config’.

/tmp/user_data.yaml

#cloud-config
system_info:
  default_user:
    name: ansible
    lock_passwd: true
    gecos: Ansible
    homedir: /var/lib/ansible
    primary_group: ansible
    groups: [adm, audio, cdrom, dialout, dip, floppy, lxd, netdev, plugdev, sudo, video]
    sudo: ["ALL=(ALL) NOPASSWD:ALL"]
    shell: /bin/bash