Cloud init

amnonh edited this page Jan 15, 2015 · 9 revisions
Clone this wiki locally

Cloud init is a mechanism which allows one to configure the instance at the time it is started.

The guest can be equipped with an agent which upon OS boot will read the configuration from various sources and interpret/apply it. By default the cloud init engine will read the configuration from the metadata service provided by the cloud. Checkout the [Configuring instances in the cloud](Configuring instances in the cloud) section on how to pass the configuration on different clouds.

To equip OSv image with the cloud init agent you have to include the cloud-init module, like this:

make image=cloud-init,<other modules>

Configuring instances in the cloud

The way you pass cloud init configuration varies depending on your cloud provider.

On EC2 you pass the configuration in the user data field.

On GCE you pass the configuration in the "user-data" meta data attribute. For example:

gcutil addinstance test-instance --metadata_from_file=user-data:<config-file> --project=<project-id>

If you want to test cloud-init in a Linux development environment you can use the scripts/ec2-simulator.py to simulate the EC2 metadata service. To use it save the OSv configuration in a file, say osv-conf.yaml, and start the simulator like this inside the osv.git checkout directory:

sudo scripts/ec2-simulator -f osv-conf.yaml

Then you can start OSv with run.py as usual. Remember to include the cloud-init module in the image.

The simulator uses the Linux iptables command to intercept traffic to the special cloud-init IP address, 169.254.169.254.

Configuration format

The configuration has a YAML format. At the highest level the configuration consists of sections. Every section is optional. Each section has its own, special syntax. For example the files section deals with creating files, httpserver section deals with RESTful API server configuration, run section allows one to issue commands.

Example configuration file:

files:
  /etc/config: |
     my config
     goes here
httpserver:
  ssl: yes
  port: 443

The files section

This section contains a dictionary where each key is a path of the file to be created and value is the contents of the file. For example the following configuration will create two files: /etc/file1 and /etc/file2 with contents respectively aaa and bbb:

files:
  /etc/file1: aaa
  /etc/file2: bbb

The httpserver section

This section configures the RESTful API server. It should contain a dictionary with the following keys:

  • ssl - when present, HTTP server will be started in SSL mode. Example: ssl: yes
  • port - override the port on which the server listens for HTTP connections. Example: port: 80
  • access-allow - when set, the server will set the CORS headers allowing access to resources from different domains. The value can be * or a sequence of allowed domains.

Example of a complete configuration with httpserver section:

httpserver:
   port: 8080
   access-allow: '*'

Note that you need to include the httpserver module in the image for this section to have effect.

The run section

This section should contain a sequence of commands. Each command represents an HTTP request to the RESTful API server. Requests are executed in order in which they occur.

Each command is represented by a dictionary. The first entry should contain a pair of request method and the request path. Request method is one of the GET, PUT, POST or DELETE. Other entries will set request parameters.

For example the following command:

    - PUT: /file/usr/log
      op: MKDIRS
      permission: 0777

is equivalent to the following request:

curl -X PUT http://localhost:8000/file/usr/log?op=MKDIRS&permisson=0777

Example of a complete configuration with run section:

run:
    # Create /usr/log directory
    - PUT: /file/usr/log
      op: MKDIRS
      permission: 0777

    # Set the 'PATH' environment variable
    - POST: /env/PATH
      value: /usr/local/bin

The include section

The include section adds multiple sources for the cloud-init. For example reading configuration from both local file and cloud-init. The include section is a list of include sources that can be: file, load-from-cloud or remote.

  • file expect a path to a local file
  • remote expect

Example of using a local file and remote file

Set the modules/cloud-init/cloud-init.yaml to be:

run:
    - POST: /env/my_var
      val: myval
include: 
    - load-from-cloud

And set the modules/cloud-init/cmdline to

/usr/mgmt/cloud-init.so --force-probe --file /usr/mgmt/cloud-init.yaml;

This will set the environment variable my_var to be myval and load the data from cloud init. Note the force-probe flag, it is required if you are working with the ec2 simulator.