Contextualization

To contextualize a VM means to configure it at instantiation time. This consists in passing additional parameters to the instantiation command, allowing scripts with specific parameters to be executed during the VM initialization sequence.

Examples of the available options:

  • add SSH keys;
  • install software;
  • configure a site specific storage access;
  • collect logs.

It is a way to keep a generic image and specialize it at instantiation according to various parameters.

Warning

CC-IN2P3 cloud supports contextualisation by “cloud-init”. It is therefore necessary that this package is installed in the VM image and properly configured.

Valid input sources

cloud-init may be powered by different types of input files. The most common are:

  • cloud-config configuration files:

They will override the cloud-init VM configuration. These text files start with the following header:

#cloud-config

They will define the cloud-init modules to use and their parameters. Their content and their syntax will be described below.

  • Shell scripts:

It is possible to provide cloud-init with a shell script, to be automatically executed at the end of the VM startup. These scripts do not require any specialization, and any shell script that has a standard type header

#!/bin/sh

provided to cloud-init will be executed automatically.

  • Combined files:

It is possible to combine different types of files into one in order to send them to cloud-init. This is done via the “write-mime-multipart” utility, provided in particular by the “cloud-utils” packages. Example:

% write-mime-multipart --output=combined-userdata.txt \
  my-user-script.sh \
  my-cloudconfig.txt

Note

There are other types of files that can be used with cloud-init, for more information you can refer to the attached cloud-init documentation.

cloud-config files syntax

cloud-config files consists in 2 main sections:

  1. Configuration elements such

    parameter: value
    

    or

    parameter:
     - value
     - value
    
  2. Activated modules, providing various configuration options. In the same way, the list turns up as follows:

    cloud_config_modules:
     - module1
     - module2
    

Among the most useful modules we may address:

  1. SSH configure sshd, generate keys and add them to authorized_keys
  2. set-passwords modify passwords
  3. runcmd automatic execution of rc.local command types
  4. mounts partition mounting management
  5. phone_home send data to an address at the end of the instantiation

Note

Modules are written in python and stored in /usr/lib/python2.6/site-packages/cloudinit/CloudConfig/

The default cloud-config configuration is the one located in /etc/cloud/cloud.cfg, it will be overridden by the configuration received during the instantiation, as described in the following paragraph.

Many configuration examples are available in /usr/share/doc/cloud-init/examples/

Execute a script

Depending on the use case:

  1. Provide the script path to the boot command:

    % nova boot [...] --user-data /path/script.sh [...]
    

or

  1. describe the commands to execute in the cloud-init configuration file:

    % cat cloudinit.cfg
    #cloud-config
    runcmd:
     - [ wget, "http://slashdot.org", -O, /tmp/index.html ]
     - [ sh, -xc, "echo $(date) ': hello world!'" ]
    [...]
    
    cloud_init_modules:
     - runcmd
    [...]
    
    cloud_final_modules:
     - scripts-user
    [...]
    
  2. then start the instance with the configuration:

    % nova boot [...] --user-data /path/cloudinit.cfg [...]
    

Note

Contrary to what indicated in the cloud-init doc, the runcmd module alone will only create a script from the commands given but will not execute anything. You must add the scripts-user module in the cloud_final_modules section for the script to run.

Examples

  • Perform specific mounts
  1. create the file cloud-config.txt having a mounts section. For example, to mount /dev/vdb dans /scratch with the options “nosuid,nodev”:

    #cloud-config
    [...]
    mounts:
     - [ vdb, /scratch, auto, "nosuid,nodev", "1", "2" ]
    [...]
    cloud_config_modules:
    [...]
     - mounts
    [...]
    
  2. for each mount create in this section an entry in table format where the fields are equivalent to those in /etc/fstab

  3. instantiate a VM with a flavor providing an ephemeral disk, giving the cloud-config file

    % nova boot --image [...] --flavor [...] --user-data ./cloud-config.txt [...]
    
  • Configure the pre-existing “cloud-user” and allow SSH connection:

    #cloud-config
    user: cloud-user
    ssh_authorized_keys:
        - ssh-rsa XXXXXXX[...]
    ssh_pwauth: True
    
    chpasswd:
      list: |
        cloud-user:passw0rd
      expire: False
    [...]
    cloud_config_modules:
    [...]
     - ssh
     - set-passwords
    [...]
    
  • configure cloud-init not to set the hostname at startup on the instance name:

    #cloud-config
    preserve_hostname: true
    

Note

/dev may be omitted for the following entry types: xvd, sd, hd ou vd.

If the mount point does not exist, it will be created.

Do not forget to list the necessary modules among the actives in cloud-config.

  • to automatically resize an LVM partition and the volumes contained at the VM creation:

    #cloud-config
    
    cloud_init_modules:
      - growpart
      - [ runcmd, instance ]  # The "instance" keyword specifies to run this configuration only once per instance.
    
    growpart:
      mode: growpart        # The growpart tool must be present in the image used to create the VM (this is the case in the image official-centosCC-7x-x86_64 since nov 2017).
      devices:
        - '/dev/vda2'      # Verify the LVM partititon name in the image
    
    runcmd:
      - 'bash -c "pvresize /dev/vda2"'                    # Resize the LVM physical volume
      - 'bash -c "lvresize -r -l +10%FREE rootvg/tmp"'    # Resize logical volumes and underlying partitions using a percentage of free space in the volume group
      - 'bash -c "lvresize -r -l +33%FREE rootvg/usr"'
      - 'bash -c "lvresize -r -l +25%FREE rootvg/root"'
      - 'bash -c "lvresize -r -l +100%FREE rootvg/var"'
    
    cloud_final_modules:
      - [ scripts-user, instance ]
    

References

  • Online documentation: https://help.ubuntu.com/community/CloudInit
  • Contents details of a cloud-config file: check /usr/share/doc/cloud-init/examples/cloud-config.txt on a virtual machine where cloud-init is installed.