For quite some time now, I’ve been using a SIP phone (Yealink T38G) at home with multiple SIP accounts linked to it. It has been a great solution but I decided to take the next big step and setup an Asterisk box And whilst I was at it – thought it would be great to have it hosted in the cloud as well. This is where Amazon’s AWS EC2 comes in – cheap virtualised hosting (and free for the first year!!)
I spent days online trying to figure out the best way to do this. After failing multiple times to do an Asterisk and FreePBX install (from scratch) directly on an instance in the cloud, I decided to rather build a machine locally (using the FreePBX distro) and try upload it somehow. There are quite a few tutorials out there explaining how to create a local machine on VirtualBox and then how to convert/deploy it to AWS, but they are all so complicated, cumbersome and outdated. I then stumbled across a post on The University of Southern California Information Science Institute’s website (what a mouthful) explaining how to build a CentOS 6 machine locally and deploy it as an AWS EC2 instance. This was perfect – seeing FreePBX’s distro is based on CentOS 6 A massive thank you to Gideon Juve for his Wiki post at USC ISI which I based most of the steps below on
For this article I’ll assume you know the basics of Amazon AWS EC2 – creating instances, how to SSH into the instances etc.
Create a new Virtual Machine
Install VirtualBox – available from here.
Start VirtualBox and create a new virtual machine. You can call it whatever you want, but I used “FreePBX”. The OS should be “Linux” and the version should be “Red Hat”. (I used 32 bit instances of everything but I guess you could use 64 bit instances if you wanted.)
Give it at least 1024 MB of memory. This is so that the installer can run as a GUI which will help with the partitioning later.
Create a new virtual disk. Use VMDK format. Set it to be dynamically allocated. It is NOT necessary to split it into files of less than 2GB.
You can specify the location of the virtual disk and the name. I just left those at the defaults. I also used the default 8GB size. Since the virtual disk is dynamically allocated it won’t really take up that much space.
Install FreePBX Distro on the new VM
Download the latest FreePBX Distro from here. (32 bit Stable-2.210.62-3 in my case.)
Link the downloaded ISO to the new VM in VirtualBox by going to the Settings -> Storage. Click the little CD on the left labelled “Empty”. Under “Attributes” on the right click the little CD image and select “Choose a virtual CD/DVD disk file…” Browse to and select the .iso FreePBX file you just downloaded. Press OK.
Start the new VM.
Below your selected version of Asterisk (1.8 in my case), select the “Advanced” install option.
Accept the default settings for TCP/IP.
At this point it will start the graphical installer. When the warning pops up select “Yes, discard any data”.
Select appropriate time zone.
Enter and confirm a strong root password.
When it gets to asking about disk partitioning, use the “Create Custom Layout” option. Create a standard partition with ext4 mounted at / that is filled to the maximum size. This step is really important. You don’t want to mess this up because it will make things really complicated when you try to move this to Amazon. Create one partition (/dev/sda1), and that’s all. No separate /boot partition, no LVM, no /home partition, no swap.
Ignore the warning about swap, write the changes, and format the disk.
Install the boot loader without a password.
At this point the installer will install CentOS and Asterisk. Make sure you are connected to the internet so that FreePBX can be downloaded and installed too. The VM will reboot when done.
Configure the VM
Log in as root.
Edit menu.lst by typing # vi /boot/grub/menu.lst (press “i” to start editing, “esc” to stop editing and “:” “x” “enter/return” to save the file):
- Set the GRUB option “timeout=0″ so that it will start the default kernel immediately.
- Append “selinux=0″ to the kernel options to disable SELinux.
To disable the firewall (seeing we’ll be using EC2′s security groups), either:
- # chkconfig iptables off
- or edit iptables by typing # vi /etc/sysconfig/iptables and remove all the INPUT entries and replace them with a single line: “-A INPUT -j ACCEPT”
Since we aren’t using LVM type # chkconfig –level 12345 lvm2-monitor off (sorry this blog doesn’t show this, but there should be two hyphens as in hyphen hyphen “level” with no spaces between the two hyphens and the word “level”)
Power VM off # poweroff
Compress and upload the VM
Locate the .vmdk file of the VM on your computer and compress it to a .gz file (this speeds up the time taken to upload the image). On my Mac I just copied the VM’s .vmdk to my desktop, opened Terminal and ran # gzip ~/Desktop/FreePBX.vmdk (On a PC you can use 7-zip to compress to a .gz)
I decided to use Dropbox as a middle man to get this compressed VM into the cloud. Hopefully you already have Dropbox installed, if not, then you’re really missing out on a great app! Copy the compressed VM (FreePBX.vmdk.gz) to your “Public” Dropbox folder. It can take a while for the file to be uploaded into the cloud though…
Once the file has uploaded, take note of it’s Dropbox public link.
Deploying the image on Amazon EC2
The next thing we will do is deploy the new VM we created with VirtualBox to Amazon EC2.
CentOS 6 has a Xen-compatible kernel, so no complex kernel stuff is required for this.
I did all this using SSH via Terminal on my Mac.
I was logged into N. Virginia and used zone us-east-1a for this tutorial (not sure if the CentOS VM I use for the getsshkey script is available in other regions).
Copying the .vmdk to Amazon EC2
Just a heads up – I used two separate instances in EC2 to do the following steps – an Ubuntu machine for the qemu conversion and a CentOS machine for the copying of the getsshkey script. (I struggled to get qemu working on the CentOS machine and thus just opted to use an Ubuntu machine for that step instead.)
First, log into the EC2 Console and launch a new instance – we’ll be using this instance to convert the .vmdk to raw. I used the standard Ubuntu Server 184.108.40.206 LTS (32 bit) for this.
In the volumes view, create and attach a standard 8GB volume to the Ubuntu VM you just started. The size of the volume must match the size of the virtual disk you created using VirtualBox.
SSH into your Ubuntu VM as user “ubuntu”.
Transfer the compressed .vmdk to your Ubuntu VM on EC2 by typing:
- # sudo -i
- # cd /tmp
- #wget https://dl.dropbox.com/u/1234567890/FreePBX.vmdk.gz (remember to replace this with your Dropbox public link)
Once downloaded, uncompress with # gunzip FreePBX.vmdk.gz
- # apt-get update
- #apt-get install qemu
The conversion instance should have a couple disks attached to it that you can see by typing # fdisk -l These may be /dev/sdX or /dev/xvdX where X is some letter. I got a /dev/xvda1, which is the root partition of the running VM, and /dev/xvdf, which is the blank volume we attached earlier.
Copy/convert the .vmdk to a disk image using # qemu-img convert -f vmdk FreePBX.vmdk -O raw /dev/xvdf (note your volume)
That operation is going to write a partition table to the blank volume (takes a little while), so you need to rescan the device to pick up the new partitions. You can do that with # partprobe /dev/xvdf
After running that command you should see a new device called ‘/dev/xvdf1′ by doing # fdisk -l again. Thats the partition you created when you installed the FreePBX Distro using VirtualBox.
You are now done with the Ubuntu VM so # poweroff
Reconfiguring the VM Image for EC2
Launch a new instance – a CentOS 6 VM this time. I’m on us-east and thus used ami-02f85a6b from the community AMIs (this is a 32 bit CentOS 6.2 VM containing the getsshkey script we need). If you’re in a different region, go here and look under the heading “CentOS Linux MultiCloud Images” for the appropriate ami.
In the volumes view, detach the volume we created earlier from the Ubuntu machine (should be the one without a snapshot ID) and attach it to the CentOS machine we just launched.
SSH into your CentOS VM as user “root”.
Run # fdisk -l to note the attached disks. I got a /dev/xvde1, which is the root partition of the running CentOS VM, and /dev/xvdj1, which is the FreePBX volume we just attached.
Mount the FreePBX partition with # mount /dev/xvdj1 /mnt
We need to make a few changes to the image so that it will boot on EC2.
Copy the getsshkey script from the CentOS VM to the FreePBX image: # cp /etc/init.d/getsshkey /mnt/etc/init.d/
Chroot to the FreePBX image so that we can update it: # chroot /mnt
Enable the getsshkey init script: # chkconfig –add getsshkey (sorry this blog doesn’t show this, but there should be two hyphens as in hyphen hyphen “add” with no spaces between the two hyphens and the word “add”)
Edit menu.lst by typing # vi /boot/grub/menu.lst to change the kernel options:
- Append “console=hvc0″ to kernel options
- Append “nomodeset” to kernel options
Edit cfg-eth0 by typing # vi /etc/sysconfig/network-scripts/ifcfg-eth0 so that the OS can bring up the network interface:
- Delete UUID and HWADDR lines
Exit from the chroot: # exit
Unmount the new image: # umount /mnt
You are now done with the CentOS VM so # poweroff
Create new FreePBX instance on EC2
In the EC2 Management Console, detach the FreePBX volume and create a snapshot of it.
Once the snapshot has finally been created, register the snapshot as a new AMI (Create Image) using the latest pv-grub hd00 kernel (not the hd0 kernel) and /dev/sda as the root device (not /dev/sda1). For region us-east-1 you should use kernel aki-b2aa75db. For other regions, have a look at the list here under the heading “Amazon Image Kernel IDs”.
Launch a new instance using your AMI (your AMI should appear under “My AMIs”). Take note of the security info below…
Remember to create a security group with the following ports open:
- TCP 22 (SSH)
- TCP 80 (HTTP)
- UDP 4569
- UDP 5060
- UDP 10000-20000
Where possible, try to limit the port ranges to your ISP’s range for additional security.
Now allocate and/or associate an elastic IP to your new FreePBX instance.
Browse to this IP in your browser and setup your Asterisk box via the FreePBX GUI. Remember to change all default passwords in the GUI and to use strong passwords for your extensions!!