How to use LXD (Linux containers) in a shell script to create VM when the cloud instance launches

Posted on in Categories , , , last updated April 26, 2017

My cloud provider allows me to run a shell script when new Ubuntu Linux 16.04 LTS machine created. I want to install LXD service and create a one VM with specific private IP using a shell script? How do I create an LXD VM when the cloud server launches?

I am assuming that you are using Ubuntu 16.04 LTS cloud VM or bare metal server. You can install lxd using apt-get and use the lxc command to create an LXD VM.

Sample bash shell script

Here is a shell script to install LXD CentOS 7 vm:

#!/bin/bash
# Author: Vivek Gite
# Purpose: Create an LXD CentOS 7 VM on top of Ubuntu 16.04 LTS server
# License: GPL v2.0+
# ----------------------------------------------------------------------
## Set defaults ##
if_net="eth0"                # vm interface
br_net="lxdbr0"              # host bridge 
if_net_sub="10.105.28.1/24"  # subnet for br_net
if_net_ip="10.105.28.2"      # IP for vm
 
## VM name ##
vm_name="www-server"
 
## Vm distro. I am using CentOS ##
## You can use Gentoo, Arch, OpenSuse, Ubuntu, Debian and more ##
vm_distro="centos/7/amd64"
 
## bin path ##
_apt="/usr/bin/apt-get"
_lxd="/usr/bin/lxd"
_lxc="/usr/bin/lxc"
 
## Update base host ##
$_apt update
$_apt -y upgrade
 
## Install LXD on base os ##
$_apt -y install lxd
$_lxd init --auto
 
## Create new networking bridge ##
$_lxc network create ${br_net} ipv6.address=none ipv4.address=${if_net_sub} ipv4.nat=true
 
## Create vm ##
$_lxc init images:${vm_distro} ${vm_name}
 
## Config vm networking ##
$_lxc network attach ${br_net} ${vm_name} ${if_net}
$_lxc config device set ${vm_name} ${if_net} ipv4.address ${if_net_ip}
 
## Start vm ##
$_lxc start ${vm_name}
 
## Make sure vm boot after host reboots ##
$_lxc config set ${vm_name} boot.autostart true
 
## Install updates in CentOS 7 VM ##
$_lxc exec ${vm_name} -- /usr/bin/yum -y update
$_lxc exec ${vm_name} -- /usr/bin/yum -y upgrade
 
## Install package (optional) ##
$_lxc exec ${vm_name} -- /usr/bin/yum -y install epel-release
$_lxc exec ${vm_name} -- /usr/bin/yum -y install httpd htop

How do I call this script?

Calling script depends upon your hosting/cloud providers system. For example, Linode user can use StackScripts:

StackScripts provide Linode users with the ability to automate the deployment of custom systems on top of our default Linux distribution images. Linodes deployed with a StackScript run the script as part of the first boot process.

Here is an example for Linode cloud provider:

Fig.01: StackScripts - Run a shell script on Linode cloud
Fig.01: StackScripts – Run a shell script on Linode cloud

Amazon AWS EC2 can use shell script too:

When you launch an instance in Amazon EC2, you have the option of passing user data to the instance that can be used to perform common automated configuration tasks and even run scripts after the instance starts. You can pass two types of user data to Amazon EC2: shell scripts and cloud-init directives

Another option is to use cloud-init directives that executes when the cloud instance launches.

6 comment

  1. Thanks for taking time to create this doco. Is there a typo in the example script tho?

    I note that _lxd is defined twice. Obe to ref lxd binary and again to ref lxc.

  2. Following line has a typo
    _lxd=”/usr/bin/lxc”## Update base host ##
    Should be
    _lxc=”/usr/bin/lxc”## Update base host ##

  3. Looks like a typo in `_lxc` definition:
    _lxd=”/usr/bin/lxd”
    _lxd=”/usr/bin/lxc”

    Both strings define `_lxd`

  4. Nice article, thanks for sharing.
    One typo to fix. You’ve defined the variable “_lxd” twice, second one should’ve been “_lxc”.
    Cheers.

Leave a Comment