Skip to content

Create Linux-based image and Configure it using Cloud-init

In this tutorial, we are going to introduce cloud-init and how you can use it to customize Linux images for deployment.

What is Cloud-init ?

"Cloud-init is the industry standard multi-distribution method for cross-platform cloud instance initialization. It is supported across all major public cloud providers, provisioning systems for private cloud infrastructure and bare-metal installations."

In other words, cloud-init can help you automatically set up your Linux deployment images and ensures that a group of tasks is automatically done every time you deploy a new Linux server from that image. For example, automatically creating users, installing packages, resetting SSH keys, and more.

For Windows images, you can check cloudbase which is the Windows equivalent to Cloud-init.

You can check the cloud-init documentation to learn how to get started with cloud-init.

Cloud-init supported distributions

Cloud-init supports multiple distributions and clouds, both public and private.

It's also supports all major Linux distributions, FreeBSD, NetBSD, OpenBSD and DragonFlyBSD:

  • Alpine Linux
  • Debian
  • Fedora
  • FreeBSD
  • Gentoo Linux
  • NetBSD
  • OpenBSD
  • RHEL/CentOS/AlmaLinux/Rocky Linux/EuroLinux
  • Ubuntu

You can check the full list of available distributions and clouds on cloud-init documentation.

Cloud-init configuration

Cloud-init builds a single configuration. This configuration is built from multiple sources with different priorities. According to Cloud-init documentation, the higher-priority source overwrites the lower-priority source.

Configuration sources priorities

The following sources are organized from the lowest priority to the highest priority:

Configuration sources Description
Hardcoded config Config that lives within the source of cloud-init and cannot be changed.
Configuration directory Anything defined in /etc/cloud/cloud.cfg and /etc/cloud/cloud.cfg.d.
Runtime config Anything defined in /run/cloud-init/cloud.cfg.
Kernel command line On the kernel command line, anything found between cc: and end_cc will be interpreted as cloud-config user data.

Vendor and User Data

Added to the previous configuration are:

Both of them get fetched from the datasource and are defined at instance launch.

Much of what is defined in the base configuration can be overridden by vendor data and user data.

Datasources

These are the sources of configuration data for cloud-init, whether added by the user or the cloud that created the configuration drive.

Supported datasources

Below you can find some of the supported datasources, check the full list on cloud-init documentation

  • Amazon EC2
  • Azure
  • DigitalOcean
  • LXD
  • OpenStack
  • Oracle
  • VMware

Cloud config example

Check the cloud configuration examples provided on Cloud-init official documentation.

Configure a Linux-based image with Cloud-init and upload it to the whitesky.cloud BV portal

Let's assume that we have a local Linux-based image that we want to upload and use on the whitesky.cloud BV portal.

In the following step-by-step guide, we will illustrate how you can set up a Linux-based image locally. Then, we will configure this image using cloud-init to be compatible and ready to be uploaded to the whitesky.cloud BV portal.

As an example, we will use CentOS 7 for this tutorial.

Create CentOS 7 image locally

Prerequisites

  1. CentOS image from CentOS official website. In our case, we will use the CentOS-7-x86_64-NetInstall-2009.iso.
  2. Linux-based host.
  3. Install Virtual machine manager on your machine. Virtual machine manager allows you to view and manage your VMs using a simple GUI.

Note: You can use any prefered alternative for virtual machine manager to create and manage VMs.

