Deploy LAMP with Vagrant and Fabric
Introduction
Lets automate every thing using python and ssh. Fabric is python library and command-line tool, which use SSH for application deployment in remote servers.Create basic Vagrant file
To start with fabric lets start our vagrant guest first. Please refer Vagrant Quickstart for more details on vagrant. Create directory ch2 and create basic Vagrantfile.Write first Fabric code
Firstly, create a fabfile.py and place it in the same directory where you have your Vagrantfile.Import fabric library and create function to for Guest Box SSH access details
from fabric.api import env, local, run
def vagrant():
# change from the default user to 'vagrant'
env.user = 'vagrant'
# connect to the port-forwarded ssh
env.hosts = ['127.0.0.1:2222']
# use vagrant ssh key
result = local('vagrant ssh-config | grep IdentityFile', capture=True)
env.key_filename = result.split()[1][1:-1]
Now add function to call any command which we want to run in Guest OS def uname():
run('uname -a')
So final fabfile.py file will be look like:-$ cat fabfile.py
from fabric.api import env, local, run
def vagrant():
# change from the default user to 'vagrant'
env.user = 'vagrant'
# connect to the port-forwarded ssh
env.hosts = ['127.0.0.1:2222']
# use vagrant ssh key
result = local('vagrant ssh-config | grep IdentityFile', capture=True)
env.key_filename = result.split()[1][1:-1]
def uname():
run('uname -a')
Let execute script and check result$ fab vagrant uname
[localhost] local: vagrant ssh-config | grep IdentityFile
[127.0.0.1:2222] Executing task 'uname'
[127.0.0.1:2222] run: uname -a
[127.0.0.1:2222] out: Linux localhost.localdomain 2.6.32-573.el6.x86_64 ...
[127.0.0.1:2222] out:
Done.
Disconnecting from 127.0.0.1:2222... done.
Here our first basic version of fabric script is ready to perform remote operations.Update Fabric code
In previous version of script we hard coded Guest OS IP address and ssh port. But depend upon Vagrantfile configuration, IP address can be different also. So let detect dynamically Guest OS IP.Now we need to import vagrant library for python, rename function 'vagrant' with 'start' and modify 'host' and 'key' settings
$ cat fabfile.py
import vagrant
from fabric.api import env, local, run
def start():
## Initialise
v = vagrant.Vagrant()
## make sure vagrant is up
v.up()
env.hosts = [v.user_hostname_port()]
env.key_filename = v.keyfile()
env.disable_known_hosts = True # useful for when the vagrant box ip changes.
# change from the default user to 'vagrant'
env.user = 'vagrant'
def uname():
run('uname -a')
When we execute modified script then result output will be same. Only difference is this time we didn't provided Guest OS IP$ fab start uname
Deploy LAMP stack with fabric
In LAMP stack we will install Apache, Mysql and PHP appliactions. Algorithm flow will be,- Install App,
- Allow in iptable,
- Start app,
- Enable to start at boot
- Configure APP (If require)
Mysql Server
def deploy_mysql():
## Install Mysql-Server
run('sudo yum -y install mysql-server')
## Add iptable rules
run('sudo iptables -I INPUT -p tcp --dport 3306 -m state --state NEW,ESTABLISHED -j ACCEPT')
run('sudo iptables -I OUTPUT -p tcp --sport 3306 -m state --state ESTABLISHED -j ACCEPT')
run('sudo service iptables save')
##Start Application
run('sudo /sbin/service mysqld start')
## Launch at reboot
run('sudo chkconfig mysqld on')
## Set Mysql password
mysqlPassword = 'fabricDeploy'
## Check condietion for for 2nd attempt of script, in case password already reset in first attempt
result = run("mysql -u root -p%s <<< 'show databases'" % mysqlPassword,warn_only=True)
if result.failed:
run("/usr/bin/mysqladmin -u root password '%s'" % mysqlPassword)
run("/usr/bin/mysqladmin -u root --password='%s' -h %s password '%s'" % (mysqlPassword,env.hostname,mysqlPassword))
Apache
def deploy_apache():
## Install Apache
run("sudo yum -y install httpd mod_ssl")
## Add IPtable rules
run("sudo iptables -I INPUT -p tcp --dport 80 -j ACCEPT")
run(" sudo service iptables save")
## Start Apache
run("sudo service httpd start")
## Launch at boot
run(" sudo /sbin/chkconfig httpd on")
PHP
def deploy_php():
## Insatll PHP
run("sudo yum -y install php php-devel php-mysql")
run("sudo service httpd restart")
So now our functions to deploy Mysql,Apache and PHP are ready. We can deploy calling functions one by one 3 times, Like$ fab start deploy_mysql
$ fab start deploy_apache
$ fab start deploy_php
Or since we have to deploy all together, so lets create another function to deploy all app togetherdef deploy_lamp_stack():
execute(deploy_mysql)
execute(deploy_apache)
execute(deploy_php)
Now lets deploy all together$ fab start deploy_lamp_stack
Create Box
Installing all application every time require network bandwidth. So to work offline and decrease deployment time, lets create local vagrant box## Create vagarnt box from curent guest os and name as 'centos-lamp-6.7'
$ vagrant package --output centos-lamp-6.7
## Check created box
$ ls
## Expected output 'Vagrantfile, fabfile.py and centos-lamp-6.7'
## Add box in local box repository
$ vagrant box add --name centos-lamp-6.7 ./centos-lamp-6.7
## Confirm Box added
$ vagrant box list
## Delete box file
$ rm centos-lamp-6.7
Run PHP Code
Since now our clean Guest OS is saved as box, Lets play with our current Guest OS.Create new function to write php script with phpinfo function inside apache DocumentRoot
def deploy_project():
##Deploy Dummy Project
run("echo '' | sudo tee /var/www/html/index.php")
Deploy demo php code$ fab start deploy_project
## Open Url http://127.0.0.1:8080/ in your local web browser
## Expecting Output of phpinfo function
Conclusion
So now our local LAMP box is ready. So next time for any new php project then edit "config.vm.box=centos-lamp-6.7" in VagrantfileIf we have local yum repository available in LAN then no need to create new box, Just deploy LAMP stack using fabric in default vm box.
Comments
Post a Comment