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

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.

ADVERTISEMENTS

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.

🐧 Get the latest tutorials on SysAdmin, Linux/Unix, Open Source/DevOps topics:
CategoryList of Unix and Linux commands
File Managementcat
FirewallCentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network Utilitiesdig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNCentOS 8 Debian 10 Firewall Ubuntu 20.04

ADVERTISEMENTS
6 comments… add one
  • Andy Apr 26, 2017 @ 15:26

    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.

  • Frank Apr 26, 2017 @ 15:49

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

  • George L. Yermulnik Apr 26, 2017 @ 16:23

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

    Both strings define `_lxd`

  • 🐧 Vivek Gite Apr 26, 2017 @ 16:47

    Andy/George/Frank ,

    Thanks for the heads up. I fixed the typo.

  • Bart Apr 26, 2017 @ 18:28

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

    • Bart Apr 26, 2017 @ 18:30

      Undo. It was fixed while i was reading/responding.

Leave a Reply

Your email address will not be published.

Use HTML <pre>...</pre>, <code>...</code> and <kbd>...</kbd> for code samples.