Larry Cai
Larry Cai

Reputation: 59933

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 ?

Upvotes: 2

Views: 8567

Answers (2)

Nakedible
Nakedible

Reputation: 4168

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.

Upvotes: 3

Heven.Yan
Heven.Yan

Reputation: 11

paste my note for you:

config: after installed cloud-init in VM,if u want to have root permission to access with passwd, do simple config below

modify /etc/cloud/cloud.cfg like below

users:
 - defaults
disable_root:0
ssh_pwauth: 1

Note: ssh_pwauth: "it will modify PasswordAuthentication in sshd_config automatically, 1 means yes

Usage: the behavior of cloud-init can configured using user data. user data can be filled by user during the start of instance (user data is limited to 16K).

Mainly there are several ways to do (tested):

  1. user-data script

    $ cat myscript.sh
    #!/bin/sh
    echo "Hello World. The time is now $(date -R)!" | tee /root/output.txt
    

when starting instance, add parameter --user-data myscript.sh, and the instance will run the script once during startup and only once.

  1. cloud config syntax:

It is YAML-based, see http://bazaar.launchpad.net/~cloud-init-dev/cloud-init/trunk/files/head:/doc/examples/

run script

    #cloud-config
    runcmd:
    - [ ls, -l, / ]
    - [ sh, -xc, "echo $(date) ': hello world!'" ]
    - [ sh, -c, echo "=========hello world'=========" ]
    - ls -l /root
    - [ wget, "http://slashdot.org", -O, /tmp/index.html ]

change hostname, password

    #cloud-config
    chpasswd:
      list: |
         root:123456
      expire: False
    ssh_pwauth: True
    hostname: test
  1. include format run url script, it will download URL script and execute them sequence, this can help to manage the scripts centrally.

    #include
    http://hostname/script1
    http://hostname/scrpt2 
    

Upvotes: 0

Related Questions