If you faced the error of [ unable to connect to libvirt qemu:///system ] on the virtual machine manager. 1. Try to restart the VM.
2. If the error is still there then use the following commands:
sudo apt install qemu qemu-kvm libvirt-clients libvirt-daemon-system virtinst bridge-utils
sudo systemctl enable libvirtd
sudo systemctl start libvirtd
3. Then restart the VM and the virtual machine manager will work fine.

Now, everything is ready to start the configuration wizard of our CentOS 7 image.

  1. Open the virtual machine manager. Then, right-click on QEMU/KVM and click New.

    virtual machine manager

  2. Select Local install media (ISO image or CDROM). Then, click Forward.

    virtual machine manager

  3. Click Browse to choose the ISO source and select the new CentOS ISO that you previously downloaded. Then, click Choose Volume.

  4. Uncheck Automatically detect from the installation media/source and select Generic default or directly choose the OS version that you are trying to install. Then, click Forward.

    virtual machine manager

  5. Choose the size of Memory and CPUs. Then, click Forward.

    virtual machine manager

  6. Create a disk image for your VM and click Forward.

    virtual machine manager

    • Option 1: Virtual manager will create the disk image for you and just select the disk size.
    • Option 2: Create custom storage and choose its directory.
      1. Click Manage.
      2. Choose the directory where the disk will be created.
      3. Click and enter the disk name, maximum capacity and leave the format to be qcow2. Then, click Finish. virtual machine manager virtual machine manager
      4. Choose the newly created disk and click Choose Volume.
    • Enter the name of the VM and click Finish.

    virtual machine manager

  7. The newly created VM will start automatically and you can see the CentOS 7 installation wizard.

Installing CentOS 7 on QEMU/KVM

  1. Select Install CentOS Linux 7.

    CentOS Setup Wizard

  2. Select your installation language and click Continue.

    CentOS Setup Wizard

  3. Select the Installation Destination

    CentOS Setup Wizard

    1. Select the virtual harddrive.
    2. Under Storage Configuration, check the Automatic option.
    3. Click Done.
  4. Select Network & Host Name

    CentOS Setup Wizard

    1. Enter the Host Name (e.g localhost) and click Apply.
    2. Enable the Ethernet toggle to activate the network adapter. Once it's activated click Done.

    Sometimes Installation Source could display an Error setting up base repository. After setting up the network, open the Installation Source and in the URL enter the CentOS Mirror URL http://mirror.centos.org/centos/7/os/x86_64/.

  5. Select Software Selection

    CentOS Setup Wizard

    1. Choose the desired base environment and decide if you want to add any Add-Ons to that environment.
    2. Click Done.
  6. Click Begin Installation.

    CentOS Setup Wizard

  7. Create a new user for your OS.

    CentOS Setup Wizard

    1. For User Creation
      • Enter your Full name, User name, Password and Confirm Password.
      • Check the Make this user administrator option.
    2. For Root Password
      • This is optional if you already chose to check the Make this user administrator option while creating your new user.
      • If you didn't make your user an administrator, then you can set a root password.
  8. Once the installation is finished successfully, click Reboot.

    CentOS Setup Wizard

After rebooting the machine, you can log in using the username and password that you set before.

CentOS Setup Wizard

Configure Cloud-init on CentOS 7

Prerequisites

  1. Make sure that cloud-init isn't installed on your image using the following command:
    cloud-init --version
    
  2. A Text editor of your choice. For this tutorial, we will use Vim editor and you can install it using the following command:
    sudo yum install vim-enhanced
    

Now we can start installing/configuring Cloud-init on our CentOS 7 image.

  1. Install cloud-init and its dependencies on your image using the following command.
    sudo yum install cloud-init
    
  2. Test the installation using the following command
    cloud-init --version
    
  3. Now cloud-init is installed but most probably it will be disabled, you can check the cloud-init status using the following command
    sudo cloud-init status --wait
    
  4. Access the following file /etc/cloud/cloud.cfg with vim using the following command
    sudo vim cloud.cfg
    
  5. Add the following data to cloud.cfg

    ssh_pwauth: true
    manage_resolv_conf: false
    
    datasource_list: [ Ec2 ]
    datasource:
        Ec2:
            metadata_urls: ["http://169.254.169.254:80", "http://instance-data:8773"]
            max_wait: 120
            timeout: 50
            apply_full_imds_network_config: true    
    

    cloud.cfg file

    We used Ec2 as a datasource since whitesky.cloud BV portal is compatible with updating Ec2. To make it simple, we will just use the default values for Ec2 datasource. Check cloud-init documentation to see other datasources and examples of how you can configure each of them.

  6. Add resolv_conf module in the cloud_init_modules section after update_etc_hosts module.

    cloud.cfg file

  7. Save the changes that you made on cloud.cfg by pressing ESC then type :wq!

  8. Enable and start the cloud-init related services by running the following commands separately
    sudo systemctl enable cloud-init-local.service
    sudo systemctl enable cloud-init.service
    sudo systemctl enable cloud-config.service
    sudo systemctl enable cloud-final.service
    sudo systemctl start cloud-init.service
    sudo systemctl start cloud-init-local.service
    sudo systemctl start cloud-config.service
    sudo systemctl start cloud-final.service
    
  9. Create a new file /etc/cloud/ds-identify.cfg and add the following data.
    policy: search,found=all,maybe=all,notfound=disabled
    
  10. Update the NetworkManager package to the latest version provided by RedHat.
    sudo yum upgrade NetworkManager
    
  11. Now cloud-init is configured and the status should be changed to done, you can check the cloud-init status using the following command
    sudo cloud-init status --wait
    

Uploading your image to whitesky.cloud BV portal

Note: You will need to upload your image to an HTTP server to make it accessible through a URL that will be used next in the image uploading to whitesky.cloud BV portal.

  1. Open your whitesky.cloud BV portal, click Locations in the left menu.
  2. Choose the desired location to upload your image.
  3. Click ADD VIRTUAL MACHINE IMAGE at the top bar.
  4. Enter your cloud image information:
    • Name - Cloud image name.
    • URL - Link of the image that you uploaded to an HTTP server before.
    • Boot type - Boot type of your image.
    • OS type - Type of the operating system of your image.
    • OS name - Name of the operating system of your image.
    • Memory size - Memory size needed by the image to operate.
    • Boot disk size - Boot disk size needed by the image to operate.
  5. Click ADD VIRTUAL MACHINE IMAGE.

Wait until the upload process is finished, then check the VM images on your location and you can find your new VM image with status: CREATED and it is now ready to use.

Testing your new cloud image

  1. Open your cloudspace that is created in the same location as your cloud image.
  2. Click CREATE VM at the top of the page.
  3. Select Create from an image option.
  4. A list of images will appear, select your newly uploaded cloud image.
  5. Configure the sizes of:
    • vCPUs
    • Memory
    • Boot disk
  6. Add configuration details for your VM:
    • Name
    • Description (optional)
    • Private IP (optional)
    • SSH key (optional, for Linux based OSs).
  7. Click CREATE VIRTUAL MACHINE.
  8. Open the VM using console at the top of the page.
  9. If cloud-init is configured correctly, you will be allowed to log in using:
    1. whitesky.cloud BV provided credentials which you can find on the VM details page.
    2. The initial credentials that you configured on your image locally.
  10. Test that the cloud-init status is set to be done using the following command.

sudo cloud-init status --wait
Cloud-init status check

Create a new VM with API and add a new user using Cloud-init

We can create a new VM on whitesky.cloud BV using APIs. Additionally, we can configure our userdata as a payload to create a new user using cloud-init.

  1. Use the following POST request to create a VM on the whitesky.cloud BV portal.

    POST/customers/<CUSTOMER_ID>/cloudspaces/<CLOUDSPACE_ID>/vms
    
  2. Add the parameters to configure the VM.

    Parameters:
        {
            "name": "my-new-centos-vm",
            "description": "new vm created with newly uploaded CentOS 7",
            "vcpus": "2",
            "memory": "4096",
            "image_id": "625",
            "disk_size": "15",
            "os_type": "Linux",
            "os_name": "Centos 7",
            "boot_type": "bios"
        }
    
  3. Use cloud-init configuration in your request payload to create a simple user.

    Payload:
        {
            "userdata": {
                "users": [
                {
                "name": "newUser",
                "groups": "users",
                "lock_passwd": false,
                "plain_text_passwd": "test1234",
                "shell": "/bin/bash"
                }
                ]
            }
        }
    
  4. Open your newly created VM on the whitesky.cloud BV portal and log in with your new user credentials.

    New user login

To learn more about using APIs on the whitesky.cloud BV portal check portal.whitesky.cloud/api/1. You can find more cloud-init configurations on Cloud-init documentation.