Search code examples
coreoscloud-init

How can I write own cloud-config in cloud-init?


cloud-init is powerful to inject user-data in to VM instance, and its existing module provides lots of possibility.

While to make it more easy to use, I want to define my own tag like coreos below, see detail in running coreos in openstack

#cloud-config

coreos:
  etcd:
    # generate a new token for each unique cluster from https://discovery.etcd.io/new
    discovery: https://discovery.etcd.io/<token>
    # multi-region and multi-cloud deployments need to use $public_ipv4
    addr: $private_ipv4:4001
    peer-addr: $private_ipv4:7001
  units:
    - name: etcd.service
      command: start
    - name: fleet.service
      command: start

So I could have something like below using my own defined tag/config myapp

#cloud-config
myapp:
  admin: admin
  database: 192.168.2.3

I am new to cloud-init, is it called module ? it is empty in document http://cloudinit.readthedocs.org/en/latest/topics/modules.html

Can you provide some information to describe how I can write my own module ?


Solution

  • You need to write a "cc" module in a suitable directory, and modify a few configurations. It is not terribly easy, but certainly doable (we use it a lot).

    1. Find the directory for cloudconfig modules. On Amazon Linux, this is /usr/lib/python2.6/site-packages/cloudinit/config/, but the directory location differs in different cloud init versions and distributions. The easiest way to find this is to find a file named cc_mounts.py.

    2. Add a new file there, in your case cc_myapp.py. Copy some existing script as a base to know what to write there. The important function is def handle(name,cfg,cloud,log,args): which is basically the entrypoint for your script.

    3. Implement your logic. The cfg parameter has a python object which is the parsed YAML config file. So for your case you would do something like: myapp = cfg.get('myapp') admin = myapp.get('admin') database = myapp.get('database')

    4. Ensure your script gets called by cloud-init. If your distribution uses the standard cloud-init setup, just adding the file might work. Otherwise you might need to add it to /etc/cloud/cloud.cfg.d/defaults.cfg or directly to /etc/cloud/cloud.cfg. There are keys called cloud_init_modules, cloud_config_modules, etc. which correspond to different parts of the init process where you can get your script run. If this does not work straight out of the box, you'll probably have to do a bit of investigation to find out how the modules are called on your system. For example, Amazon Linux used to have a hardcoded list of modules inside the init.d script, ignoring any lists specified in configuration files.

    Also note that by default your script will run only once per instance, meaning that rerunning cloud-init will not run your script again. You need to either mark the script as being per boot by setting frequency to always in the configuration file listing your module, or remove the marker file saying that the script has run, which lives somewhere under /var/lib/cloud like in /var/lib/cloud/instances/i-86ecc763/sem/config_mounts.