How to Run Cloud Init Modules Multiple Times

cloud-initUbuntu

I am using cloud-init to build an Ubuntu 16.04 LTS VM on Azure. The server I want to build will run software installed from a custom repository.

I use the runcmd directive to add the repository, update the apt database and install the package and its dependencies:

runcmd:
  - wget -O - https://nightly.odoo.com/odoo.key | apt-key add -
  - echo "deb http://nightly.odoo.com/10.0/nightly/deb/ ./" | tee /etc/apt/sources.list.d/odoo.list
  - apt update
  - apt install --assume-yes odoo

I then write a custom configuration file using the write_files directive. I am unable to do this before installing the software because the presence of a configuration file triggers an interactive prompt during installation.

What I would then like to do is execute further commands (specifically I want to run certbot to install a Lets Encrypt certificate). I have been unable to find a way to do this.

It is possible to add a second set of runcmd entries, but by default cloud-init will ignore all but the last set.

There are solutions for merging multiple sets of entries together. However, the commands are then all executed together, which is not what I want.

One obvious solution would be to write the configuration file using shell commands rather than using the write_files directive, but really I feel like I am swimming upstream with my entire approach, and that perhaps there is a more straightforward solution to what must be a fairly common requirement.

Any input appreciated.

Best Answer

This does not solve the specific issue of running shell commands at different points during the cloud-init execution, however the solution to my problem was to use the built in functionality to add apt sources:

https://cloudinit.readthedocs.io/en/latest/topics/examples.html#additional-apt-configuration

I guess the more general answer is to use a module for everything you can, use runcmd when you have to, and if you need both, write your own cloud init module.

Related Topic