Tuesday, October 20, 2015

Local Vagrant VM as part of a deployment strategy

Local Vagrant VM as part of a deployment strategy

Previously I discuss setting up a Vagrant EC2 VM for web application deployment. In this post, I will walk through the process of setting up a local development VM with the objective of maintaining a commmon environment between the local and remote (EC2) VM’s.

The local VM

I assume that you’ve already installed Virtual Box guest additions

(1) Create the directory for the new Vagrant configuration files – I will call mine vagrant-local mkdir vagrant-local – and move to that directory cd vagrant-local.

(2) Create a new vagrantfile, using your favorite text editor (e.g., vi vagrantfile) and insert the following text

Vagrant.configure(2) do |config|
  config.vm.box = "hashicorp/precise64"
  config.vm.network "forwarded_port", guest: 80, host: 8080
  config.vm.synced_folder "..\\vagrant_data", "/vagrant_data"
  config.vm.provider "virtualbox" do |vb|
  #   # Display the VirtualBox GUI when booting the machine
    vb.gui = false
  #   # Customize the amount of memory on the VM:
  #   vb.memory = "1024"
  # config.vm.provision :shell, path: "bootstrap.sh"

(3) Save this file, and bring the vagrant VM vagrant up

(4) As you install packages, make sure to add those lines to a new file, (vi bootstrap.sh). You can also add checks where necessary. My bootstrap.sh is long, but here’s a portion of it for example:

#!/usr/bin/env bash

# install and configure linux tools
sudo apt-get -y update
# sudo apt-get -y upgrade
sudo apt-get -y install unattended-upgrades make vim acl
sudo addgroup web
sudo adduser www-data web
sudo usermod -a -G web vagrant

# apache install and config
sudo apt-get install -y apache2
if ! [ -L /var/www ]; then
  rm -rf /var/www
  ln -fs /vagrant_data /var/www
sudo chown www-data:web /var/www
sudo a2enmod rewrite
sudo /etc/init.d/apache2 restart

# sqlite install and config
sudo apt-get -y install sqlite3 libspatialite3 spatialite-bin

(5) Uncoment line second to end (config.vm.provision :shell, path: "bootstrap.sh") in your vagrantfile with your favorite text editor (e.g., vi vagrantfile) to configure provisioning via bootstrap.sh on a new VM when vagrant up is run.

You will need to make the same changes to ..\vagrant-aws\vagrantfile and a ..\vagrant-aws\bootstrap.sh, created in the previous post, to syncronize your development and deployment provisioning

(6) Destroy the existing vagrant instance, including all files created when you brought it up vagrant destroy and bring up the new instance vagrant up

Written with StackEdit.

Friday, October 16, 2015

Vagrant on AWS with Windows

Vagrant on AWS with Windows

Required installations:
– VirtualBox
– Vagrant
– an existing EC2 instance with an account private key on your local file system.

[Optional] If you use PuTTy ssh client, you may want to install and configure the Vagrant PuTTY plugin, by following instructions here: https://github.com/nickryand/vagrant-multi-putty. You will also need to make a symbolic link to the executable, using the following command.

> mklink D:\Vagrant\embedded\bin\putty.exe "C:\Program Files (x86)\PuTTY\putty.exe"

(1) Use the AWS CLI/Security Token Service to generate temporary credentials for AWS

> aws sts get-session-token  

The credentials returned by this command will be valid for 1 hour.

(2) Install the Vagrant AWS plugin.

> vagrant plugin install vagrant-aws

(3) Add the “dummy” Box provided by the vagrant-aws project. This is a barebones Box compatible with AWS. We will flesh this out in the Vagrantfile to be created in the next step.

> vagrant box add dummy https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box

(4) Create a new directory to hold files for this Vagrant instance. I’m calling this vagrant-aws.

> mkdir vagrant-aws

(5) With your favorite text editor create a file called Vagrantfile inside this new directory. Edit this file vagrant-aws\Vagrantfile copying and pasting the following to the file (source).

Vagrant.configure("2") do |config|
  config.vm.box = "dummy"

  config.vm.provider :aws do |aws, override|
    aws.access_key_id = "YOUR KEY"
    aws.secret_access_key = "YOUR SECRET KEY"
    aws.session_token = "SESSION TOKEN"
    aws.keypair_name = "KEYPAIR NAME"

    aws.ami = "ami-7747d01e"

    override.ssh.username = "ubuntu"
    override.ssh.private_key_path = "PATH TO YOUR PRIVATE KEY"

(6) Now edit this text with the credentials returned by AWS STS (from above). You can use a different AMI (the current one given is for Ubuntu 12.04 x64) or change many other options, as described in the Vagrant AWS plugin documentation.

(7) Now you can bring the instance up with Vagrant, first making sure you are in the directory where you had created the Vagrantfile.

> cd vagrant-aws
> vagrant up

To work on your new Vagrant VM, use vagrant ssh or vagrant putty if you set up Putty using the plugin mentioned below. Once you’re finished, you can use vagrant destroy to completely blow away this instance, or some other vagrant command if you need to come back to the instance.

Next: The local VM

Friday, September 25, 2015

I'm back!

I'm back from my cross country bike ride!  On a completely different topic, my book with Packt Publishing, is finished and available for pre-order on Amazon, Barnes and Noble, and other fine book retailers:

Thursday, August 6, 2015

Out to ride -- back sometime in September

I'm on a cross country bike ride!

My progress as of 8/4/15:


Wednesday, February 25, 2015

cakephp controller save from scaffolded "join table" relationship, non-conventional primary keys

When I build interfaces on top of a pre-established database schema, I usually can't change schema properties.  That's a problem when working with a "convention over configuration" MVC Framework like cakephp.

After baking/scaffolding a CRUD interface based on a "join table" (HABTM) class, that issue came into focus, once again.  I have had run into some fairly easily resolvable issues involving some non conventional naming in the schema, such as primary key names.  I had primary key names from different tables that included the table prefix as well as irregular pluralization in the names.  Initially I wasn't able to get my dropdowns to populate from related tables, as described in the previous post.  Then I ran into an even stickier problem: the save method would fail on validation in the add method of the join table controller.

As it turned out, the form helper input method, though it would accept various names (probably cake-conventional) to refer to itself and to the primary key field, would not accept the ACTUAL name of the primary key field (which, while cake-unconventional, was actually set in both its own class model using $primaryKey and the join model using $foreignKey -- BTW, the same name was in use in the join table database, so this was really convention over configuration coming back to bite me).

To fix this I added the following to the controller to remap the cake-conventional failing field names to the actual (working!) field names:

I discovered, subsequently, that defining foreignKey (of parent) in child class models fixes some issues ... may even fix issue that I describe above.

Relates to: Cakephp SQL Error 1054 Unknown Column In The Field List (id column)

Tuesday, February 24, 2015

Auto-populate Bake/Scaffold Form in cakephp

To my knowledge, there's no way to "autopopulate" a form created through cakephp's bake/scaffold utility.  Populating of the forms are also not well documented.  Here's how you do it, with a related table via foreign key in the database.