How to create Virtual machines using cloud-init

Want to create virtual machines frequently? Consider using “cloud-init.” Before going into the usage of cloud-init, let’s understand what cloud-init is and why we need it. Cloud-init allows users to write down their desired configurations into a YAML file before creating the VM. During the creation of the VM, the YAML configuration file will be automatically read. During the first boot of the virtual machine, cloud-init will read all the configurations from the cloud-config YAML file and implement those configurations automatically.

The bottom line here is “Sow once, Reap unlimited.” Sowing means designing your own cloud-config YAML once, reaping means creating pre-configured VMs unlimitedly. 

By providing the YAML file, all the manual configuration is automated and will be taken care of by cloud-init. Of course, you would have to write your YAML file with your desired settings. 

  1. You want to create virtual machines frequently  
  2. You want to make a bunch of virtual machines. 

This post will use multipass with cloud-init to create virtual machines. If you want to read more about multipass, check out here

Let’s start with a problem statement. When we create a Virtual machine following are the few(not limited to) configurations we do on each virtual machine. Let’s assume that we need to create a few Virtual machines daily and manually configure the below configuration on each virtual machine. Configuring the same on multiple virtual machines would be a monumental task. Even if automated, the time taken would be too much. 

  1. Create a user
  2. Set up the SSH public Key
  3. Add the User to Sudo
  4. Disable root
  5. Perform package update(apt update)
  6. Install desired packages(Example: apt install python3-pip)
  7. Network
  8. CPU, RAM, Disk
  9. Many more as per custom requirement

The solution to this is cloud-init. The user can write all the desired configurations to a YAML file in cloud-init. You can supply this YAML file during VM creation. All the configurations would be read from YAML and applied on the VM during the first boot.  Now you can create an infinite number of virtual machines using the same YAML with all the configurations pre-applied on the virtual machine. 

Using Cloud-init with Multipass:

multipass launch command provides –cloud-init flag to supply the input cloud-config YAML file during the creation of the virtual machine. The syntax to use the input file as follow:

multipass launch --name my-new-vm-cloud-init --cloud-init <input.yaml>

Sample cloud-config YAML file,  The file must start with #cloud-config

#cloud-config                                                                           # DO NOT DELETE THIS LINE
timezone: America/Chicago # set the timezone of the VM
users: # This is a list of users you want to add under
- name: foo # adding a user called "foo"
sudo: # Adding foo to sudo
- 'ALL=(ALL) NOPASSWD:ALL' # providing the password-less sudo privileges to foo for all the commands
groups: [sudo,admin] # adding the used to sudo and admin user groups
shell: /bin/bash # setting /bin/bash as default shell
ssh_authorized_keys: # adding your public key to authorized_keys in the VM. (see below for instruction)
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINUOyd3Wk3BnlA1hcdBFd6RTUaaY4Figwmi9LU34w2aX #adding one public key to authorized_key, you can add multiple in next line
package_update: true # perform apt update
packages: # list of the packages to install after first boot
- - python3-pip # as an example installing pip3 during the first boot.
write_files: # To write some characters into any file create list of items.
- content: | # 1st content
alias k='kubernetes' # writing "alias k='kubernetes'" to /etc/profile
export dr='--dry-run=client -oyaml' # writing "export dr='--dry-run=client -oyaml'" to /etc/profile
path: /etc/profile # name of the file where content is written.
permissions: '0755' # file permissions


In case you wondering how to generate an SSH key on your host machine, run the following command:

ssh-keygen -t ed25519 -c mylocalhost

Another example of cloud-config YAML file:

#cloud-config
ssh_deletekeys: false
timezone: America/Chicago
users:
- name: foo
sudo:
- 'ALL=(ALL) NOPASSWD:ALL'
groups: [sudo,admin]
shell: /bin/bash
ssh_authorized_keys:
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINUOyd3Wk3BnlA1hcdBFd6RTUaaY4Figwmi9LU34w2aX
package_update: true
packages:
- - python3-pip
write_files:
- content: |
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACDVDsnd1pNwZ5QNYXHQRXekU1GmmOBYoMJovS1N+MNmlwAAAJipPTDsqT0w
7AAAAAtzc2gtZWQyNTUxOQAAACDVDsnd1pNwZ5QNYXHQRXekU1GmmOBYoMJovS1N+MNmlw
AAAEBkAERgrWbygTxyucVuV0aoZKtPDx+3V1DUf+J/wPLP09UOyd3Wk3BnlA1hcdBFd6RT
UaaY4Figwmi9LU34w2aXAAAAFXByYXRlQERFU0tUT1AtNEhGTkYzSw==
-----END OPENSSH PRIVATE KEY-----
path: /home/foo/.ssh/id_ed25519
permissions: '0600'
append: true
- content: |
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINUOyd3Wk3BnlA1hcdBFd6RTUaaY4Figwmi9LU34w2aX
path: /home/foo/.ssh/id_ed25519.pub
permissions: '0644'
append: true
runcmd:
- chown -R foo:foo /home/foo

Example: 

Sample cloud-config file

Example of using a cloud-config YAML file:

The following image shows that a YAML file is supplied to multipass to create the virtual machine. This cloud-config file contains the timezone info, public, keys, packages update, pip installations, etc. 

Using a cloud-config file with multipass

References: 

https://cloudinit.readthedocs.io/en/latest/topics/examples.html 

https://multipass.run/

Creating multiple Virtual Machines Fast using multipass – Technekey

Leave a Comment

Your email address will not be published.

Scroll to Top