Packer-cloudstack
This adds a plugin to Packer to talk to Apache
Cloudstack. It supports both
bootstrapping a OS installation to a empty block device as well as
extending existing templates.
Install the plugin
First at all, you should have already installed Packer and have it added to your PATH.
Docker way
If you have a running Docker, you can build and run the image without having to install anything :
# From the root of the repository
docker build -t packer-cs-build .
cd $PACKER_BIN_PATH/
docker run packer-cs-build > ./packer-cs.tgz
tar xzf ./packer-cs.tgz && rm -f ./packer-cs.tgz
Manual way
To install this plugin you will need to have Go installed as well as
the needed version control tools for the dependencies. Here we assume
a Red Hat derivate, please adjust to your native OS package manager
(e.g. apt-get or brew).
export GOPATH=$HOME/go
mkdir -p $GOPATH
export PATH=$PATH:$GOPATH/bin
sudo yum install hg git bzr -y
go get -u github.com/mitchellh/gox
go get -u github.com/mindjiver/packer-cloudstack
make -C $GOPATH/src/github.com/mindjiver/packer-cloudstack updatedeps dev
How it works ?
The diagram below shows how to perform a full OS installation (Red Hat
derivate) via PXE chainloading onto an empty block
device. The
special chain boot iPXE ISO needs to be built with an embedded script,
Embedding script in iPXE. The following
snippet should be enough to generate the chainloader ISO from scratch:
sudo yum install -y genisoimage
git clone git://git.ipxe.org/ipxe.git
cd ipxe/src
wget http://ftp.sunet.se/pub/os/Linux/distributions/centos/6/os/x86_64/isolinux/isolinux.bin
cat << EOF > chainload.ipxe
#!ipxe
dhcp
sleep 10
chain http://\${dhcp-server}/latest/user-data
EOF
make ISOLINUX_BIN=isolinux.bin EMBED=chainload.ipxe
The resulting bin/ipxe.iso file needs to be uploaded to your
Cloudstack instance. Specify Other (32-bit)
as the OS type for
the ISO. Also note the resulting UUID as you will need be use this
inside the Packer JSON configuration files.
Packer configuration example
The JSON payload below will utilize the special iPXE ISO as well as
spin up a local web server on the Packer build workstation. This web
server will then serve the neccessary files to perform the full OS
installation. This assume we have exported some environment variables
for the API end point and the API and secret keys. This will avoid
having to hard code these values inside the JSON files which normally
will be stored under version control (e.g. git).
export CLOUDSTACK_API_URL="https://cloudstack.local:443/client/api"
export CLOUDSTACK_API_KEY="AAAAAAAAAAAAAAAAAA"
export CLOUDSTACK_SECRET_KEY="AAAAAAAAAAAAAAAAAA"
Currently there is no support for using display names of service
offerings, zones, etc. So one needs to add the UUID here. Also note
that the hypervisor type needs to be specified so update this
accordingly. This builder has been verified to work with Xenserver and
VmWare.
{
"provisioners": [
{
"type": "shell",
"scripts": [
"scripts/base.sh",
"scripts/motd.sh",
"scripts/version.sh",
"scripts/chef-client11.sh",
"scripts/setupvm.sh",
"scripts/tuned.sh",
"scripts/tuneio.sh",
"scripts/xs-tools.sh",
"scripts/vmtweaks.sh",
"scripts/cleanup.sh",
"scripts/zerodisk.sh"
]
}
],
"builders": [
{
"type": "cloudstack",
"hypervisor": "xenserver",
"service_offering_id" : "4ccec2a3-0b53-4db0-aebc-6735019581b2",
"template_id" : "b34f2d7b-2bec-497e-a18e-06d0de94526e",
"zone_id" : "489e5147-85ba-4f28-a78d-226bf03db47c",
"disk_offering_id" :"ef781d7f-f8e8-4f73-985c-e0b0a8ef8d48",
"network_ids" : ["9ab9719e-1f03-40d1-bfbe-b5dbf598e27f"],
"ssh_username": "root",
"ssh_key_path": "data/vagrant_insecure_private_key",
"ssh_timeout": "15m",
"state_timeout": "30m",
"template_name": "centos-6.5-20gb-chef11",
"template_display_text": "CentOS 6.5 20GB chef11",
"template_os_id": "144",
"http_directory": "web",
"user_data": "#!ipxe\nkernel http://{{.HTTPIP}}:{{.HTTPPort}}/vmlinuz ks=http://{{.HTTPIP}}:{{.HTTPPort}}/ks.cfg\ninitrd http://{{.HTTPIP}}:{{.HTTPPort}}/initrd.img\nboot"
}
]
}
Vmlinuz, initrd and kickstart files are all served from the webserver
Packer spins up on the local workstation that is also performing the
API calls to Cloudstack.
To continue the provisioning using Packer we need to add the user
and/or key we define in the JSON configuration file. An example on how
to do this using a CentOS kickstart file is available below. In this
example we use the well known Vagrant SSH key pair. This of course
needs to be removed after the provisioning has been performed.
install
url --url http://ftp.sunet.se/pub/os/Linux/distributions/centos/6/os/x86_64/Packages/
lang en_US.UTF-8
keyboard sv-latin1
network --bootproto=dhcp --noipv6 --onboot=yes
authconfig --enableshadow --passalgo=sha512
rootpw --iscrypted $6$BbYMtjYH1Xm6$JwsqvNUpqyBiedELVG5aXeTyZXwWhdJ6gTFzrsgA9bykApjz/GrdKqadgvPV38fSM/R8ci3ju5RNm7RB1uQsr.
firewall --disabled
selinux --disabled
timezone --utc Europe/Stockholm
bootloader --location=mbr --append="notsc clocksource=hpet"
text
skipx
zerombr
clearpart --all --initlabel
part /boot --fstype=ext4 --asprimary --recommended --size=100 --fsoptions "defaults,noatime"
part / --fstype=ext4 --grow --asprimary --size=100 --fsoptions "defaults,noatime,data=writeback,barrier=0,nobh,commit=15"
part swap --recommended
firstboot --disabled
reboot
%packages --ignoremissing
@base
@development
kernel-devel
kernel-headers
tuned
%end
%post
mkdir -p /root/.ssh/
cat > /root/.ssh/authorized_keys <<'END_OF_KEY'
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key
END_OF_KEY
chmod 0700 /root/.ssh/
chmod 0600 /root/.ssh/authorized_keys
%end