creating development environments with - droppdf3.droppdf.com/files/i2svq/packt-publishing... ·...

Post on 20-May-2020

20 Views

Category:

Documents

3 Downloads

Preview:

Click to see full reader

TRANSCRIPT

CreatingDevelopmentEnvironmentswithVagrantSecondEdition

TableofContents

CreatingDevelopmentEnvironmentswithVagrantSecondEdition

Credits

AbouttheAuthor

AbouttheReviewers

www.PacktPub.com

Supportfiles,eBooks,discountoffers,andmore

Whysubscribe?

FreeaccessforPacktaccountholders

Preface

Whatthisbookcovers

Whatyouneedforthisbook

Whothisbookisfor

Conventions

Readerfeedback

Customersupport

Downloadingtheexamplecode

Errata

Piracy

Questions

1.GettingStartedwithVagrant

IntroducingVagrant

RequirementsforVagrant

Gettingstarted

InstallingVirtualBox

InstallingVagrant

Summary

2.ManagingVagrantBoxesandProjects

CreatingourfirstVagrantproject

ManagingVagrant-controlledguestmachines

PoweringupaVagrant-controlledvirtualmachine

Suspendingavirtualmachine

Resumingavirtualmachine

Shuttingdownavirtualmachine

Startingfromscratch

UpdatingbasedonVagrantfilechanges

ConnectingtothevirtualmachineoverSSH

Managingintegrationbetweenhostandguestmachines

Portforwarding

Syncedfolders

Networking

Autorunningcommands

ManagingVagrantboxes

AddingVagrantboxes

ListingVagrantboxes

Checkingforupdates

RemovingVagrantboxes

RepackagingaVagrantbox

Updatingthecurrentenvironment’sbox

ToomanyVagrants!

Summary

3.ProvisioningwithPuppet

Provisioning

Puppet

CreatingmodulesandmanifestswithPuppet

Puppetclasses

DefaultPuppetmanifests

Resources

Resourcerequirements

Resourceexecutionordering

Thenotify,subscribe,andrefreshonlyparameters

Executingresourcesinstages

Installingsoftware

Updatingourpackagemanager

Installingthenginxpackage

Runningthenginxservice

Filemanagement

Copyingafile

Creatingasymlink

Creatingfolders

Creatingmultiplefoldersinonego

Cronmanagement

Runningcommands

Managingusersandgroups

Creatinggroups

Creatingusers

Updatingthesudoersfile

Creatingconfigurableclasses

Puppetmodules

UsingPuppettoprovisionservers

Summary

4.UsingAnsible

UnderstandingAnsible

InstallingAnsible

Creatinganinventory

CreatingAnsibleplaybooks

Modules–whatAnsiblecando

Installingsoftware

Updatingourpackagemanager

Installingthenginxpackage

Runningthenginxservice

Understandingfilemanagement

Copyingafile

Creatingasymlink

Creatingfolders

Managingcron

Runningcommands

Managingusersandgroups

Creatinggroups

Creatingusers

UsingAnsibleroles

UsingAnsibletoprovisionservers

Summary

5.UsingChef

KnowingaboutChef

CreatingcookbooksandrecipeswithChef

Resources–whatChefcando

Installingsoftware

Updatingourpackagemanager

Installingthenginxpackage

Runningthenginxservice

Understandingfilemanagement

Copyingafile

Creatingasymlink

Creatingfolders

Creatingmultiplefoldersinasingleprocesswithlooping

Managingcron

Runningcommands

Managingusersandgroups

Creatinggroups

Creatingusers

Updatingthesudoersfile

Knowingcommonresourcefunctionalities

UsingChefcookbooks

UsingCheftoprovisionservers

Summary

6.ProvisioningVagrantMachineswithPuppet,Ansible,andChef

ProvisioningwithinVagrant

ProvisioningwithPuppetonVagrant

UsingPuppetinstandalonemode

Puppetprovisioninginaction

UsingPuppetinclient/servermode

ProvisioningwithAnsibleonVagrant

ProvisioningwithChefonVagrant

UsingChef-solo

UsingChefinclient/servermode

ProvisioningwithSSH–arecap

Usingmultipleprovisionersonasingleproject

Overridingprovisioningviathecommandline

Summary

7.WorkingwithMultipleMachines

UsingmultiplemachineswithVagrant

Definingmultiplevirtualmachines

ConnectingtothemultiplevirtualmachinesoverSSH

Networkingthemultiplevirtualmachines

Provisioningthemachinesseparately

Destroyingamultimachineproject

Summary

8.CreatingYourOwnBox

Gettingstarted

PreparingtheVirtualBoxmachine

VirtualBoxGuestAdditions

Vagrantauthentication

Vagrantuserandadmingroup

Thesudoersfile

Insecurepublic/privatekeypair

Provisioners

InstallingPuppet

InstallingChef

CleaninguptheVM

Export

Summary

9.HashiCorpAtlas

Discoveringboxes

Installingnewboxes

Updatingexistingboxes

Checkingforoutdatedboxes

Distributingboxes

SharingandconnectingwithAtlas

LoggingVagrantintoVagrantCloud

SharingaVagrantvirtualmachineoverHTTP(S)

SharingandconnectingtoaVagrantvirtualmachine

Summary

A.ASampleLEMPStack

CreatingtheVagrantproject

CreatingthePuppetmanifests

InstallingNginx

InstallingPHP

InstallingtheMySQLmodule

Defaultmanifest

InstallingNginxandPHP

Hostnameconfiguration

E-mailsendingservices

MySQLconfiguration

Launchingthevirtualmachine

Summary

Index

CreatingDevelopmentEnvironmentswithVagrantSecondEdition

CreatingDevelopmentEnvironmentswithVagrantSecondEditionCopyright©2015PacktPublishing

Allrightsreserved.Nopartofthisbookmaybereproduced,storedinaretrievalsystem,ortransmittedinanyformorbyanymeans,withoutthepriorwrittenpermissionofthepublisher,exceptinthecaseofbriefquotationsembeddedincriticalarticlesorreviews.

Everyefforthasbeenmadeinthepreparationofthisbooktoensuretheaccuracyoftheinformationpresented.However,theinformationcontainedinthisbookissoldwithoutwarranty,eitherexpressorimplied.Neithertheauthor,norPacktPublishing,anditsdealersanddistributorswillbeheldliableforanydamagescausedorallegedtobecauseddirectlyorindirectlybythisbook.

PacktPublishinghasendeavoredtoprovidetrademarkinformationaboutallofthecompaniesandproductsmentionedinthisbookbytheappropriateuseofcapitals.However,PacktPublishingcannotguaranteetheaccuracyofthisinformation.

Firstpublished:August2013

Secondedition:March2015

Productionreference:1050315

PublishedbyPacktPublishingLtd.

LiveryPlace

35LiveryStreet

BirminghamB32PB,UK.

ISBN978-1-78439-702-9

www.packtpub.com

CreditsAuthor

MichaelPeacock

Reviewers

JonathanBardo

AnirudhBhatnagar

CommissioningEditor

UshaIyer

AcquisitionEditors

RichardBrookes-Bland

EllenBishop

ContentDevelopmentEditor

SriramNeelakantan

TechnicalEditor

MrunalM.Chavan

CopyEditor

RashmiSawant

ProjectCoordinator

AboliAmbardekar

Proofreaders

SimranBhogal

MariaGould

PaulHindle

Indexer

MonicaAjmeraMehta

ProductionCoordinator

ArvindkumarGupta

CoverWork

ArvindkumarGupta

AbouttheAuthorMichaelPeacockisanexperiencedsoftwaredeveloperandteamleadfromNewcastle,UK,withadegreeinsoftwareengineeringfromtheUniversityofDurham.

Afterspendinganumberofyearsrunninghisownwebagency,andsubsequently,workingdirectlyforanumberofsoftwarestart-ups,henowrunshisownsoftwaredevelopmentagency,workingonarangeofprojectsforanarrayofdifferentclients.

HeistheauthorofCreatingDevelopmentEnvironmentswithVagrant,PHP5SocialNetworking,PHP5E-CommerceDevelopment,Drupal7SocialNetworking,andSellingonlinewithDrupale-CommerceandBuildingWebsiteswithTYPO3,allbyPacktPublishing.TheotherpublicationsMichaelhasbeeninvolvedinincludeAdvancedAPISecurity,MobileWebDevelopment,JenkinsContinuousIntegrationCookbook,andDrupalforEducationandE-Learning;fortheseheactedasatechnicalreviewer.

Michaelhasalsopresentedatanumberofusergroupsandtechnicalconferences,includingPHPUKConference,DutchPHPConference,ConFoo,PHPNE,PHPNW,andCouldConnectSantaClara.

YoucanfollowMichaelonTwitter(@michaelpeacock),orfindoutmoreabouthimthroughhiswebsite(www.michaelpeacock.co.uk).

I’dliketothanktheteamatPacktPublishingfortheirhelpingettingthisrevisededitionofthebookpublished,andthetechnicalreviewersforensuringtechnicalaccuracyinthebook.

AbouttheReviewersJonathanBardoisaMontreal-basedwebdeveloperwithakeeninterestfornewtechnologiesandautomation.Hehasworkedformanylarge-scalewebsitesdealingwithmillionsofdailyvisitorsonvariousplatforms.Whenheisnotprogramming,helikestowatchagoodTVshowortravelsomewherehehasneverbeenbefore.Ifyouseehimridinghismotorcycleorskiingdownahill,justsayhi!Heisveryfriendly!

Jonathanrunshisownconsultingcompany,whichletshimmeetallsortsofinterestingclients,suchasFoxBroadcasting(USA),RogersDigitalMedia(Canada),andYellowPagesGroup(Canada).

Aspecialthankstoeveryonewhohasbeenapartofmyjourneysofar!Iwouldn’tbeherewithoutalltheincrediblepeopleIworkedwitheveryday.

AnirudhBhatnagarisaprincipalconsultantatXebia.Hestartedhiscareerasadeveloperworkinginproduct-basedcompaniessuchasAdobe.

AnirudhhasbeenworkingmostlywithJava-basedtechnologystacksthatuseSpring,Hibernate,XML,webservices,REST,CMS,SSO,ESB,andLiferay.

Duringthelastfewyears,AnirudhhasbeenadvocatingContinuousDeliveryandisinterestedintechnologiessuchasChef,Puppet,Jenkins,Vagrant,Docker,andmanymore.Heregularlycontributestothecommunityviablogs,articles,meetups,conferences,andopensourceprojects.

Moredetailsabouthimcanbefoundonhisblog(http://anirudhbhatnagar.com).

www.PacktPub.com

Supportfiles,eBooks,discountoffers,andmoreForsupportfilesanddownloadsrelatedtoyourbook,pleasevisitwww.PacktPub.com.

DidyouknowthatPacktofferseBookversionsofeverybookpublished,withPDFandePubfilesavailable?YoucanupgradetotheeBookversionatwww.PacktPub.comandasaprintbookcustomer,youareentitledtoadiscountontheeBookcopy.Getintouchwithusat<service@packtpub.com>formoredetails.

Atwww.PacktPub.com,youcanalsoreadacollectionoffreetechnicalarticles,signupforarangeoffreenewslettersandreceiveexclusivediscountsandoffersonPacktbooksandeBooks.

https://www2.packtpub.com/books/subscription/packtlib

DoyouneedinstantsolutionstoyourITquestions?PacktLibisPackt’sonlinedigitalbooklibrary.Here,youcansearch,access,andreadPackt’sentirelibraryofbooks.

Whysubscribe?FullysearchableacrosseverybookpublishedbyPacktCopyandpaste,print,andbookmarkcontentOndemandandaccessibleviaawebbrowser

FreeaccessforPacktaccountholdersIfyouhaveanaccountwithPacktatwww.PacktPub.com,youcanusethistoaccessPacktLibtodayandview9entirelyfreebooks.Simplyuseyourlogincredentialsforimmediateaccess.

PrefaceWeb-basedsoftwareprojectsareincreasinglycomplicated,witharangeofdifferentdependencies,requirements,andinterlinkingcomponents.Swappingbetweenprojects,whichrequiredifferentversionsofthesamesoftware,becomestroublesome.Gettingteammembersupandrunningonnewprojectsbecomestime-consuming.

Vagrantisapowerfultoolusedtocreate,manage,andworkwithvirtualizeddevelopmentenvironmentsforyourprojects.Bycreatingavirtualenvironmentforeachproject,theirdependenciesandrequirementsareisolated,theyalsodon’tinterferewiththesoftwareinstalledonyourownmachinesuchasWAMPorMAMP.Colleaguescanbeupandrunningonanewprojectinminuteswithasinglecommand.WithVagrant,wecanwipetheslatecleanifwebreakourenvironmentandbebackupandrunninginnotime.

WhatthisbookcoversChapter1,GettingStartedwithVagrant,introducestheconceptofvirtualization,itsimportanceintheroleofthedevelopmentenvironment,andwalksyouthroughtheVagrantinstallationprocess.

Chapter2,ManagingVagrantBoxesandProjects,walksyouthroughcreatingVagrantprojects,exploringandconfiguringtheVagrantfile,andworkingwithbaseboxes.

Chapter3,ProvisioningwithPuppet,exploresPuppet,theprovisioningtool,andhowtocreatePuppetmanifeststoprovisionaserver.

Chapter4,UsingAnsible,exploresAnsible,theprovisioningtool,andhowtocreateAnsibleplaybookstoprovisionaserver.

Chapter5,UsingChef,exploresChef,theprovisioningtool,andhowtocreateChefrecipestoprovisionaserver.

Chapter6,ProvisioningVagrantMachineswithPuppet,Ansible,andChef,discusseshowtousePuppet,Ansible,andChefwithinthecontextofVagranttoprovisiondevelopmentenvironments.

Chapter7,WorkingwithMultipleMachines,exploresusingVagranttocreateandmanageprojectsthatusemultiplevirtualmachines,whichcommunicatewitheachother.

Chapter8,CreatingYourOwnBox,discussestheprocessofcreatingyourownbaseboxforusewithinaVagrantproject.

Chapter9,HashiCorpAtlas,walksyouthroughusingVagrantSharetoshareSSHandHTTP(S)accesstoaVagrant-managedmachine,andhowtousetheservicesprovidedthroughtheVagrantCloud.

Appendix,ASampleLEMPStack,walksyouthroughtheprocessofcreatingaLEMPserverwithinanewVagrantproject.

WhatyouneedforthisbookYouwillneedaWindows,OSX,orLinuxcomputerwithVagrantandOracleVirtualBoxinstalled,althoughtheinstallationprocessforthesewillbediscussedinChapter1,GettingStartedwithVagrant.

WhothisbookisforThisbookisforsoftwaredevelopers,developmentmanagers,andtechnicalteamleaderswhowanttohaveamoreefficient,robust,andflexibledevelopmentenvironmentfortheirprojectsandfortheirteam.

ConventionsInthisbook,youwillfindanumberofstylesoftextthatdistinguishbetweendifferentkindsofinformation.Herearesomeexamplesofthesestyles,andanexplanationoftheirmeaning.

Codewordsintext,databasetablenames,foldernames,filenames,fileextensions,pathnames,dummyURLs,userinput,andTwitterhandlesareshownasfollows:“AfterinstallingVagrant,weranthevagrantcommandtocheckwhetheritwasinstalledcorrectly.”

Ablockofcodeissetasfollows:

VAGRANTFILE_API_VERSION="2"

Vagrant.configure(VAGRANTFILE_API_VERSION)do|config|

config.vm.box="base"

end

Whenwewishtodrawyourattentiontoaparticularpartofacodeblock,therelevantlinesoritemsaresetinbold:

---

-hosts:default

tasks:

-name:updateaptcache

apt:update_cache=yes

-name:ensurenginxisinstalled

apt:pkg=nginxstate=present

-name:writethenginxconfigfile

template:src=nginx-default-site.confdest=/etc/nginx/sites-

available/default.conf

notify:

-restartnginx

-name:ensurenginxisrunning

service:name=nginxstate=started

handlers:

-name:restartnginx

service:name=nginxstate=restarted

Anycommand-lineinputoroutputiswrittenasfollows:

ansible-playbookour-playbook.yml-iour-inventory-file

Newtermsandimportantwordsareshowninbold.Wordsthatyouseeonthescreen,inmenusordialogboxesforexample,appearinthetextlikethis:“Again,onOSX,thefirststepistodouble-clickontheVagrant.pkgicon.”

NoteWarningsorimportantnotesappearinaboxlikethis.

TipTipsandtricksappearlikethis.

ReaderfeedbackFeedbackfromourreadersisalwayswelcome.Letusknowwhatyouthinkaboutthisbook—whatyoulikedormayhavedisliked.Readerfeedbackisimportantforustodeveloptitlesthatyoureallygetthemostoutof.

Tosendusgeneralfeedback,simplysendane-mailto<feedback@packtpub.com>,andmentionthebooktitleviathesubjectofyourmessage.

Ifthereisatopicthatyouhaveexpertiseinandyouareinterestedineitherwritingorcontributingtoabook,seeourauthorguideonwww.packtpub.com/authors.

CustomersupportNowthatyouaretheproudownerofaPacktbook,wehaveanumberofthingstohelpyoutogetthemostfromyourpurchase.

DownloadingtheexamplecodeYoucandownloadtheexamplecodefilesforallPacktbooksyouhavepurchasedfromyouraccountathttp://www.packtpub.com.Ifyoupurchasedthisbookelsewhere,youcanvisithttp://www.packtpub.com/supportandregistertohavethefilese-maileddirectlytoyou.

ErrataAlthoughwehavetakeneverycaretoensuretheaccuracyofourcontent,mistakesdohappen.Ifyoufindamistakeinoneofourbooks—maybeamistakeinthetextorthecode—wewouldbegratefulifyouwouldreportthistous.Bydoingso,youcansaveotherreadersfromfrustrationandhelpusimprovesubsequentversionsofthisbook.Ifyoufindanyerrata,pleasereportthembyvisitinghttp://www.packtpub.com/submit-errata,selectingyourbook,clickingontheerratasubmissionformlink,andenteringthedetailsofyourerrata.Onceyourerrataareverified,yoursubmissionwillbeacceptedandtheerratawillbeuploadedonourwebsite,oraddedtoanylistofexistingerrata,undertheErratasectionofthattitle.Anyexistingerratacanbeviewedbyselectingyourtitlefromhttp://www.packtpub.com/support.

PiracyPiracyofcopyrightmaterialontheInternetisanongoingproblemacrossallmedia.AtPackt,wetaketheprotectionofourcopyrightandlicensesveryseriously.Ifyoucomeacrossanyillegalcopiesofourworks,inanyform,ontheInternet,pleaseprovideuswiththelocationaddressorwebsitenameimmediatelysothatwecanpursuearemedy.

Pleasecontactusat<copyright@packtpub.com>withalinktothesuspectedpiratedmaterial.

Weappreciateyourhelpinprotectingourauthors,andourabilitytobringyouvaluablecontent.

QuestionsYoucancontactusat<questions@packtpub.com>ifyouarehavingaproblemwithanyaspectofthebook,andwewilldoourbesttoaddressit.

Chapter1.GettingStartedwithVagrantDevelopingmodernweb-basedapplicationscanbecomplicated!

Thetechnologybehindourprojectsisbecomingmoreadvancedanddiverse.Whereonceprojectsranwithsimplyawebserver,adatabase,andasetprogramminglanguage,nowweusetoolsbuiltinavarietyofdifferentlanguages.Weusecomponentsanddependenciesthatneedtobeinstalled,andtheirmanagedversions,andoftenprojectsneedtorunacrossmultiplemachines.

Differentprojectshavetheirownrequirementsanddependencies,whichareoftenincompatiblewithoneanother.AlegacyprojectmightrequireaspecificversionofPHPorspecificversionsofextensionsforApache,whereasanotherprojectmightrequireanewerversionofPHPandrunningonNginx.Projectswitchinginthisscenarioisnoteasy.

Often,weneedtoworkwithteamsofpeople,someofwhichmightbeusingtheirownequipment,workingremotely,andcontractors.Thisrequiresyoutoensurethateveryonerunsthesamedevelopmentenvironment,regardlessoftheirownsystemanditsconfiguration,theinfrastructurechangesforprojectsaretrackedandmadeavailabletotheteam,andtheprojectsetupisfastfornewteammembers.

Combiningthesethreefactorsandsettinguptraditionaldevelopmentenvironmentsisbecomingmoredifficult,lessrelevant,andlesshelpfulfordevelopers.

Asprojectsgetmorecomplicated,it’salsoeasyforauxiliaryconfigurationstobeforgottenabout.Backgroundworkers,messagequeues,cronjobs,andmultiserverconfigurationsneedtobemanaged,distributedtotheentireteam,andthenwhenthetimecomes,appliedtotheprojectwhenitgetsdeployedintoaproductionenvironment.

Virtualizeddevelopmentenvironmentscanhelpwiththis.Insteadofhavingtobattleconfigurationswhenworkingonotherprojects,eachprojectcansimplyhaveitsownvirtualizedenvironment.Itcanhaveitsowndedicatedwebserver,databaseserver,andtheversionsoftheprogramminglanguageandotherdependenciesitneeds.Becauseitisvirtualized,itdoesn’timpactonotherprojects;justshutitdownandbootuptheenvironmentfortheotherproject.

Withavirtualizedenvironment,thedevelopmentenvironmentscanalsomimictheproductionenvironment.Youdon’tneedtoworryaboutwhethersomethingwillworkwhenitgetsdeployed,ifitisbeingdevelopedonamachinewiththeexactsamesoftwareconfiguration.EvenifyoudeployonaLinuxmachinebutdeveloponWindows,yourvirtualizedenvironmentcanbeLinux,runningthesamedistributionasyourproductionenvironment.

Whileavirtualizedenvironmentmakesdifferentprojectsandtheirdependencieseasiertomanageandseparate,theyarenottheeasiestofthingstoconfigureandmanage.Theystillneedtobeconfiguredtoworkwiththeprojectinquestion,whichofteninvolvessomelevelofsystemadministrationskills,andweneedtoconnecttotheseenvironmentsandworkwiththem.Theyalso,bydesign,arenotveryportable.Youneedtoexportalarge

imageofthevirtualizedenvironmentandsharethatwithyourcolleagues,andkeepingthatimageuptodateasprojectsevolvecanbecumbersome.Thankfully,thereisatoolthatcanmanagethesevirtualizedenvironmentsforus,andprovideasimpleinterfacetoconfigurethem;aninterfacethatinvolvesstoringconfigurationsinsimpleplaintextfiles,whichareeasytosharewithcolleagues,keepingeveryoneuptodateastheprojectchanges.ThistoolisVagrant.

IntroducingVagrantVagrant(http://www.vagrantup.com/)isapowerfuldevelopmenttoolthatletsyoumanageandsupportthevirtualizationofyourdevelopmentenvironment.Insteadofrunningallyourprojectslocallyonyourowncomputer,havingtojugglethedifferentrequirementsanddependenciesofeachproject,Vagrantletsyouruneachprojectinitsowndedicatedvirtualenvironment.

Vagrantprovidesacommand-lineinterfaceandacommonconfigurationlanguagethatallowsyoutoeasilydefineandcontrolvirtualmachinesthatrunonyourownsystems,butwhichtightlyintegrate,andalsoallowsyoutodefinehowyourownmachineandthevirtualmachineinteract.Thiscaninvolvesyncingfolderssuchthattheprojectcode,whichyoueditusingtheIDEonyourcomputer,issyncedsothatitrunsontheVagrantdevelopmentenvironment.

Vagrantusesproviderstointegratewiththethird-partyvirtualizationsoftware,whichprovidesthevirtualizedmachinesforourdevelopmentenvironment.ThedefaultproviderisforOracleVirtualBox;however,therearecommercialproviderstoworkwithVMwareFusionandalsopluginsforVagranttoworkwithAmazonWebServices.Theentireconfigurationisstoredinsimpleplaintextfiles.TheVagrantconfiguration(Vagrantfile),andtheconfigurationthatdefineshowourVagrantmachinesareconfigured(typicallyShellscripts,Ansibleplaybooks,ChefcookbooksorPuppetmanifeststhatVagranthasbuilt-insupportfor,asprovisioners)aresimplywrittenintextfiles.Thismeansthatwecaneasilysharetheconfigurationsandprojectswithcolleagues,usingversioncontrolsystemssuchasGit.

WhenusingVagrant,thenexttimeyouneedtogobacktoapreviousproject,youdon’tneedtoworryaboutanypotentialconflictswithchangesmadetoyourdevelopmentenvironment(forexample,ifyouhaveupgradedPHP,MySQL,orApacheonyourlocalenvironmentorwithintheVagrantenvironmentforanotherproject),asthedevelopmentenvironmentfortheseprojectsarecompletelyself-contained.Ifyoubringanewmemberintotheteam,theycanbeupandrunningwithyourprojectsinminutes.Vagrant,alongwithitsintegrationwithprovisioners,willtakecareofallthesoftwareandservicesneededtoruntheprojectontheirmachine.IfyouhaveoneprojectthatusesonewebserversuchasApache,andanotheronethatusesNginx,Vagrantletsyouruntheseprojectsindependently.Ifyourproject’sproductionenvironmentinvolvesmultipleservers(perhapsonefortheWebandoneforthedatabase),Vagrantletsyouemulatethatwithseparatevirtualserversonyourmachine.

WithVagrant:

YourdevelopmentenvironmentcanmimictheproductionenvironmentIntegratedprovisioningtoolssuchasPuppet,Chef,andAnsibleallowyoutostoretheconfigurationinastandardformat,whichcanalsobeusedtoupdateproductionenvironmentsEachprojectisseparateinitsownvirtualizedenvironment,soissuesasaresultofconfigurationandversiondifferencesfordependenciesondifferentprojectsarea

thingofthepastNewteammemberscanbeonboardedtonewprojectsaseasyasgitclone&&vagrantup

“Itworksonmymachine”asaresponsetobugsisathingofthepastTheheadacheoflinkingcodethatyouwriteonyourownmachinetoyourvirtualizeddevelopmentenvironmentistakencareofthroughsyncedfoldersTheenvironmentcanactasifitwasyourlocalmachineandmapthewebserverport(80)ofyourdevelopmentmachinetoyourdevelopmentenvironmentifyouwish,oryoucanaccessitasyouwouldanothermachineonyournetworkYoucanletcolleaguesviewyourowndevelopmentenvironmentaswellaseasilysharethedevelopmentenvironmentYoucanshareaccesstoyourowndevelopmentenvironmentovertheInternettodemoyourprojectortogetsupportfromacolleagueYourlocalWAMPorMAMPinstallationswillbegatheringdust!

Inthischapter,wewillcoverthefollowingtopics:

DiscusstherequirementsandprerequisitesforVagrantInstallOracleVirtualBoxInstallVagrantVerifythatVagrantwassuccessfullyinstalled

OncewehaveVagrantanditsprerequisitesonourmachine,wecanthentakealookatusingitforourfirstproject.

RequirementsforVagrantVagrantcanbeinstalledonLinux,Windows,andMacOSX,andalthoughitusesRuby,thepackageincludesanembeddedRubyinterpreter.TheonlyotherrequirementisavirtualizationprovidersuchasOracleVirtualBoxorVMwareFusion.TheOracleVirtualBoxproviderisavailableforfreeandisthedefaultproviderforVagrant.So,wewilluseandinstallVirtualBoxinordertouseVagrantduringthecourseofthisbook.Otherprovidersareavailable,includingoneforVMwareFusionorWorkstation,whichisavailableasacommercialadd-on(http://www.vagrantup.com/vmware).

GettingstartedNowthatweknowwhatsoftwareweneedinordertogetVagrantrunningonourmachine,let’sstartinstallingVirtualBoxandVagrantitself.

InstallingVirtualBoxVirtualBox(https://www.virtualbox.org/)isanopensourcetoolsponsoredbyOraclethatletsyoucreate,manage,andusevirtualmachinesonyourowncomputer.

VirtualBoxisagraphicalprogramwithacommand-lineinterfacethatletsyouvisuallycreatevirtualmachines,allocateresources,loadexternalmediasuchasoperatingsystemCDs,andviewthescreenofthevirtualmachine.Vagrantwrapsontopofthisandprovidesanintuitivecommand-lineinterfacealongwiththeintegrationofadditionaltools(includingintegrationswithprovisionersandalsoHashiCorpAtlas(formerly,VagrantCloud)thatallowyoutofindanddistributebaseserverimagesandshareaccesstoyourVagrantenvironments),sothatwedon’tneedtoworryabouthowVirtualBoxworksorwhattodowithit;Vagranttakescareofthisforus.

ThefirststageistodownloadtheinstallerfromtheVirtualBoxdownloadspage(https://www.virtualbox.org/wiki/Downloads),asshowninthefollowingscreenshot.Weneedtoselecttheoptionthatisappropriateforourcomputer(OSX,Windows,Linux,orSolaris):

NoteAtthetimeofwritingthis,Vagrantsupportsversions4.0.xthrough4.3.xofVirtualBox;earlierversionsarenotsupported.

Oncedownloaded,let’sopenitandruntheinstaller.OnOSX,thisinvolvesclickingontheVirtualBox.pkgicon,asshowninthefollowingscreenshot.OnWindows,simplyopeningtheinstalleropenstheinstallationwizard.OnLinux,therearepackagesavailablethatcanbeinstalledthroughyourchosenpackagemanager,seehttps://www.virtualbox.org/wiki/Linux_Downloadsformoreinformation.

Beforetheinstallerruns,itfirstcheckswhetherthecomputeriscapableofhavingVirtualBoxinstalled.WeneedtoclickonContinuetobegintheinstallationprocess,asshowninthefollowingscreenshot.WhilethisprocesswillvaryfromOSXtoWindowstoLinux,theprocessisverysimilaracrossallplatforms.TherearefullydetailedinstallationinstructionsforallplatformsontheVirtualBoxwebsite(https://www.virtualbox.org/manual/ch02.html).

Thefirststepintheprocessprovidesuswithanintroductiontotheinstallationprocessandremindsusastowhatweareactuallyinstalling:

Next,theinstallerinformsusastohowmuchspaceitwilluseonourcomputer,andprovidesuswiththeoptiontocustomizetheinstallationifwewanttoChangeInstallLocation…,andinstallthesoftwareinanotherlocation(perhapsanotherdiskdriveifourdiskgetsfull).

Let’sleavethedefaultinstalllocationasitis,andclickontheInstallbuttontoinstallVirtualBoxonourcomputer:

Afterbeingpromptedtoprovideadministrativeprivileges,theinstallerthenautomaticallyinstallsVirtualBoxforus:

Oncetheinstallationhasfinished,weareshownaconfirmationscreenwiththeoptionofclickingonClosetoclosetheinstaller:

NowwehavesuccessfullyinstalledVirtualBox!

InstallingVagrantNowthatwehavetheprerequisitesinstalledonourcomputer,wecanactuallyinstallVagrantitself.ThisprocessissimilartothatofinstallingVirtualBox.First,let’sdownloadtherelevantinstallerfromtheVagrantdownloadpage(http://www.vagrantup.com/downloads.html):

Let’sopentheinstallerandstarttheprocess.Again,onOSX,thefirststepistodouble-clickontheVagrant.pkgicon:

Wenowneedtofollowtheinstallationstepsthatareprovided;thisisverysimilartotheearlierstepsforVirtualBox,andformostofthesoftwarepackagesingeneral.Youmightbepromptedtoprovideyourcomputer’sadministrativeuserprivilegesforthesoftwaretobeinstalled.

Let’sverifythatVagranthasbeensuccessfullyinstalled.Wecandothisbyopeningaterminalwindow(cmdonWindows)andrunningthevagrantcommand:

TheprecedingscreenshotshowsthatwehavesuccessfullyinstalledVagrant,andweareabletorunit.

Runningthevagrantcommandonitsownlistsarangeofcommonsubcommands,whichwecanrunwithinVagrant,aswellasinstructionsonhowtoaccessthehelpinformationonVagrantandanyofitssubcommands.WecanaccessthehelpinformationonVagrantanditssubcommandsbyaddingthehflag,-h,totheendofthecommandwhenwerunit.

SummaryInthischapter,wediscussedthebenefitsofusingvirtualizeddevelopmentenvironmentsandspecifically,Vagrant.WetheninstalledOracleVirtualBox,whichisthevirtualizationproviderVagrantusesbydefault,andweinstalledVagrant.AfterinstallingVagrant,weranthevagrantcommandtocheckwhetheritwasinstalledcorrectly.

NowthatwehaveVagrantandaproviderinstalled,wecannowmoveontousingVagranttosetupandmanagesomeofourdevelopmentprojectsinavirtualdevelopmentenvironment.Inthenextchapter,wewillcreateourfirstproject,learnabouttheconfigurationfile,andmanageourVagrantcontrolledmachines.

Chapter2.ManagingVagrantBoxesandProjectsInthischapter,wewilllearnthebasicsofusingVagrant.Wewilltakealookatinitializingprojects,importingbaseboxestobeusedasouroperatingsystem,andcontrollingthevirtualmachinebypoweringonandoff,suspendingandresuming,andconnectingtothebox.Finally,wewillalsolearnhowtoconfiguresomeofthekeyintegrationpointsbetweenourownmachineandourVagrant-controlledvirtualmachine,including:

PortforwardingFoldermappingNetworking

CreatingourfirstVagrantprojectNowthatwehaveVagrantinstalledonourmachine,let’stakealookatcreatingVagrantprojects.AnyfoldercanactasaVagrantproject;itonlyrequiresaspecialconfigurationfile,calledtheVagrantfile,withinit.Vagrantusesthisfiletosetupthevirtualmachines(guests)andmanagetheirintegrationwithourcomputer(orhostmachine).

VagranthasacommandtocreateaVagrantfilewithinthecurrentdirectoryyouarein,withinyourcomputer’sterminal:thevagrantinitcommand.Tocreateanewproject,let’screateanewfolderanywhereinoursystem–ideally,somewhereeasilyreachable,thenweneedtogointothisfolder,andruntheinitcommand:

VagrantwillthencreateaVagrantfilewithinthatfolder,andshowusaconfirmationmessage:

IfwetakealookatthecontentsofthisVagrantfilefilethatwascreated,wewillseearangeofconfigurationoptions.Mostoftheoptionsarecommentedout(astheyareprefixedwitha#character)togiveusanideaofhowwecanconfiguretheproject.

Thereareonlyfourlinesofactualusableconfigurationinthefile,asshownhere:

VAGRANTFILE_API_VERSION="2"

Vagrant.configure(VAGRANTFILE_API_VERSION)do|config|

config.vm.box="base"

end

TipDownloadingtheexamplecode

Youcandownloadtheexamplecodefilesfromyouraccountathttp://www.packtpub.comforallthePacktPublishingbooksyouhavepurchased.Ifyoupurchasedthisbookelsewhere,youcanvisithttp://www.packtpub.com/supportandregistertohavethefilese-maileddirectlytoyou.

DifferentversionsofVagrantusedifferentstructuresandinstructionswithintheirVagrantfilefiles.TomakeVagrantbackwardcompatible,thevarioussettingsarewrappedinablockofcodethatcontainstheversionoftheconfigurationtobeused.ConfigurationVersion2iscompatiblewithVagrantVersion1.1uptoVersion2.0.x(whenreleased).

Withinhere,wehaveasingleoption—thetypeofVagrantboxtouse.AVagrantboxisanimageofanoperatingsystemthatisconfiguredtoworkwithVagrant.

WecangenerateaVagrantfilewithouttheillustrativecommentsbyprovidingtheminimaloption(-mor--minimal,forexample,vagrantinit--minimal).

InordertobootourVagrantmachine,werunthevagrantupcommand:

AsVagrantdoesn’tknowwhattheboxbaseis,ourprojectisunabletoboot.WhileVagrantprojectshavetheirconfigurationstoredwithintheirprojectsfolder,boxesareinstalledgloballyonyourcomputerandcanbesharedacrossprojects.IfVagrantdoesn’thaveaboxinstalledwiththatname,itwilleithertrytodownloaditfromtheURLprovidedintheVagrantfile(ifthereisoneprovided)oritwilllookfortherelevantboxinHashiCorpAtlas(formerlyVagrantCloud).HashiCorp,thecompanybehindVagrant,providesofficialboxesforthelatestLongTermSupportversionofUbuntu(thisboxishostedonanddistributedthroughVagrantCloud;wewilldiscussthisinmoredetailinChapter9,HashiCorpAtlas).Tousethisbox,wesimplypassthenameoftheboxtotheinitcommand(orupdatetheVagrantfile).AswealreadyhaveaVagrantfileinplaceforourproject,weneedtousetheforceoptiontooverridetheexistingfile(-for--force):

vagrantinit--forcehashicorp/precise64

NowifwetrytorunourVagrantproject,Vagrantwilllookforthebox,andthistime,itwilldownloadtheprecise64boxfromVagrantCloud,foruseinourproject:

Typically,boxesareminimalinstallationsofoperatingsystemsthatcontainonlywhatisrequiredfortheoperatingsystemtofunction,toolstointegratewithVagrant,andaminimalamountofothertools.ThisprovidesgreaterflexibilitywhenitcomestousingVagranttomanageprojects,aswecandecideexactlywhatsoftwareweneedtorunonourvirtualmachineforourprojecttofunction,withouthavingtoworryabouttheconflictingversionsofthesaidsoftware.Someexistingboxesmayhavemoresoftwareinstalled,andofcourse,wemaywanttopackageaboxthatcontainssomeofthekeysoftwareourprojectsneed(particularly,usefulasabackupforuserswithunreliableInternetconnections).

NoteWhileweareusingcommandstoinitializeourVagrantprojectsinthischapter,thesearesimplyquickwaystocreateaVagrantfilefilewithsomeprepopulatedvalues.AVagrantfilefileistheconfigurationfilethatdefineshowVagrantshouldusetheproject(suchasoperatingsystemtobeused,virtualmachinestobootup,syncedfolders,forwardedports,andsoon).Wecan,ofcourse,createthisfileourselveswithinthefolderwewishtouseasourproject.

ManagingVagrant-controlledguestmachinesThevirtualmachines,whichVagrantcontrolsforus,stillneedtobemanagedandworkedwith.WehaveseenthatwecanstartaVagrantprojectwithvagrantup.Let’slearnmoreaboutthiscommand,andseehowtoperformotheroperationsonournewvirtualmachine.

PoweringupaVagrant-controlledvirtualmachineAswehavejustseen,wecanpowerupavirtualmachineusingthevagrantupcommand.Withthiscommand,VagrantwillfirstcheckwhetheraVagrantenvironmenthasalreadybeensetup.Ifapreviouslysuspendedenvironmentisfound,itwillresumethatenvironment.

Iftheenvironmentwasnotpreviouslysuspended,Vagrantthencheckswhetherthebaseboxhasalreadybeendownloadedontothemachine.Ifithasn’t,itwilldownloadit,asitdidforuswhenwebootedourprojectwiththeprecise64boxforthefirsttime.

Vagrantwillthenperformthefollowingactions:

1. Copythebasebox(remember,baseboxesaremanagedgloballyonourhostcomputer,soittakesacopyforeachmachinemanagedbyit).

2. Createanewvirtualmachinewiththerelevantprovider(thedefaultbeingVirtualBox).

3. Forwardanyconfiguredports;bydefault,itwillforwardport22(theSSHport)onthevirtualmachinetoport2222onthehost.ThiswillallowustoconnecttothevirtualmachineoverSSH.

4. Boot(powerup)thevirtualmachine.5. Configureandenablenetworking,sothatwecancommunicatewiththevirtual

machine.6. Mapsharedfoldersbetweenthehostandtheguest(bydefault,itwillmapthefolder

thatcontainstheVagrantprojectto/vagrantontheguestmachine).7. RunanyprovisioningtoolsthataresetupsuchasPuppet,Chef,orSSHcommands

orscripts.

TheactionsperformedbyVagrantwilllooksomethinglikethis:

SuspendingavirtualmachineWecansavethecurrentstateofthevirtualmachinetothedisk(suspendit)sothatwecanresumeitlater.Ifwerunvagrantsuspend,itwillsuspendtheVMandstopitfromconsumingourmachine’sresources,exceptforthediskspaceitwilloccupy,readyforustouseagainlater:

ResumingavirtualmachineInordertouseapreviouslysuspendedvirtualmachine,wesimplyrunvagrantresume:

ShuttingdownavirtualmachineWecanshutdownarunningvirtualmachineusingthevagranthaltcommand.ThisinstructstheVMtostopallrunningprocessesandshutdown.Touseitagain,weneedtorunvagrantup,whichwillpoweronthemachine;provisioningistypicallyonlyranonthefirstvagrantupcommand.Toensurethatprovisioningrunswhenwebootupasavedmachinesubsequently,wecanusethe--provisionflag.

StartingfromscratchSometimes,thingsgowrong.It’snotinconceivablethatwemightmakesomechangestoourvirtualmachine,andfindoutthatitnolongerworks.Thankfully,sincewehaveabasebox,configurationfile,andprovisioningfiles,whichareallstoredseparately,wecaninstructVagranttodestroyourvirtualmachine,andthencreateitagain,usingtheconfigurationstosetitup.Thisisdoneviathedestroycommand,andthenweneedtousetheupcommandtostartitagain:

vagrantdestroy

vagrantup

Ofcourse,ifweupdateourVagrantfile,provisioningmanifests,orapplicationcodethatcanalsobreakthings;soitisimportantthatweuseaversioncontrolsystemtoproperlymanageourproject’scodeandconfiguration,sothatwecanundothechangestheretoo;Vagrantcanonlydosomuchtohelpus!

UpdatingbasedonVagrantfilechangesIfwemakechangestoourVagrantfile,thesechangeswon’tapplyuntilwenextshutdownandpoweronourvirtualmachine.Asthisisn’tveryconvenient,thereisahandyreloadcommandthatwillshutdownthemachine,reloaditsconfigurationbasedontheVagrantfileasitcurrentlyis,andbootitupagain:

vagrantreload

Runningthiscommandyieldsthefollowingresult:

ConnectingtothevirtualmachineoverSSHIfwerunthevagrantsshcommand,VagrantwillthenconnecttothevirtualmachineoverSSH.Alternatively,wecanSSHtolocalhostwithport2222,andthiswilltunnelintothevirtualmachine,usingthedefaultforwardedSSHport.

IfwerunVagrantonaWindowsmachine,wewon’thaveabuilt-inSSHclient.WecanuseaclientsuchasPuTTYtoconnecttoVagrant.PuTTYcanbedownloadedfromhttp://www.chiark.greenend.org.uk/~sgtatham/putty/.MoreinformationonhowtoconfigurePuTTYtoworkwithVagrantisavailableontheVagrantwebsite(http://docs-v1.vagrantup.com/v1/docs/getting-started/ssh.html).

ManagingintegrationbetweenhostandguestmachinesWithoutanyformofintegrationbetweenthehostmachineandtheguest,wewouldsimplyhaveabarebonesvirtualserverrunningontopofourownoperatingsystem,whichisnotparticularlyuseful.Weneedourownmachinetobecapableofintegratingtightlywiththeguest(virtualmachine).

PortforwardingAlthoughthevirtualmachineisrunningonourownmachine,becauseofvirtualization,itactsandbehaveslikeacompletelydifferentmachine.Sometimes,thisiswhatwewant;however,theremightbetimeswewanttohavethevirtualmachinebehavealmostasanextensionofourownmachine.Onewaytodothisisthroughportforwarding,wherewecantunnelaportfromthevirtualmachinetoaportonthehostmachine.If,forexample,wehaveawebserverrunningonourownmachine,weobviouslydon’twanttomapthewebserverportfromVagrantontothesameport;otherwise,therewouldbeaconflict.Instead,wecanmapittoanotherport.Ifwemapthewebserverportonthevirtualmachinetoport8888onthehost,thennavigatingtohttp://localhost:8888onourownmachinewouldshowusthewebservicewerunontheguest,despitethefactthatthelocalhostreferstoourhostmachine.

TheportforwardingisdonevialinesintheVagrantfilefile;wesimplyprovidetheguestandhostportswewishtomap:

config.vm.network:forwarded_port,guest:80,host:8888

IfwehaveotherVagrantmanagedvirtualmachinesonourcomputer,whichwewishtorunsimultaneously,wecanenableauto_correctonspecificports.Thisway,ifaconflictisfound(forexample,twovirtualmachinestryingtomaptothesameport),onevirtualmachinewilltryadifferentportinstead:

,auto_correct:true

Portsbelowacertainrangeneedelevatedorrootprivilegesonthehostmachine,soyoumaybeaskedforyouradministrativepassword.

SyncedfoldersSyncedfoldersallowustoshareafolderbetweenthehostandtheguest.Bydefault,VagrantsharesthefolderthatcontainstheVagrantproject/vagrantonthevirtualmachine.WecanusethefollowingcommandinourVagrantfiletosyncmorefoldersifwewish:

config.vm.synced_folder"/Users/michael/assets/""/var/www/assets"

ThefirstparameteristhepathtothefolderonourmachineandthesecondisthemountpointontheVM.Ifweusearelativepathonourmachine,itwouldberelativetotheprojectfolder.

Ifwewanttooverridethedefaultsyncedfolder,wecandothistoo:

config.vm.synced_folder".","/var/another/folder"

TheNetworkFileSystem(NFS)cangiveusbetterperformancewithsyncedfoldersthanthedefaultsettings.Thiswon’thaveanyeffectonWindowshosts,andonLinux/OSX,hostswillrequirerootprivileges.WecanenableNFSonapersyncedfolderbasisbyaddingthefollowingcommandtotheprecedingline:

,type:"nfs"

NetworkingBydefault,ourVagrantvirtualmachinesareonlyaccessiblefromthemachineswerunVagranton,andothermachinesinournetworkwon’tbeabletoaccessthem.Ifwemapportstoourhost,thenwecansharetheservicesrunningonthevirtualmachinewithourcolleagueswithinournetwork.IfwewanttoallowourcolleaguestoaccessourVagrantmanagedvirtualmachinesdirectly,wecanattachthevirtualmachinetoourinternalnetwork,andVirtualBoxwillbridgethenetworkbetweenourmachineandthevirtualmachine,andtheinternalnetworkbetweenourmachineandtherestofthemachinesinourhomeoroffice.

config.vm.network"private_network",ip:"10.11.100.200"

ThisapproachisalsousefulwhenwantingtohavemultipleVagrantprojectsrunningatthesametime;iftheyarewebprojects,theycanallexposeport80,butondifferentIPaddresses,andifwewant,wecanmapthesetothehostnamesinourhostsfile.

NoteThehostsfileisafileonacomputerthatmapsadomainnametoanIPaddress.ThiscanbeusedtopreventthecomputerfromhavingtolookuptheIPaddressforadomainandisusefulforlocallyhostedsites,aswecanmanuallylinktheIPaddresstoadomainname,justforourlocalmachine.OnOSXandLinux,thehostsfileisstoredas/etc/hosts,andonWindowsitisstoredasC:\Windows\System32\Drivers\etc\hosts.

Ifwewanttoshareaccesstoourvirtualmachineordemosomethingrunningonit,wecanuseVagrantSharethroughVagrantCloud,whichwewilldiscussinChapter9,HashiCorpAtlas.

ItisalsopossibletohavetheIPaddressassignedviaDHCP(typically,thiswillmeanthatyournetwork’srouterwillassignitanIPaddress):

config.vm.network"private_network",type:"dhcp"

AutorunningcommandsOneofthekeyconceptswithinVagrantisprovisioning.Thisinvolvesturningabasicvirtualmachinewithabaseoperatingsystemintoaserverthatisreadytorunforyourproject,meetingyourrequirements.Togofromthebaseoperatingsystemtoafullyfledgedmachine,weneedtouseaprovisioningtooltoinstallthesoftwareandconfigurethemachine.ThereareanumberofkeyprovisioningoptionswithinVagrant:

ShellPuppetAnsibleChef

Puppet,Ansible,andChefareallthird-partytoolsthatVagrantsupportsoutofthebox,andprovidespecificlanguagestoconfigureserversinanagnosticwaythatcanbeusedfordifferentoperatingsystems.Thenextthreechapterswilldiscussthesetoolsinmoredetail.Vagrantalsosupportssomeotherprovisioningtools,includingSalt,Docker,andCFEngine.

SSHprovisioninginvolvesrunningaseriesofcommandsonthevirtualmachineoverSSHwhenthemachineisfirstsetup.

TherearetwokeywaysinwhichwecanuseSSHprovisioning.WecaneitherdirectlyrunacommandfromourVagrantfileorwecanrunthecontentsofascript.

ThefollowinglineinourVagrantfilewillruntheinlinecommandprovided:

config.vm.provision"shell",inline:"sudoapt-getupdate"

Alternatively,wecantellVagranttorunaparticularshellscript(thelocationofthescriptspecifiedisrelativetoourprojectroot,thatis,/vagrant):

config.vm.provision"shell",path:"provision.sh"

Thisshellscriptcouldcontainallofthecommandsweneedtoconvertabaseboxintoabox,whichsupportsourprojectandapplication,perhapsinstallingwebanddatabaseservers.

ManagingVagrantboxesWecanmanageVagrantboxesusingthevagrantboxcommand.Let’srunthiscommandwiththehelpflag(--help)andseewhatsubcommandsareavailable:

vagrantbox--help

Runningthiscommandgivesthefollowingresult:

Therearesixavailablebox-relatedsubcommands.Witheachofthese,wecanprovidethe--helpflagtoseewhatadditionalargumentsareavailable.Theavailablebox-relatedsubcommandsare:

add:Thiscommandaddsanewboxlist:Thiscommandlistsallboxesinstalledoutdated:Thiscommandcheckswhetheranyboxeshaveupdatesavailableremove:Thiscommandremovesaboxfromthehostrepackage:ThiscommandconvertsaVagrantenvironmentintoadistributableboxupdate:ThiscommandwillupdatetheboxbeingusedbythecurrentrunningVagrantenvironment

AddingVagrantboxesTheaddsubcommandallowsustoaddanewbox.Ittakesasingleargumentandanumberofoptionalflags.Theargumentisaname,URL,orpathtoaboxfile.Ifanameisprovided,VagrantwilldownloadtheboxfromVagrantCloud.IfweprovideaURLorpathtoaboxstoredelsewhere,weneedtogiveVagrantanametouse.Thisisprovidedwiththe--nameoptionalflag.

Someotheroptionalflagsthatmightbeusefulinclude:--force,whichwilltellVagranttoremoveapre-existingboxwiththesamename;--clean,whichwilltellVagranttocleananytemporarydownloadedfiles;and--provider,whichallowsustospecifyanotherprovidertobackthebox(thedefaultproviderbeingVirtualBox,however,thereareprovidersavailableforVagrant,includingVMwareandAmazonEC2).

Thefollowingcommandwilladdanewpacktbox,andifanexistingoneisfound,itwilloverrideit:

vagrantboxadd––forcepackthttp://our-server.vagrant/packt.box

Theprocessofaddingaboxmaytakeawhile,asmostVagrantboxeswillbeatleast200MBbig.Oncedownloaded,theboxwillbeextractedandavailableforustouseinourVagrantprojects,asweobservedwhenwestartedourfirstprojectearlierinthechapter.

ListingVagrantboxesThelistsubcommandwilllisttheboxesinstalledwithinVagrant,alongwiththeproviderthatbacksthebox:

vagrantboxlist

Runningthiscommandgivesthefollowingoutput:

CheckingforupdatesBoxes,whichareprovidedbyVagrantCloud,mayberegularlyupdated;wecanusetheoutdatedsubcommandtoseewhetherthereareupdatesavailable:

RemovingVagrantboxesWecanremovetheboxwiththeremovesubcommand.Weneedtoprovidethenameoftheboxtoberemoved.Optionally,wecanalsospecifytheproviderandtheversionoftheboxtoberemovedwiththe--providerand--box-versionflags,respectively.Thefollowingexamplewillremoveourprecise64boxforVirtualBox:

vagrantboxremovehashicorp/precise64--providervirtualbox

Runningthiscommandgivesthefollowingoutput:

RepackagingaVagrantboxTherepackagesubcommandletsusconvertaVagrantenvironmentcompletewithanycustomizationswehavemadetoit,suchassoftwarewehaveinstalledonit,intoaboxthatwecanreuseanddistributetoothers.WewillusethiscommandinChapter8,CreatingYourOwnBox.

Updatingthecurrentenvironment’sboxWecanusetheupdatesubcommandtoupdatetheboxinuseonthecurrentVagrantenvironment:

vagrantboxupdate

Alternatively,wecanupdateaspecificbox,whichisn’ttiedtothecurrentenvironment,usingthe--boxflagtoprovidethenameofthebox(andthe--provideroptiontooifwewish).

ToomanyVagrants!OncewestartusingVagrantonarangeofprojects,thelackofaGUIcanmakeiteasytolosetrackofwhichprojectsarerunningorsuspendedonyourmachine.Thisisespeciallyannoyingwhenyouwanttobootupanewproject,butanexistingVagrantprojectiseithercausingaconflictorconsumingtoomanyresourcesonyourmachine.Thankfully,thereisnowacommandtolistallactiveVagrantenvironmentsonyourhost,forexample,

ThiscommandliststheIDs,names,providers,andstatesofourVagrantprojectsaswellasthedirectorytheyarerunningin:

WecanappendtheIDtotheendofthevagrantcommandtorunthecommandagainstthatmachine,withouthavingtogointothatfolder,forexample:

vagrantsuspend77e5115

SummaryInthischapter,wecreatedprojectswithVagrant,importedabaseboxtouse,andbootedourVagrantenvironment.WealsolookedatthecommandsneededtomanagetheseboxesandtheVagrantvirtualmachines.WelookedathowwecanconfigureourVagrantenvironmentwithnetworking,syncedfolders,andforwardedports,andhowtoprovisionsoftwareonourvirtualmachinewithSSHcommands.WhenitbecomesaproblemtohavemultipleVagrantprojectsrunning,wenowknowhowtolocatetheserunningprojectswiththeglobal-statuscommand.

Inthenextchapter,wewilltakealookathowtousePuppet,oneoftheprovisioningtoolssupportedbyVagrant.Wewillcoverinstallingandconfiguringservices,managingfilesandfolders,runningcommands,andmanagingusersandscheduledtasks.

Chapter3.ProvisioningwithPuppetVagrantisaverypowerfultoolprimarilybecauseofthefollowingkeyconceptsitcanmanageforus:

VirtualizationProvisioningBoxdistributionSharing

InChapter1,GettingStartedwithVagrantandChapter2,ManagingVagrantBoxesandProjects,welearnedtouseVagranttomanagevirtualmachinesforus.Whilethisisuseful,atthisstage,thesevirtualmachinesaredumb;theyhaveverylittlesoftwareinstalledforustouse,andtheyarecertainlynotconfiguredforourprojects.

TherearetwoapproacheswecanusetosetupaVagrant-managedvirtualmachinewithallthesoftwarerequiredforaproject:

UseabaseboxthatispreconfiguredwiththesoftwareordevelopmentstackthatwerequireProvisiontheexactsoftwareandconfigurationthatwerequireusingaprovisioningtool

Preconfiguredbaseboxesareusefulandhavetheirplace.IfwewerealwaysusingaspecificconfigurationorwewerecreatingaVagrantenvironmentforanopensourceprojectwewerereleasing,aconfiguredboxmightbethebestoption.Inthatinstance,aconfiguredbaseboxwillquicklygetusersupandrunningontheproject.Thedownsideisthatitisn’teasytochangetheconfigurationastheneedsoftheprojectchange,andcertainelementssuchascronjobsandbackgroundworkerswouldstillneedtobeconfiguredseparately.

Provisioning,however,automatestheprocessofturningabasemachineintoonethatisconfiguredforusewithaspecificproject.

Inthischapter,wewillquicklytakealookatthebasicsofPuppet,oneofthevariousprovisioningoptionsavailablewithinVagrant.Wewon’tlookatitwithinaVagrantcontextjustyet;wewillsimplytakealookathowaPuppetworks,andhowwecanuseit.InChapter6,ProvisioningVagrantMachineswithPuppet,Ansible,andChef,wewilltakealookathowtoconnectwhatwewilllearninthischapterwithVagrantitself.Inthischapter,wewilllearnthefollowingtopics:

HowPuppetworksThebasicsbehindPuppetmodulesandmanifestsHowtousePuppettoperformthefollowingtasks:

InstallsoftwareManagefilesandfolderswithinthefilesystemManagecronjobsRuncommands

Manageusersandgroups

CreatingconfigurableclassesHowtousethird-partyPuppetmodulesandPuppetForgeHowtomanuallyrunPuppettoprovisionamachine

Puppetitselfisalargetopicandthesubjectofseveralbooks.ForamoredetailedlookatPuppet,PacktPublishinghassometitlesdedicatedtoit:

Puppet2.7Cookbook,JohnArundel(http://www.packtpub.com/puppet-2-7-for-reliable-secure-systems-cloud-computing-cookbook/book)Puppet3:BeginnersGuide,JohnArundel(http://www.packtpub.com/puppet-3-beginners-guide/book)

ProvisioningWithinthiscontext,provisioningistheprocessofsettingupavirtualmachinesothatitcanbeusedforaspecificpurposeorproject.Typically,thisinvolvesinstallingsoftware,configuringthesoftware,managingservicesrunningonthemachine,andevensettingupusersandgroupsonthemachine.

Foraweb-basedsoftwareproject,provisioningwilllikelyentailtheinstallationofawebserver,aprogramminglanguage,andadatabasesystem.Configurationchangeswillbeneededtosetupadatabaseonthedatabasesystemandtoallowthewebservertowritetospecificfolders(todealwithuseruploads).

Withoutthisprovisioningprocess,wewouldhaveanalmostvanillainstallofanoperatingsystem,whichcontainsasyncedcopyofourprojectfolder;thisvanillainstallwouldn’tbeusableasadevelopmentenvironmentforourproject.Provisioningtakesustothenextlevelandgivesusafullyworkingenvironmentforourproject.

PuppetPuppetisaprovisioningtoolthatwecanusetosetupaserverforuseforaproject.TheconfigurationthatdetermineshowtheserverneedstobesetupcanbestoredwithinourVagrantprojectandcanbesharedwithteammatesthroughaversioncontrol,ensuringeveryonegetsanup-to-datecopyoftherequireddevelopmentenvironment.

Informationabouthowaservershouldbeconfigured,thatis,itssoftware,files,users,andgroups,iswrittenintofilesknownasthePuppetmanifests.ThesemanifestsarewrittenusingPuppet’sownlanguage,whichisaRubydomain-specificlanguage.Puppettakesthisinformationandcompilesitintoacatalogthatisspecificfortheoperatingsystemitisbeingappliedto.Thecatalogisthenappliedtothemachine.

Forourpurposes,wewillusePuppetinstandalonemode(thisisalsohowVagrantusesit).Standalonemodemeansthateverythingrunsfromonemachine.Puppetalsohasclient-servercapabilities,whereyoucandefinethePuppetmanifestsforalltheserversinyourinfrastructure,onacentralhost,anditkeepsyourindividualserversattherequiredlevelofconfiguration.

Puppetisidempotent,whichmeansrunningPuppetonamachinemultipletimeshasthesameeffectasrunningitonlyonce.Ineffect,Puppetensuresthatconditionsaremet,andiftheyarenot,itwillperformactionstoensurethattheyaremet,forexample,PuppetwouldinstallNginxifitwasn’talreadyinstalled.Ifitwasalreadyinstalled,itwoulddonothing.ThismeanswecanreprovisionwithPuppetmanytimeswithoutanydetrimentaleffect.ThisisusefulaswecanuseittokeeptheserverinsyncwithourPuppetmanifestsiftheyweretochange.

CreatingmodulesandmanifestswithPuppetPuppetismadeupofamanifestfileandanumberofmodules(whichalsocontainmanifestsandotherresources).Thedefaultmanifestspecifieswhichmodulesaretobeused,anddependingonthemodule,providescustomizationoptionsforit(forexample,thePuppetmoduleforsupervisord(http://supervisord.org/),aprocesscontrolsystem,allowsustospecifyanynumberofprocessesthatshouldbemanagedusingsupervisordthroughthemoduleitself).

ModulesmakeuseofresourceswithinPuppettocontrolandconfigurethemachine,andthesemodulescanbeimportedtoruninaspecificsequence,throughstages.

PuppetclassesPuppetmodulestypicallyconsistofclasses,which,inturn,utilizeanumberofresourcetypes(inthisexample,thepackageresourcetype,toinstallasoftwarepackage)toachieveaspecificrequirementforourserver.Iteffectivelyallowsustobundleanumberoftheseresourcetypesinaway,whichmeanswecansimplyincludetheclassbyitsname,andhavealloftheinstructionsexecutedfromwithinit.

Aclassinitsmostbasicformisstructuredasfollows:

classnginx{

package{"nginx":

ensure=>present,

require=>Exec['apt-getupdate']

}

}

ForitsmostbasicusewithinVagrant,classessuchasthesewillbesavedasdefault.ppwithinthemodules/nginx/manifests/folder.Theclasscancontainmanyresourcetypestoachieveadesiredgoal(forinstance,installingtheApachepackageisn’tthesameaspreparingthewebserverfullyforaproject,relatedtaskscanbebundledintothesameclass).

DefaultPuppetmanifestsForagivenproject,Puppetmodulesaretypicallyalllocatedinaspecificmodulesdirectory.Manymodulescanbecustomizedwhentheyarerun,anexamplebeingthesupervisordmodule;itsimplyprovidesthestructureforustocustomizeforeachprocesswewantittomanage.

Becauseofthis,weneedtohaveadefaultPuppetmanifestthatincludesalistofmodulestoberunandanyconfigurationsforthem.BecausePuppetisawareofourmodulefolderlocationwhenwerunit(andwhenitisrunthroughVagrant),wejustlistthemodulestobeincludedandrun.

Abasicmanifestthatwillincludeandrunthenginxclasswewroteearlierwouldbeasfollows:

import"nginx"

includenginx

Imentionedthesupervisormodule(https://github.com/plathrop/puppet-module-supervisor)afewtimesasamodulethatisdesignedtobeusedformultipledifferentthings,whichcanbecustomizedbythedeveloperusingit.

NoteSupervisordisthenameofthesoftware,however,thePuppetmodulewearegoingtousetomanagesupervisordiscalledsupervisor(no“d”)—sowatchoutforthat!

Supervisordisatoolthatmaintainsanumberofrunningprocesses,forexample,ifyouhaveabackgroundworkerinawebapplicationtoresizeimages,thesupervisormightberesponsibleforkeepingfiveworkersrunningatanyoneinstance,respawningthemwhenonehasfinished.ThefollowingisanexampleofhowthismodulewouldbeusedinadefaultPuppetmanifest:

supervisor::service{

'resize_images':

ensure=>present,

command=>'/usr/bin/php/vagrant/app/consoleimg:resize',

user=>'root',

group=>'root',

autorestart=>true,

startsecs=>0,

num_procs=>5,

require=>[Package['php5-cli'],Package['beanstalkd']];

}

supervisor::service{

email':

ensure=>present,

command=>'/usr/bin/php/vagrant/app/consoleemail',

user=>'root',

group=>'root',

autorestart=>true,

startsecs=>0,

num_procs=>5,

require=>[Package['php5-cli'],Package['beanstalkd']];

}

Here,weareinstructingPuppettousethesupervisordmoduletwicetosetupandmanagetwoworkersforus.Foreachoftheworkers,wehaveasetoffiveprocessestoberun,andwehavesettheuserandgrouptorunthem.WehavedefinedPHP’scommand-lineinterfaceandthebeanstalkdworkerqueueasrequirementsfortheworkers.ThisillustratesthepowerthatPuppetmoduleshave.

ResourcesPuppetprovidesarangeofresourcetypesthatwecanutilizetocreateourconfigurationfiles.Theseresourcetypesaretranslatedandcompileddependingontheoperatingsystembeingused.Forexample,ifweweretousethepackageresourcetypetoinstallsomesoftware,thiswoulduseapt-getonUbuntuandYumonFedoraoperatingsystems.A

smallnumberofresourcetypesareoperatingsystemspecific,forexamplethescheduled_taskresourcetypeisdesignedspecificallyforWindows,andthecrontypeisdesignedforLinuxandUnix-basedsystems.

Resourcetypesavailableinclude:

Cron:ThisresourcetypeisusedtomanagecronjobsonLinux-andUnix-basedsystemsExec:Thisresourcetypeisusedtoruncommandsattheterminal/commandpromptFile:ThisresourcetypeisusedtomanageandmanipulatefilesandfoldersonthefilesystemGroup:ThisresourcetypeisusedtomanageusergroupsPackage:ThisresourcetypeisusedtoinstallsoftwareService:ThisresourcetypeisusedtomanagerunningservicesonthemachineUser:Thisresourcetypeisusedtomanageuseraccountsonthemachine

Whenresourcetypesareuseddirectly(forexample,weusethePackageresourcetypetoinstallsomesoftware),theyareusedinlowercase(package).However,whenwerefertoaresourcetypewehaveused,forexample,asarequirementforanotherPuppetaction,wereferencethemwithaleadingcapitalletter(Package).

Anexampleofthisisasfollows:

package{"nginx":

ensure=>present,

require=>Exec['apt-getupdate']

}

WetellPuppettoinstallthenginxpackage(lowercase“p”forpackage),butwhenwespecifytherequirementofapreviouslyexecutedexeccommand,weusealeadingcapitalletter.TheoptionswithinthisinstructionforPuppet(ensureandrequirekeywords)arecalledparameters.

AfulllistofresourcetypesisavailableonthePuppetwebsiteathttp://docs.puppetlabs.com/references/latest/type.html.

Whenusingaresourcetype,anameisprovided(intheprecedinginstance,thisisnginx),thisisoftendualpurpose,servingbothasawayforustoreferencetheaction(inthiscase,thepackagebeinginstalled)andalsoasaninstruction(inthiscase,whatpackagePuppetneedstoinstall).WhenitcomestotheExecresourcetype,thenameisthecommandwewishtorun.Bydefault,weneedtoprovidethefullpathtothecommandthatwerun.Wecanavoidthisbyprovidingthepathfromwhichthecommandshouldberunasaparameter.

Resourcerequirements

CertainthingsthatwedowithPuppetwillrequireotheractionstohavebeenperformedfirst.Thesecanbedefinedusingtherequireparameter,andwecanspecifymultiplerequirements.

IfweneedtorunorinstallsomethingafterboththeMySQLServerandtheMySQLclient

packageshavebeeninstalled,wewillusetherequireparametertodefinethemasfollows:

require=>[Package['mysql-client'],Package['mysql-server']]

ThisdefinesanarrayofmultiplerequirementsasadependencyforourPuppetcode.

ResourceexecutionorderingSometimes,weneedtorunspecificblocksofthePuppetcodebeforeotherblocks.Inmostcases,wecanusetherequire,notify,andsubscribeparameterstogetaroundthisproblem.

Thenotify,subscribe,andrefreshonlyparametersSometimes,wewanttohaveaPuppetcommandrunmultipletimeswhenothercommandshavefinished.Oneexampleistorestartthenginxservice.Wewillperformthefollowingsteps:

1. Importanewconfigurationfile.2. Addnewvirtualhosts.

Wecanusethenotifyparametertoinstructonecommandtotriggeranothertoberun.Ineffect,thisnotifiesthenextcommandtotellitthattherehavebeenchangesmadeelsewhere,whichrequiresthatcommandtonowrun.

Inthefollowingexample,werequireaPuppetmanagedconfigurationfiletobecopiedtoourPuppetmanagedmachine.ThecoderequiresNginxtobeinstalledbeforeitisrun,andafterthefilehasbeencopiedacross,itwillnotifythenginxservicetoberestarted.Importantly,thisnotificationwillberuneachtimethefilechanges,butwon’tbetriggeredwhenitrunswherethefileisunchanged:

file{'/etc/nginx/sites-available/default':

source=>"puppet:///modules/nginx/default",

owner=>'root',

group=>'root',

notify=>Service['nginx'],

require=>Package['nginx']

}

Thiscanbealsobeachievedusingthesubscribeandrefreshonlyparameters,whichworkintheoppositewaytonotify.Thesubscribeparameterinstructsthecommandtoruneverytimeanyofthecommandsinthesubscribeoptionhavebeenrun.

Therefreshonlyparameter,whensettotrue,instructsthecommandtoonlyrunwhenoneofthecommandsitsubscribestohasrun(leavingthisoutwouldmeanthecommandisalsoruninitsownright):

service{"nginx":

refreshonly=>false,

subscribe=>File['/etc/nginx/sites-available/default'],

}

Here,thecommandtoreloadNginxwillonlyberunwhenthenewconfigurationfilehasbeenloaded.Wecan,ofcourse,extendthesubscribeparametertocontainotherthingssuchasmodulesandotherconfigurations,asdiscussedearlier.

TipOnlyservice,exec,andmountresourcetypescanberefreshed.

ExecutingresourcesinstagesWhererequire,notify,andsubscribearenotsuitableforourusecase,wecanusestages.Puppethasadefaultstage,withinwhichallcommandsrun.Wecancreateourown

stages,whichrunbeforeorafterthisstagethatallowustoforcecommandstoberuninspecificorders.

WecandefinestageswithinourdefaultPuppetmanifestandtheninstructPuppettoruncertainclassesfromwithinthatstage.If,forexample,wewantedtorunourNginxclassbeforeanythingelse,wecancreateastagetorunfirst,andputtheNginxclasswithinthatstageasfollows:

stage{'first':before=>Stage[main]}

class{'nginx':stage=>first}

Thiscreatesastagecalledfirst,andanythingassignedtothisstagewillbeexecutedbeforethedefaultPuppetstage;next,itplacestheNginxclasswithinthatstage.Oncewehaveanamedstage,suchasfirst,wecanthencreateotherstages,whichcanrunbeforethisonetoo.

NoteStagesareusefulwhenyouneedtogrouptheorderingofcertaintasks,however,theycannormallybeavoidedthroughtheproperuseofrequire,notify,andsubscribe,whichshouldbeusedinsteadwherepossible.

InstallingsoftwareLet’ssaywewanttoinstallNginxonourserver.Therearethreetypicalstepsinvolvedinthisprocess:

1. Updatingourpackagemanager.2. Installingthenginxpackage.3. Runningthenginxservice.

Becausethefirststepisdifferent,dependingontheoperatingsystemwearerunning,wewouldwanttoeithermovethisoutofPuppetatalaterstageorlookatusingamoduletoabstractitout,however,wewilluseitwithinPuppetforthetimebeing.Anyoperatingspecificcommands(suchasthese)arewrittenforUbuntu,whichistheoperatingsystemweareusingwithVagrant.IfyouarenotusingUbuntu,theExeccommandshouldberewrittentoupdatethepackagemanageronyoursystem.

NoteThisexampleispurelytoillustratetheprocessofputtingtogetherasimplemodule.TherearemanyexistingmodulesavailableonPuppetForge,whichwewillcometolater.

UpdatingourpackagemanagerInordertoupdateourpackagemanager,weneedtorunacommandontheserver.ThiscanbeachievedusingtheExecresourcewithinPuppet:

exec{'apt-getupdate':

command=>'/usr/bin/apt-getupdate',

timeout=>0

}

ThisinstructsPuppettoruntheapt-getupdatecommand.Wehavesetatimeoutofzerosothatifittakesawhile(andafterafreshinstallationofanoperatingsystemthroughVagrant,itmight),Puppetwillrunitforaslongasittakes,overridingthedefaulttimeout.

NoteThisisn’tthemostelegantofapproaches,especiallywithitbeingoperatingsystemspecificandsubsequentlyarequirementformostofourothercommands.InAppendix,ASampleLEMPStack,wewillbuildaLEMPserverprojectwithVagrantandPuppet,andintheexample,weuseVagrant’sSSHprovisioningoptionstoupdatethepackagemanagerbeforeweinstalltheothersoftware.Mostbaseboxesdon’thaveup-to-datepackagedetailstosavespaceandduetotheirage,soupdatingthepackagemanagerisrequired.

InstallingthenginxpackageWecanusethePackageresourcetoensurethatNginxisinstalled,andifitisn’t,itwillbeinstalledasfollows:

package{"nginx":

ensure=>present,

require=>Exec['apt-getupdate']

}

Here,wetoldPuppettoensurethatthenginxpackageispresent.Weaddedourapt-getupdatecommandasaprerequisite,soweknowthatourpackageswillbeuptodate.

RunningthenginxserviceFinally,tomakesurethatNginxisrunning,weusetheServiceresourcetoensurethatthenginxserviceisrunning.Obviously,thiscan’tberunifNginxisn’tinstalled,sothenginxpackageisaprerequisite:

service{"nginx":

ensure=>running,

require=>Package['nginx']

}

FilemanagementWecanusetheFileresourcewithinPuppettomanagefilesandfolderswithinthefilesystem.Let’stakealookatsomeexamples,whichallowusto:

CopyfilesCreatesymlinksCreatefoldersCreatemultiplefoldersinonego

CopyingafileOnecommonfileoperationwemightwanttoperformwouldbetotakeaconfigurationfilefromourprojectandcopyitintoourvirtualmachine.OneparticularusecasewouldbeanNginxconfigurationfile;wemightwanttodefinesomevirtualhostsandothersettingsinafile,whichwecansharewithourcolleagues.

TipWhilethisworkswellandcangetusupandrunningquickly,therearemodulesouttherethatallowustoconfigureNginxandothertypesofsoftwaredirectlyfromPuppet.Thistypicallyworksbythemoduleofstoringatemplatefile(acopyoftheconfigurationfilewithplaceholdersinit)andthen,insertingdatathatwedefinewithinPuppetintothetemplate,andcopyingthefileontothemachine.However,forthesakeofthisintroductorychapter,wewilljustcopyafileacross.

Thefileresourcetypeallowsustocreatefiles,folders,andsymlinks.Inordertocreateafile(orreplacethecontentsofanexistingfilewithanotherfile),wesimplytellPuppetwhatfilewewanttocreateorreplace(thedestination),thesource(thatis,thefiletobecopiedandputintothedestination),andtheuserandgroupwhoshouldownthefile:

file{'/etc/nginx/sites-available/default':

source=>'puppet://modules/nginx/default',

owner=>'root',

group=>'root',

require=>Package['nginx']

}

AsthisisanNginxconfigurationfile,itisworthensuringthatNginxisalreadyinstalled;otherwise,Nginxwilloverridethiswhenitinstallsthefirsttimeandthiswouldn’tmaketheprocessidempotent.

TipHere’ssomethingtonoteaboutfilelocations:thesourcefileintheprecedingfileresourcecodeisheldwithinaVagrantenvironmentandthePuppetmoduleitself.Wecanprovidetwokindsoffilepaths:eitherthefullpathtothefileonthemachine,whichPuppetisrunningon(ourVagrantenvironment),suchas/vagrant/path/to/defaultorapathrelativetoPuppetmodules.ThesePuppetpathsarestructuredlikethis:puppet:///modules/nginx/default.Thedifferenceyouwillnoteisthatitautomaticallylooksforinthefiles/folderwithinthenginxfolder;wedon’tneedtospecifythat.

CreatingasymlinkIfweomitthesourceparameterandinsteadaddanensureparameter,andsetthattolink,wecancreateasymlink.Atargetisusedtodefinewherethesymlinkshouldpointto,asshowninthefollowingcode:

file{'/var/www/vendor':

ensure=>'link',

target=>'/vagrant/vendor',

require=>Package['nginx']

}

CreatingfoldersSimilartotheprecedingsymlinkcode,thistime,wesimplyneedtosetensuretoadirectory.Thiswillthencreateadirectoryforusasfollows:

file{"/var/www/uploads":

ensure=>"directory",

owner=>"www-data",

group=>"www-data"

mode=>777,

}

Wecanusethemodeparametertosetthepermissionsofthefolder(thisalsocanbeusedforfileswecreateandmanage).

CreatingmultiplefoldersinonegoInmanywebprojects,wemightneedtocreateanumberoffolderswithinourserversorourVagrantvirtualmachines.Inparticular,wemightwanttocreateanumberofcachefoldersfordifferentpartsofourapplication,orwemightwanttocreatesomeuploadfolders.

Inordertodothis,wecansimplycreateanarraythatcontainsallofthefolderswewanttocreate.Wecanthenusethefileresourcetypeandpassthearraytocreatethemall,asfollows:

$cache_directories=[

"/var/www/cache/",

"/var/www/cache/pages",

"/var/www/cache/routes",

"/var/www/cache/templates",

]

file{$cache_directories:

ensure=>"directory",

owner=>"www-data",

group=>"www-data",

mode=>777,

}

CronmanagementThecronresourcetypeletsususePuppettomanagecronjobs,whichweneedtorunonthemachine.Weprovideaname,inthiscase,web_cron,thecommandtorun,theusertorunthecommandas,andthetimesatwhichtorunthecommand,asshowninthefollowingcode:

cron{web_cron:

command=>"/usr/bin/php/vagrant/cron.php",

user=>"root",

hour=>[1-4],

minute=>[0,30],

}

Puppetprovidesuswithdifferentconfigurationoptionstodefinethetimesatwhichacronshouldberun,whichincludesthefollowing:

Hour:Thisvalueisbetween0and23inclusiveMinute:Thisvalueisbetween0and59inclusiveMonth:Thisvalueisbetween1and12inclusiveMonthDay:Thisvalueisbetween1and31inclusiveWeekday:ThisvalueisSunday(7or0)toSaturday(6)

Ifoneoftheseisomittedfromtheconfiguration,thenPuppetrunsitforeachoneoftheavailableoptions(thatis,ifweomitmonth,itwillrunforJanuarythroughtoDecember).Whendefiningthedatesandtimes,wecaneitherprovidearange,forexample,[1-5]orspecifics,suchas[1,2,10,12].

RunningcommandsTheExecresourcetypeallowsustoruncommandsthroughtheterminalonthemachineweareprovisioning.OnecaveatwiththeexeccommandisthatifyoureprovisionwithPuppet,itwillrerunthecommand,whichcanbedamagingdependingonthecommand.WhatwecandowiththeExecresourcetypeissetthecreatesparameter.ThecreatesparametertellsPuppetthatafilewillbecreatedwhenthecommandisrun,andifPuppetfindsthatfile,itknowsthatithasalreadybeenrunandwon’trunitagain.

Takeforexample,thefollowingconfiguration;thiswillusethePHPcomposertooltodownloaddependencies.Thecommanditselfcreatesafilecalledcomposer.lock(wecan,ofcourse,usetheexeccommanditselftocreateafilemanually,perhapsusingthetouchcommand).Becauseofthelockfilethatiscreated,wecanusethecreatesparametertopreventthecommandfrombeingexecutedifithaspreviouslybeenexecutedandhascreatedthelockfile,asshowninthefollowingcode:

exec{"compose":

command=>'/bin/rm-rfv/var/www/repo/vendor/*&&/bin/rm–f

/var/www/repo/composer.lock&&/usr/bin/curl–s

http://getcomposer.org/installer|/usr/bin/php&&cd

/var/www/repo&&/usr/bin/php/var/www/repo/composer.

pharinstall',

require=>[Package['curl'],Package['git-core']],

creates=>"/var/www/repo/composer.lock",

timeout=>0

}

ManagingusersandgroupsTheuserandgroupresourcetypesletuscreateandmanageusersandgroups.TherearedifferencesbetweendifferentoperatingsystemsastowhatPuppetcandowiththeusersandgroupsandhowthisworks.ThecodeinthefollowingsectionistestedonUbuntu,Linux.MoreinformationonthedifferencesforusersandgroupsondifferentplatformscanbefoundonthePuppetwebsiteathttp://docs.puppetlabs.com/references/latest/type.html#user.

CreatinggroupsThesimplestwaytocreateagroupissimplytosettheensureparametertopresent:

group{"wheel":

ensure=>"present",

}

CreatingusersTocreateauser,thebasicinformationweshouldprovideisasfollows:

TheusernameThefactthatwewanttheusertoexist(ensure=>present)Thegroup(gid)theusershouldbepartofTheshelltousefortheuserThehomedirectoryfortheuserIfwewantPuppettomanagethehomedirectoryfortheuser,inthiscase,itwillcreatethefolderforusifitdoesnotexistThepasswordfortheuserTherequirementsthatweneedthewheelgroupinplacefirst

Thecodethatwillthencreateouruserisasfollows:

user{"developer":

ensure=>"present",

gid=>"wheel",

shell=>"/bin/bash",

home=>"/home/developer",

managehome=>true,

password=>"passwordtest",

require=>Group["wheel"]

}

UpdatingthesudoersfileIt’sallwellandgoodbeingabletocreateusersandgroupsonourmachine,however,onethingthatwecan’tdousingtheuserandgroupresourcetypesisdefineauserorgroupashavingelevatedprivileges,unlesswemaketheuserapartoftherootgroup.

Wecanuseanexeccommandtopushsometexttotheendofoursudoersfile;thetextweneedtopushjusttellsthefilethatwewanttogivethewheelgroupthesudoprivileges,asshowninthefollowingcode:

exec{"/bin/echo\"%wheelALL=(ALL)ALL\">>/etc/sudoers":

require=>Group["wheel"]

}

Thiscode,however,willcontinuallyaddthislinetothefileeachtimeitisrun,whichwedon’twant,however,aswelearnedearlier,wecaninstructtheexecresourcestoonlyrunatcertaintimes.Thankstosubscribeandrefreshonly:

exec{"/bin/echo\"%wheelALL=(ALL)ALL\">>/etc/sudoers":

subscribe=>Group["wheel"],

refreshonly=>true

}

Thisstillisn’tideal,asifwedecidetochangethewheelgroupthenthiswouldbererun,soideally,wemightkeepthesudoersfilewithinourPuppetconfigurationinsteadandusePuppettomanagethechangestoit.

CreatingconfigurableclassesOnelimitationthatourentirePuppetcodehassofarinthischapteristhatwiththeexceptionofthecontentsofsomefiles,theconfigurationisallfixed.IfwewanttoreusesomeofthePuppetcodeonanotherproject,wemightneedtochangethingssuchasvariablenames,pathstofiles,orotherproject-orenvironment-specificproperties.

Tomakeourcodemoreflexible,wecanputthecodeintoaclass,anduseclassparameterstodynamicallyinjectvariablesintotheclass.

Aclassis,atitssimplestlevel,amethodofgroupingrelatedcodetogether;however,wecanusethemtobuildreusableandconfigurablemodules.IfwetakethecomposerExecresourceillustratedearlier,wecanstarttomakethatreusablebyputtingitintoaclass:

classcomposer{

exec{"compose":

command=>'/bin/rm-rfv/var/www/repo/vendor/*&&/bin/rm–f

/var/www/repo/composer.lock&&/usr/bin/curl–s

http://getcomposer.org/installer|/usr/bin/php&&cd/var/www/repo&&

/usr/bin/php/var/www/repo/composer.pharinstall',

require=>[Package['curl'],Package['git-core']],

creates=>"/var/www/repo/composer.lock",

timeout=>0

}

}

Whilewecannowmoreeasilypullthisintoanotherproject,wearelockeddownintermsofthelocationofthecomposerfileandalsootherparametersthatmightberequired.Wealsorequiretwopackages:wewouldeitherrequirethatthedeveloperaddstheseelsewheretotheirPuppetcode,orwewouldincludethemhere,however,includingthemherewouldconflictwithothermodulesandreducesflexibility.Classparametersletuspassinformationtoaclasswhenitisused;thisinformationcanbeusedtocontrolthecodewithintheclassandalsoconfigurepartsoftheclass.

ForourComposerclass,wemightwanttoletthedeveloperusingitdecidewhetherthedependenciesareinstalledbythemoduleornot,andalsoprovidepathstobeusedbythemodule.Classparametersaredefinedinbracketsimmediatelyaftertheclassnameandcanhavedefaultvalues,soiftheyareomitted,theirdefaultsareused.

Wecanthenusecontrolstatementstodecidewhetherthedependenciesshouldbeinstalled,andwecanpullinthecontentsofavariableusing${variable}:

classcomposer($install_deps=true,$path='/var/www/repo/',

$composer_home='/var/www/'){

if($install_deps==true){

package{"curl":

ensure=>present

}

package{"git-core":

ensure=>present

}

}

exec{"compose":

command=>"/bin/rm-rfv${path}vendor/*&&cd${path}&&

/usr/bin/curl-shttp://getcomposer.org/installer|/usr/bin/php&&

COMPOSER_HOME=\"${composer_home}\"/usr/bin/php${path}composer.phar

install",

require=>[Package['curl'],Package['git-core'],Package['php5-

cli']],

creates=>"${path}composer.lock",

timeout=>0

}

}

Now,whenwewanttousethisclass,wepassthevaluesalongwiththesevariablenames.BecauseofthewayPuppetworks,theorderingoftheparametersdoesn’tmater;theyarepassedassociativelywiththeircorrespondingvariablenames,asshowninthefollowingcode:

class{

'composer':

install_deps=>true

}

PuppetmodulesTherearemanyexisting,well-written,reusablePuppetmodulesfreelyavailabletouse.PuppetForgeisacollectionofmodules,whichisavailableathttp://forge.puppetlabs.com/.Itisalwaysworthcheckingwhetherthereisanexistingmodulethatsolvesyourproblembeforewritingyourown.

UsingPuppettoprovisionserversWearegoingtotakealookathowtousePuppetwithVagrantinChapter6,ProvisioningVagrantMachineswithPuppet,Ansible,andChef,however,Puppetcanalsoberunindependently.IfPuppetisinstalled(itwillbeonmostVagrantbaseboxes,butifyouwanttorunitonanothermachine,itmightnotbe,soinstallitfirst),youcanusetheapplysubcommand,passingwithitthelocationofthemodulesfolderandthedefaultmanifesttoapply,asfollows:

puppetapply--modulepath=/home/michael/provision/modules

/home/michael/provision/manifests/default.pp

SummaryInthischapter,wehadawhirlwindtourofPuppetandexploredthevariouswaysinwhichwecoulduseittoprovisionaserverforourprojects.WeinstalledsoftwarewiththePackageresource,managedcronjobswiththeCronresource,managedusersandgroupswiththeUserandGroupresources,andrancommandswiththeExecresource.TomanageexecutionorderanddependencyrelationshipswithPuppet,welookedatusingRequire,Subscribe,Notify,andRefreshonly.Welookedathowmodules,classes,andstagesworkaswellashowtouseclassparameterstoconfigurereusablePuppetcode.Finally,welookedathowtousePuppettoprovisionamachine.

Inthenextchapter,wewilltakealookatAnsible,anotherprovisioningtoolthathassupportbuiltintoVagrant.

Chapter4.UsingAnsibleAnsibleisanotherprovisioningtoolsupportedbyVagrantthatmakesiteasyforustotakeabaseoperatingsysteminstallationandturnitintoafull-fledgedserverthatsuitstheneedsofourproject.

Inthischapter,wewillquicklytakealookatthebasicsofAnsible.Wewon’tlookatitwithinaVagrantcontextjustyet;wewillsimplytakealookathowAnsibleworks,andhowwecanuseit.InChapter6,ProvisioningVagrantMachineswithPuppet,Ansible,andChef,wewilltakealookathowtoconnectwhatwewilllearninthischapterwithVagrantitself.Inthischapter,wewilllearnthefollowingtopics:

HowAnsibleworksHowtouseAnsibletoperformthefollowingtasks:

InstallingsoftwareManagingfilesandfolderswithinthefilesystemManagingcronjobsRunningcommandsManagingusersandgroups

Howtousethird-partyAnsiblerolesHowtomanuallyrunAnsibletoprovisionamachine

Ansibleitselfisalargetopicandsubjectofseveralbooks.ForamoredetailedlookatAnsible,PacktPublishinghassometitlesdedicatedtoprovisioningwithAnsible:

LearningAnsible:https://www.packtpub.com/networking-and-servers/learning-ansibleAnsibleConfigurationManagement:https://www.packtpub.com/networking-and-servers/ansible-configuration-management

UnderstandingAnsibleAnsibleisanITautomationtoolthatprovidesprovision,orchestration,andconfigurationmanagementfeatures.UnlikewithPuppetandChef,Ansibledoesn’trequireanysoftwaretobepreinstalledontheserver,otherthananSSHservice,astheheavyliftingisdonebyourowncomputerthatconnectstoourAnsible-managedserversandinstructstheserveronhowitneedstochange.

LikePuppetandChef,Ansibleisalsoidempotent.ThismeanseachtimewerunAnsible,itwillonlyperformactionswhereachangeisrequired—soifweinstalltheNginxwebserver,thefirstrunofAnsiblewillinstallitandsubsequentrunswon’tbecauseitknowsNginxisalreadyinstalled.

AnsibleconfigurationiswritteninYamlAin’tMarkupLanguage(YAML),whichmakestheconfigurationeasytoreadandwrite.

Conceptually,Ansibleconfigurationismadeupofplaybooksthataremadeupofplays,whicharemadeupoftasks.Aplaybookistheconfigurationforanentiresystemorenvironment,whichismappedtospecificserversorhoststhroughplays—differentplayscanbeappliedtodifferentgroupsofserversatdifferenttimesfromthesameplaybook.Eachplaycontainsanumberoftasks,which,inturn,makecallstoAnsiblemodules.Inamoreadvancedcontext,wecanmakeuseofroleswithinAnsible(reusablefunctionality)suchthatourplaybooksmightsimplybeamappingofhoststoroles.However,forthepurposesofthischapter,wewillputtasksandmodulecallsdirectlyinourplaybook.

ModuleswithinAnsiblearesimilarincontexttoresourceswithinPuppet.Therearemodulestodealwithmanydifferentkindsofoperationsonaserver,whichwewilldiscussshortly.

InstallingAnsibleBecauseAnsibledoesn’trequireanysoftwaretobeinstalledontheserverside,wecan’tsimplyconnecttoaVagrantvirtualmachineandtryoutAnsiblebecauseitisn’tinstalledonthere!Inordertouseit,bothtotryitout,andalsowhenitcomestointegratingwithVagrant,weneedtoinstallAnsibleonourowncomputer,whichisknownasthecontrolmachine.

AlthoughAnsiblecanbeusedtomanageWindowsServers,itcannotberunfromaWindowscontrolmachine.

PackagesareavailableformanyLinuxdistributions,andAnsiblecanbeinstalledonOSXusingHomebreworPython’spip.Completedetailsofthedifferentoperatingsystemsareavailableonlineathttp://docs.ansible.com/intro_installation.html.

NoteAlthoughwedon’tneedanythinginstalledontheserverbeingmanaged,wedoneedSSHaccesstothemachine,andunlessweinstalladditionalpluginsforAnsible,wewillalsoneedtohavepublicandprivatekeyssetup,sothatwecanconnecttothemachinewewishtomanageoverSSHwithoutapasswordfromourcontrolmachine.

CreatinganinventoryWhenwerunAnsibletoprovisionorconfigureamachine,Ansibletakesthehostswewanttoapplytheconfigurationto,fromourplaybooks.Itthenlooksupthesemachinesinitsinventory,whichspecifytheaddressesandconnectiondetailsforthesemachines,sothatAnsiblecanconnecttotheminordertochecktheirstatusandruntheprovisioningtasks.

Ataminimum,theinventoryneedstocontainanameandanIPaddressforeachserverthatwewantAnsibletomanage.However,thereareadditionalconfigurationswecanprovide,forexample,settingtheusertoconnectas,thepasswordtouse(whichrequiresadditionalconfiguration),theporttoconnectthrough,andifweneedtotunneltotheserverthroughanother.Anexampleofcreatinganinventoryisasfollows:

defaultansible_ssh_host=192.168.100.123

AlthoughwearelookingatAnsibleoutsidethecontextofVagrant,westillmightwanttouseAnsible,independently,toconnecttoandconfigureaVagrant-managedvirtualmachinesothatwecantestitinisolation.InChapter6,ProvisioningVagrantMachineswithPuppet,Ansible,andChef,wewilllearnhowtodothiswithinVagrantitself.Ifwedothis,weneedtoprovidetheport.Wemightalsowishtochangetheuserthatweconnectastoroot,andensurethataspecificSSHkeyisusedfortheconnectionasfollows:

defaultansible_ssh_host=127.0.0.1ansible_ssh_port=2222

ansible_ssh_user=rootansible_ssh_private_key=~/.ssh/id_rsa

Thisinventoryfileissimplyaplaintextfilesavedsomewhereonourcontrolmachine.Bydefault,Ansiblewilllookforafilecalled/etc/ansible/hosts,whichitexpectstobetheinventory,however,whenwerunAnsible,wecanpointtoourowninventoryfileelsewhere,whichwewilldolaterinthischapter.

CreatingAnsibleplaybooksAswediscussed,anAnsibleplaybookisaYAMLfile.ThefollowingexampleisasimpleplaybookthatcontainsinstructionstoupdatetheAptpackagemanagerclassonthemachinecalledbydefaultinourinventory:

---

-hosts:default

tasks:

-name:updateaptcache

apt:update_cache=yes

Wecanrunthisplaybookbyrunningtheansible-playbookour-playbook.yml-iour-inventory-filecommand.Ansiblewillthenlookupthatthisplaybookistobeappliedtothedefaultmachine,thedefaultmachine’sdetails,connecttoit,andifappropriate,runthecommand.Wewillwalkthroughtheexecutionprocessshortly.

Tasksareexecutedintheorderthattheyappearwithintheplaybook.However,wehavetheoptiontocallothertaskstoberunlateronceanactioniscompleted,throughtheuseofhandlers,whichwewilldiscussshortly.

NoteBecauseplaybooksarewritteninYAML,theformatandspacing/indentationinthesefilesiscritical.Incorrectindentationcancausefilestonotbeparsedcorrectly.

Modules–whatAnsiblecandoAnsiblemodulesaresimilartoPuppetresources,andwecanusethemtoinstallandmanagepackages,servers,users,files,cronjobs,andsoon.

Themodulesavailableinclude:

Apt:ThisisusedtomanageaptpackagesGit:ThisisusedtomanageanddeployfromgitrepositoriesService:ThisisusedtomanagerunningservicesontheserverCopy:Thisisusedtocopyfiles

Eachmodulecanbeconfiguredwithdifferentproperties,aswewilldiscussinthischapter.AcompletelistofthemodulesisavailablefromtheAnsiblewebsiteathttp://docs.ansible.com/list_of_all_modules.html.

InstallingsoftwareLet’ssaywewanttoinstallNginxonourserver.Therearethreestepsinvolvedinthisprocess:

1. Updatingourpackagemanager.2. Installingthenginxpackage.3. Runningthenginxservice.

UpdatingourpackagemanagerWecanusetheaptmodule(http://docs.ansible.com/apt_module.html)toupdatetheaptpackagemanager’scache,whichistheequivalentofperforminganapt-getupdatecommand:

-name:updateaptcache

apt:update_cache=yes

Theupdate_cacheparametercanalsobeprovidedwhenwerunotherapt-relatedtasks,soinsteadofadedicatedtaskforit,wecaninsteadspecifythatwhenweinstallNginx,thepackagemanager’scachemustbeuptodate.

InstallingthenginxpackageWecanusetheaptmodule(http://docs.ansible.com/apt_module.html)toensurethatNginxisinstalled,andifitisn’t,itwillbeinstalledasfollows:

-name:ensurenginxisinstalled

apt:pkg=nginxstate=presentupdate_cache=yes

Here,wetoldAnsibletoensurethatthestateofthenginxpackageispresent,andthatweshouldupdatethepackagemanager’scachebeforeinstallingit.Therearedifferentstatesavailable,includingthelateststatestoensurethatwehavethelatestversionofapackagepresent,orabsenttoensurethatapackageisnotinstalledontheserver.

RunningthenginxserviceFinally,tomakesurethatNginxisrunning,weusetheservicemodule.WhileNginxwillautomaticallyrunwhenweinstallit,wecanconnecttoournewserverandaltersettingsorservicesbymistake.Ifthishappens,wecansimplyreruntheprovisioner,asNginxwillalreadybeinstalled,soitwon’treinstallit,buttheservicemodulewillforcetheservertostartthenginxservice.Wecanusetheenabledparametertoensurethattheserviceisconfiguredtostartautomaticallywhenthesystembootsnext:

-name:ensurenginxisrunning

service:name=nginxstate=startedenabled=yes

UnderstandingfilemanagementWecanusethefile,copy,andtemplatemoduleswithinAnsibletomanagefilesandfolderswithinthefilesystem.Let’stakealookatsomeexamples,whichallowustoperformthefollowing:

CopyfilesCreatesymlinksCreatefolders

CopyingafileOnecommonfileoperationwemightwanttoperformwouldbetotakeaconfigurationfilefromourprojectandcopyitintoourvirtualmachine.OneparticularusecasewouldbeanNginxconfigurationfile;wemightwanttodefinesomevirtualhostsandothersettingsinafile,whichwecansharewithourcolleagues.

TipWhilethisworkswellandcangetusupandrunningquickly,therearerolesouttherethatallowustoconfigureNginxandothersoftwaredirectlyfromAnsible.Thistypicallyworksbytheroleofstoringatemplatefile(acopyoftheconfigurationfilewithplaceholdersinit)andthen,insertingdatathatwedefinewithinourplaybookintothetemplate,andcopyingthefileontothemachine.However,forthesakeofthisintroductorychapter,wewilljustcopyafileacross.

Thetemplatemodule(http://docs.ansible.com/template_module.html)allowsustocopyafilefromourcontrolmachineontothemachinebeingprovisionedasfollows:

-name:writethenginxconfigfile

template:src=nginx-default-site.confdest=/etc/nginx/sites-

available/default.confowner=www-datagroup=www-data

AsthisisourNginxconfigurationfile,itmakessenseforustoreloadorrestartNginxwhenthisfilechangestoensurethattheupdatedconfigurationisappliedtotheserver.Wedothisintwostages:

1. Wesetourtasktonotifyahandleronceitisdone.2. Wecreateahandler,whichisonlyactivatedwhenitisnotified,torestartNginx.

Thefollowingisaplaybookthatupdatestheaptcache,installsNginx,ensuresthattheserviceisrunning,copiestheconfigurationfile,andthenensuresthatNginxisrestartedwhenthatfilechangesthroughanotifyoperationandahandler.Thenotifyandhandlerscodesectionsarehighlightedarefollows:

---

-hosts:default

tasks:

-name:updateaptcache

apt:update_cache=yes

-name:ensurenginxisinstalled

apt:pkg=nginxstate=present

-name:writethenginxconfigfile

template:src=nginx-default-site.confdest=/etc/nginx/sites-

available/default.conf

notify:

-restartnginx

-name:ensurenginxisrunning

service:name=nginxstate=started

handlers:

-name:restartnginx

service:name=nginxstate=restarted

CreatingasymlinkThefilemodule(http://docs.ansible.com/file_module.html)allowsustocreatesymboliclinkstotheexistingfilesandfoldersinthefilesystem.If,forinstance,wewanttomapapublicfolderwithinourwebserversrootdirectorytoafolderwithinourVagrantsharedfolder,wecandothisasfollows:

-name:makeourVagrantsyncedfolderourwebroot

file:src=/vagrantdest=/var/www/siteowner=www-datagroup=www-data

state=link

CreatingfoldersWecanalsousethefileresourcetypetocreatefolders;thisisparticularlyusefulforscenariossuchasfolderstoholdfiles(avatars,attachments,andsoon)uploadedbyusersofawebapplication:

-name:createanuploadsfolder

file:path=/var/www/uploadsowner=www-datagroup=www-datamode=0777

state=directory

Wecanusethemodeparametertosetthepermissionsofthefolder,andtheownerandgroupparameterstosettheuserandgroupswhoownthedirectory(thesealsocanbeusedforfileswecreateandmanagetoo).Finally,thestateparameterisusedtoensurethatthepathprovidedisafolder.

ManagingcronThecronmodule(http://docs.ansible.com/cron_module.html)letsususeAnsibletomanagecronjobs,whichweneedtorunonthemachine.Weprovideaname(whichisarequiredparameter),inthiscase,web_cron,thecommandtorun,theusertorunthecommand,andthetimesatwhichtorunthecommand,asshowninthefollowingcode:

-name:Runsomecron

cron:name="web_cron"hour="1-4"minute="0,30"job="/usr/bin/php

/vagrant/cron.php"

Ansibleprovidesuswithvariousdifferentconfigurationoptionstodefinethetimesatwhichacronshouldberun.Theseinclude:

Hour:Thisvalueisbetween0and23inclusiveMinute:Thisvalueisbetween0and59inclusiveMonth:Thisvalueisbetween1and12inclusiveDay:Thisvalueisbetween1and31inclusiveWeekday:ThisvalueisfromSunday(0)toSaturday(6)

Ifoneoftheseisomittedfromtheconfiguration,thenAnsiblerunsitforeachoneoftheavailableoptions(thatis,ifweomitmonth,itwillrunforJanuarythroughtoDecember),asithasadefaultvalueof*.Whendefiningthedatesandtimes,wecaneitherprovidearange,forexample,1-5orspecifics,suchas1,2,10,12.

RunningcommandsThecommandandshellmodulesallowustoruncommandsthroughtheterminalonthemachineweareprovisioning.Thedifferencebetweenthetwoisthattheshellmodulewillrunthecommandsthroughashellontheremotesystem.Soifweneedtoaccessenvironmentvariablesoroperators,suchas&,|,>,and<,thenweneedtousetheshellmodule.

ManagingusersandgroupsTheuserandgroupmodules(http://docs.ansible.com/user_module.htmlandhttp://docs.ansible.com/group_module.html)letuscreateandmanageusersandgroups.

CreatinggroupsWesimplyprovideaname.Bydefault,thestateparameterissettopresent:

-name:createsomenewgroup

group:name=newgroupstate=present

CreatingusersTocreateauserwecanusetheusermodule(http://docs.ansible.com/user_module.html);theminimuminformationweneedagainistheusername.However,wecanalsospecifytheirgroup,password(providingacryptedhashasperhttp://docs.ansible.com/faq.html#how-do-i-generate-crypted-passwords-for-the-user-module),andevenwhetheranSSHkeycanbegeneratediftheuserdoesnothaveone:

-name:createanewuser

user:name=ournewusergroup=newgroupstate=present

UsingAnsiblerolesTherearemanyexisting,well-written,reusableAnsiblerolesfreelyavailabletouse.Theserolestypicallymanagelargeaspectsofserverfunctionalityinonereusablebundle,forexample,thereisanNginxroletomanageNginxandconfiguresiteswithit.TherearemanyrolesavailableonAnsibleGalaxy(https://galaxy.ansible.com/),soitisworthcheckingtheseoutbeforewritingourowncode!

UsingAnsibletoprovisionserversOncewehaveaplaybookandinventoryfile,wecanruntheansible-playbookcommandtoanalyzeourplaybook,andensurethattheconfigurationforthematchingserversinourinventoryfileisupdated:

ansible-playbookour-playbook.yml-iour-inventory-file

Whenthiscommandwasrunforthefirsttimeagainstaparticularserver,theoutputwassomethinglikethis:

Let’swalkthroughthisscreenshottoseewhatisgoingon:

1. First,Ansiblepullsthefilestogetherandcheckswhethereverythingisvalid.2. Next,itgathersfactsabouttherelatedmachinesitneedstoconnectto.Thisisdone

byconnectingoverSSHandfindingoutinformation,suchasspecification,networkingdetails,andsoon.

3. Next,itrunsthroughthetasksinourplaybook.Wheninstallingandwritingourconfigurationfiles,Ansibleneedstomakeachange,becauseitisn’tinstalledandthefileisn’tthere.

4. Onceinstalled,Nginxautomaticallystarts,sothetasktoensurethatitisrunningdoesn’tdoanything(thiscomesbacktotheidempotencyofAnsible).AstheconfigurationfilewritingnotifiesthehandlertorestartNginx,Nginxisthenrestartedattheend.

5. Finally,weseearecap,threechangesweremade,andfivetasksresultedinanokresponse.

Onsubsequentruns,theoutputlookslikethis:

Therearetwodifferences:firstly,Ansibledoesn’tneedtodoanything,soeverythingisgreenandwegetfourokresults.Again,thisisbecauseAnsibleisidempotent,soitonlydoesthingswhenachangetothesystemisrequired.Secondly,becausewedidn’tnotifytheNginxrestarthandler,thehandlerwasn’tevenrunasatask,whichiswhyourrecapnumberhasdroppedto4,andtherewasnorelatedoutputforthehandler.

SummaryInthischapter,welearnedaboutAnsible,theITautomationtool.Welookedathowitworks,andhowtocreateaninventoryfilesoAnsiblecanmanagedifferentservers,andhowtowriteplaybooks,whichcanworkwithsomeofthedifferentmodules.

Weinstalledthesoftwareandlearnedtoupdatethepackagemanagercachewiththeaptmodule,andpackagesthatareserviceswerethenstartedandmanagedwiththeservicemodule.ThetemplatemoduleallowedustocopyfilesfromourcontrolmachinetotheAnsible-managedmachine.Inordertotriggerservicereloads,welookedintonotifyinghandlersafterspecifictasksoccur.

Tocreateandmanage,files,folders,andsymlinksthefilemodulewasused,andweusedthecronmoduletocreateandmanagecronjobs.Usersandgroupswerecreatedandmanagedwiththeuserandgroupmodulesandfinallywelookedintorunningcommandswiththecommandandshellmodules.

Inthenextchapter,wewilltakealookatChef,thefinalprovisionerthatwewilldiscussinthisbook,andalsodiscusshowwecanuseittoprovisionservers.

Chapter5.UsingChefChefisanotherprovisioningtoolsupportedbyVagrantthatmakesiteasyforustotakeabaseoperatingsysteminstallationandturnitintoafull-fledgedserversuitedtotheneedsofourproject.

Inthischapter,wewillquicklytakealookatthebasicsofChef.Wewon’tlookatitwithinaVagrantcontextjustyet;wewillsimplytakealookathowChefworks,andhowwecanuseit.InChapter6,ProvisioningVagrantMachineswithPuppet,Ansible,andChef,wewilltakealookathowtoconnectwhatwewilllearninthischapterwithVagrantitself.Inthischapter,wewilllearnthefollowingtopics:

HowChefworksThebasicsbehindChefcookbooksandrecipesHowtouseCheftoperformthefollowingtasks:

InstallingsoftwareManagingfilesandfolderswithinthefilesystemManagingcronjobsRunningcommandsManagingusersandgroups

Howtousethird-partyChefcookbooksandrecipesHowtomanuallyrunCheftoprovisionamachine

Chefitselfisalargetopicandthesubjectofseveralbooks.ForamoredetailedlookatChef,PacktPublishinghassometitlesdedicatedtoprovisioningwithChef:

ChefInfrastructureAutomationCookbook,http://www.packtpub.com/chef-infrastructure-automation-cookbook/bookInstantChefStarter,http://www.packtpub.com/chef-starter/book

KnowingaboutChefChefisaprovisioningtoolthatwecanusetosetupaserverforuseforaproject.Theconfiguration,whichdetermineshowtheserverneedstobesetup,canbestoredwithinourVagrantprojectandcanbesharedwithteammatesthroughversioncontrol,ensuringthateveryonegetsanup-to-datecopyoftherequireddevelopmentenvironment.

Informationabouthowaservershouldbeconfigured,thatis,itssoftware,files,users,andgroups,iswrittenintofilesknownasChefrecipes.TheserecipesarewrittenasRubyfiles.Cheftakesthisinformationandmatchesittoprovidersthatareusedtoexecutetheconfigurationonthemachineinacompatibleway.

Forourpurposes,wewilluseChef-solo,whichisitsstandalonemode(thisisalsohowVagrantusesit).Chef-solomeansthateverythingrunsfromonemachine.Chefalsohasclient-servercapabilities,whereyoucandefinetheChefcookbooksandrolesforalltheserversinyourinfrastructureonacentralhost,anditkeepsyourindividualserversattherequiredlevelofconfiguration.

AswithPuppet,Chefisalsoidempotent,whichmeansrunningChefonamachinemultipletimeshasthesameeffectasrunningitonlyonce.

CreatingcookbooksandrecipeswithChefChefinstructionsarerecipesthatarebundledtogetherincookbooks.Acookbookcontainsatleastonerecipe,whichperformssomeactions.Cookbookscancontainmultiplerecipesandotherresourcessuchastemplatesandfiles.

Atitsmostbasiclevel,acookbookisafolder(namedasthenameofthecookbook)thatcontainsatleastarecipesfolder,whichcontainsatleastadefaultrecipefile,default.rb.Filesaretypicallystoredinafilesfolderwithinthecookbookfolderandtemplatefileswithinthetemplatesfolder.

NoteWhilebothPuppetandChefuseRuby,Puppetisadomain-specificlanguage,whichmakesitlookandfeellikeitsownlanguage,whereasChefisstructuredmorelikeRubyitself.

Resources–whatChefcandoChefusesresourcestodefinetheactionsandoperationsthatcanbeperformedagainstthesystem.ResourcesaremappedtoaChefcode,whichvariesdependingontheplatform/operatingsystembeingused.Forexample,onanUbuntumachine,thepackageresourceismappedtoapt-get.Someofthesesystem-specificinstructionscanalsobeaccesseddirectlyviatheirownresources,apt_package.Forexample,thisisusedtomanagepackagesonUbuntu-andDebian-basedsystems,whereasusingthepackageresource,Chefwillworkoutwhichpackagemanagertousebasedontheoperatingsystem.

Resourcetypesavailableinclude:

cron:ThisresourcetypeisusedtomanagecronjobsonLinux-andUnix-basedsystemsexecute:Thisresourcetypeisusedtoruncommandsattheterminal/commandpromptfile:Thisresourcetypeisusedtomanageandmanipulatefilesandfoldersonthefilesystemgroup:Thisresourcetypeisusedtomanageusergroupspackage:Thisresourcetypeisusedtoinstallsoftwareservice:Thisresourcetypeisusedtomanagerunningservicesonthemachinetemplate:ThisresourcetypeisusedtomanagefilecontentswithanembeddedRubytemplateuser:Thisresourcetypeisusedtomanageuseraccountsonthemachine

Eachresourcecanbeconfiguredwithdifferentattributes,aswewilldiscussinthischapter.AcompletelistoftheresourcetypesisavailableontheOpscodewebsite(OpscodeisthecompanybehindChef)athttp://docs.opscode.com/resource.html.

InstallingsoftwareLet’ssaywewanttoinstallNginxonourserver.Therearethreestepsinvolvedinthisprocess:

1. Updatingourpackagemanager.2. Installingthenginxpackage.3. Runningthenginxservice.

Becausethefirststepisdifferentdependingontheoperatingsystemwearerunning,wemightwanttomovethisoutofChefatalaterstage;however,wewilluseitwithinChefforthetimebeing.Anyoperatingspecificcommands(suchasthis)arewrittenforUbuntu,whichistheoperatingsystemweareusingwithVagrant.

UpdatingourpackagemanagerInordertoupdateourpackagemanager,weneedtorunacommandontheserver.ThiscanbeachievedusingtheexecuteresourcewithinChefasfollows:

execute"apt-getupdate"do

ignore_failuretrue

end

ThisinstructsCheftoruntheapt-getupdatecommand.Asthenameoftheresource(thepartprovidedinquotesafterthenameoftheresource)isthecommandwewanttorun,thiswillbeexecuted.Ifweuseafriendlynameinstead,thenwewouldneedtoprovideacommandattributeasfollows:

execute"update-package-manager"do

command"apt-getupdate"

ignore_failuretrue

end

Bydefault,theexecuteresourceshaveatimeoutof3,600seconds,however,thiscanbeoverriddenbygivingatimeoutattributetotheresourceandatimevalue,forexample:

execute"apt-getupdate"do

ignore_failuretrue

timeout6000

end

InstallingthenginxpackageWecanusethepackageresourcetoensurethatNginxisinstalled,andifitisn’t,itwillbeinstalledasfollows:

package"nginx"do

action:install

end

Here,wetoldCheftoensurethatthenginxpackageisinstalled.Providedthatwehaveincludedtherecipeorcookbookthatcontainstheapt-getupdatecommandbeforetheprecedingcode,ourpackagemanagerwillbeuptodate.

RunningthenginxserviceFinally,tomakesurethatNginxisrunning,weusetheserviceresource.AswellasensuringNginxrunswhenitisfirstinstalled,thisalsoensuresthatifwemakeanychangestoourserver(andaccidentallystopNginx),wecansimplyreruntheprovisioner.AsNginxwillalreadybeinstalleditwon’treinstallit,buttheserviceresourcewillforceCheftoenablethenginxservice(soitautomaticallystartsonsystemboot),andstarttheservicewhenthecommandisrun,asfollows:

service"nginx"do

supports:status=>true,:restart=>true,:reload=>true

action[:enable,:start]

end

ThesupportspropertyisalistofattributesthatinstructChefonhowtomanageaparticularservice.Theactionensuresthatweenabletheservice(tohaveitrunwhenthemachinebootsup)andruntheservice(so,wedon’thavetowaitforarestart).

UnderstandingfilemanagementWecanusecookbook_file,directory,link,andtemplateresourceswithinCheftomanagefilesandfolderswithinthefilesystem.Let’stakealookatsomeexamples,whichallowusto:

CopyfilesCreatesymlinksCreatefoldersCreatemultiplefoldersinonego

CopyingafileOnecommonfileoperationwemightwanttoperformwouldbetotakeaconfigurationfilefromourprojectandcopyitintoourvirtualmachine.OneparticularusecasewouldbeanNginxconfigurationfile;wemightwanttodefinesomevirtualhostsandothersettingsinafile,whichwecansharewithourcolleagues.

TipWhilethisworkswellandcangetusupandrunningquickly,therearemodulesouttherethatallowustoconfigureNginxandothersoftwaredirectlyfromChef.Thistypicallyworksbythemodulestoringatemplatefile(acopyoftheconfigurationfilewithplaceholdersinit)andtheninsertingdatawedefinewithinChefintothetemplateaswellascopyingthefileontothemachine.However,forthesakeofthisintroductorychapter,wewilljustcopyafileacross.

Thecookbook_fileresourceallowsustocopyafilefromaChefcookbookontothemachineasfollows:

cookbook_file"/etc/nginx/sites-available/default"do

backupfalse

action:create_if_missing

end

Becauseweomittedthesourceandpathattributes,Chefmakessomeassumptions.Ittakesthebasename(ineffect,thelastelement)ofthenameandusesthisasthesource(thebasenameof/etc/nginx/sites-available/defaultbeingthedefault)andusesthenameasthepath(destination).Thesourcefileshouldbelocatedinthefilesfolderwithinthecookbook’sownfolder.

AsthisisanNginxconfigurationfile,itisworthensuringthatNginxisalreadyinstalled;otherwise,Nginxwilloverridethiswhenitinstallsthefirsttime,andthiswouldn’tmaketheprocessidempotent.Wecandothisbynotifyingthenginxservice,forexample:

cookbook_file"/etc/nginx/sites-available/default"do

backupfalse

action:create_if_missing

notifies:restart,"service[nginx]",:delayed

end

ThedelayedoptionallowsalloftheserestartrequeststobequeuedupandexecutedattheendofChef’sexecution;theoppositeofthisbeingimmediately.

CreatingasymlinkThelinkresourceallowsustocreatesymboliclinkstotheexistingfilesandfoldersonthefilesystem.If,forinstance,wewanttomapapublicfolderwithinourwebserver’srootdirectorytoafolderwithinourVagrantsharedfolder,wecandothisasfollows:

link"/var/www/public"do

to"/vagrant/src/public"

end

CreatingfoldersWecanusethedirectoryresourcetocreatefolders;thisisparticularlyusefulforscenariossuchasfolderstoholdfiles(avatars,attachments,andsoon)uploadedbyusersofawebapplication:

directory"/var/www/uploads"do

owner"root"

group"root"

mode00777

action:create

end

Wecanusethemodeparametertosetthepermissionsofthefolder,andtheownerandgroupparameterstosettheuserandgroupswhoownthedirectory(thesealsocanbeusedforfileswecreateandmanagetoo).Finally,the:createactionisusedtoensurethatthefolderiscreated.

CreatingmultiplefoldersinasingleprocesswithloopingInmanywebprojects,wemightneedtocreateanumberoffolderswithinourserversorourVagrantvirtualmachines.Inparticular,wemightwanttocreateanumberofcachefoldersfordifferentpartsofourapplication,orwemightwanttocreatesomeuploadfolders.

Inordertodothis,wecansimplycreateanarraythatcontainsallofthefolderswewanttocreate.Wecanthenusethedirectoryresourcetypeandloopthroughalistofdirectorynames:

%w{dir1dir2dir3}.eachdo|dir|

directory"/tmp/mydirs/#{dir}"do

mode00777

owner"www-data"

group"www-data"

action:create

end

end

ManagingcronThecronresourcetypeletsususeCheftomanagecronjobsthatweneedtorunonthemachine.Weprovideaname,inthiscase,web_cron,thecommandtorun,theusertorunthecommand,andthetimesatwhichtorunthecommand,asshowninthefollowingcode:

cron"web_cron"do

action:create

command"/usr/bin/php/vagrant/cron.php"

user"root"

hour"1-4"

minute"0,30"

end

Chefprovidesuswithvariousdifferentconfigurationoptionstodefinethetimesatwhichacronshouldberun;theseinclude:

hour:Thisvalueisbetween0and23inclusiveminute:Thisvalueisbetween0and59inclusivemonth:Thisvalueisbetween1and12inclusiveday:Thisvalueisbetween1and31inclusiveweekday:ThisvalueisSunday(0)-Saturday(6)

Ifoneoftheseisomittedfromtheconfiguration,thenChefrunsitforeachoneoftheavailableoptions(thatis,ifweomitmonth,itwillrunfromJanuarythroughtoDecember).Whendefiningthedatesandtimes,wecaneitherprovidearange,forexample,1-5,orspecifics,suchas1,2,10,12.Wecanalsoprovideanemailtopropertytoe-mailtheresultingoutputfromthecrontoane-mailaddressofourchoice.

RunningcommandsTheexecuteresourceallowsustoruncommandsthroughtheterminalonthemachineweareprovisioning.OnecaveatwiththeexeccommandisthatifyoureprovisionwithChefitwillrerunthecommand,whichcanbedamagingdependingonthecommand.Whatwecandowiththeexecuteresourceissetthecreatesparameter.ThecreatesparametertellsChefthatafilewillbecreatedwhenthecommandisrun;ifCheffindsthatfile,itknowsthatithasalreadybeenrun,anditwon’trunitagain.

Take,forexample,thefollowingconfiguration;thiswouldusethePHPcomposertooltodownloaddependencies.Thecommanditselfcreatesafilecalledcomposer.lock(wecan,ofcourse,usetheexeccommanditselftocreateafilemanually,perhapsusingthetouchcommand).Becauseofthelockfilethatiscreated,wecanusethecreatesparametertopreventthecommandfrombeingexecutedmultipletimeswhenalockfileisfound:

execute"compose"do

command"/bin/rm-rfv/var/www/repo/vendor/*&&/bin/rm–f

/var/www/repo/composer.lock&&/usr/bin/curl–s

http://getcomposer.org/installer|/usr/bin/php&&cd

/var/www/repo&&/usr/bin/php/var/www/repo/composer

.pharinstall"

creates"/var/www/repo/composer.lock"

timeout6000

end

ManagingusersandgroupsTheuserandgroupresourcetypesletuscreateandmanageusersandgroups.TherearedifferencesbetweendifferentoperatingsystemsastowhatChefcandowiththeusersandgroupsandhowthisworks.

CreatinggroupsThesimplestwaytocreateagroupissimplytosettheactionto:create,asfollows:

group"wheel"do

action:create

end

CreatingusersTocreateauser,weshouldprovidethefollowingbasicinformation:

TheusernameThefactthatwewanttocreatetheuserThegroup(gid)theusershouldbepartofTheshelltousefortheuserThehomedirectoryfortheuserWhetherwewantCheftomanagethehomedirectoryfortheuser;inthiscase,itwillcreatethefolderforusifitdoesnotexistThepasswordfortheuser

Thecodethatwillthencreateouruserisasfollows:

user"developer"do

action:create

gid"wheel"

shell"/bin/bash"

home"/home/developer"

supports{:manage_home=>true}

password"passwordtest"

end

UpdatingthesudoersfileIt’sallwellandgoodbeingabletocreateusersandgroupsonourmachine,however,onethingthatwecan’tdousingtheuserandgroupresourcetypesisdefineauserorgroupashavingelevatedprivileges,unlesswemaketheuserapartoftherootgroup.

Wecanuseanexeccommandthroughtheexecuteresourcetopushsometexttotheendofoursuodersfile;thetextweneedtopushsimplytellsthefilethatwewanttogivethewheelgroupsudoprivileges.Thecommandwewillneedtoexecuteisasfollows:

/bin/echo\"%wheelALL=(ALL)ALL\">>/etc/sudoers

KnowingcommonresourcefunctionalitiesThereisalsoasetofcommonfunctionalityavailabletoallresources.Thiscommonfunctionalityincludes:

Theabilitytodonothingwiththe:nothingactionSharedattributesavailabletoallresources:ignore_failure,provider,retries,retry_delay,andsupportsThenot_ifandonly_ifconditionstoensurethatactionsonlyrunwhencertainconditionsaremet;thesearecommandsthatarerunanddependingontheirreturnvalue,recipes,andresourcescanbeignoredTherearenotificationstoinstructotherresourcesthatanotheractionhasbeencompleted,orforaresourcetotakeactionifanotherresourcechanges(subscribes)

UsingChefcookbooksTherearemanyexisting,well-written,reusableChefcookbooksfreelyavailabletouse.TheOpscodecommunitysitecontainsacollectionofthemathttp://community.opscode.com/cookbooks.Itisalwaysworthcheckingwhetherthereisanexistingcookbookthatsolvesyourproblembeforewritingyourown.

UsingCheftoprovisionserversWewilltakealookathowtouseChefwithVagrantinChapter6,ProvisioningVagrantMachineswithPuppet,Ansible,andChef;however,Chefcanalsoberuninitsownright.ProvidedChefisinstalled(itwillbeonmostVagrantbaseboxes,butifyouwanttorunitonanothermachine,itmightnotbe,soinstallitfirst),youcanusethechef-solocommand,passingwithitthelocationofaconfigurationfiletouse,andaJSONfilethatcontainsattributeswewishtouse(thisshouldincludetherublist,whichisthelistofrecipesandcookbookswewishtouse),asfollows:

chef-solo–c/home/michael/chefconfig.rb–j

/home/michael/attributes.json

Therearesomeusefullinksinthislistyoucanrefertoformoreinformation

Chef-soloconfiguration:http://docs.opscode.com/config_rb_solo.htmlApplyrecipestorunlists:http://docs.chef.io/recipes.html#apply-to-run-listsAnatomyofaChefrun:https://github.com/jhotta/chef-fundamentals-ja/blob/master/slides/anatomy-of-a-chef-run/01_slide.mdCheftutorial:http://www.mechanicalfish.net/configure-a-server-with-chef-solo-in-five-minutes/

SummaryInthischapter,wehadawhirlwindtourofChefandexploredthevariouswayswecoulduseittoprovisionaserverforourprojects.Thisincludedhowtoinstallsoftwarepackageswiththepackageresourceandrunserviceswiththeserviceresource.Wealsomanagedcronjobswiththecronresource,managedusersandgroups,andrancommands.Finally,welookedathowrecipesandcookbookswork,andhowwecanuseCheftoprovisionaserver.

Inthenextchapter,wewilltakealookathowtousebothChefandPuppettoprovisionamachinewithinthecontextofVagrant.

Chapter6.ProvisioningVagrantMachineswithPuppet,Ansible,andChefInChapter3,ProvisioningwithPuppet,Chapter4,UsingAnsible,andChapter5,UsingChef,wehadanintroductiontoPuppet,Chef,andAnsible,whichareprovisioningtoolswithsupportbuiltintoVagrant.However,weonlylookedathowthetoolsworkedinageneralway;wedidn’tlookathowtousethemwithVagrant.

Inthischapter,youwilllearnthefollowingtopics:

UsingPuppetwithinVagrantUsingChefwithinVagrantUsingAnsiblewithinVagrantRecappinghowtoprovisionwiththebuilt-inSSHprovisionerWorkingwithmultipleprovisionersHowwecanoverridetheprovisioningtoolsthroughthecommandline

ProvisioningwithinVagrantVagrantreliesonbaseboxesfortheguestvirtualmachines;thesearespecificallypreconfiguredvirtualmachineimagesthathavecertainsoftwarepackagespreinstalledandpreconfigured.PuppetandChefaretwosuchsoftwarepackagesthatarepreinstalled(AnsibleiscontrolledbyVagrantitselfonthehostmachine,soitisn’tinstalledonthevirtualmachine,butrequiresanSSHconnectiontothevirtualmachine).Vagranthasitsowninterfacethroughtothesepackagesfromthehostmachine.ThismeanswecanprovidesomeconfigurationinourVagrantfile,andVagrantwillpassthisinformationtotherelevantprovisionersontheguestVM.

ProvisioningwithPuppetonVagrantVagrantsupportstwomethodsofusingPuppet:

PuppetinstandalonemodeusingthepuppetapplycommandontheVMPuppetinclient/servermode,wherebytheVM(usingthePuppetagent)willbeconfiguredfromacentralserver

Let’stakealookathowtoconfigureVagrantwithPuppetusingthesetwodifferentmethods.

UsingPuppetinstandalonemodePuppetstandaloneisthesimplestwaytousePuppetwithVagrant.WesimplytellVagrantwherewehaveputourPuppetmanifestsandmodules,andwhatmanifestshouldberun.ThesmallestamountofconfigurationweneedwithinourVagrantfileinordertousePuppetisthis:

config.vm.provision"puppet"do|puppet|

end

ThisshouldgowithintheVagrant.configure("2")do|config|…endblockofcodewithintheVagrantfile.

Alongwiththisconfiguration,wewillneedaPuppetmanifestcalleddefault.ppinthemanifestsfolderofourprojectroot.Vagrantwillthenusethistoprovisionthemachine.

ThiswillinstructVagranttorunthePuppetprovisionereitherwhenthemachinebootsupforthefirsttimeorifwerunthevagrantprovisioncommand.ThedefaultVagrantPuppetsetupwillmakethefollowingassumptions,unlessweoverridethesettings:

ManifestswillbelocatedinthemanifestsfolderModuleswillalsobelocatedinthemanifestsfolder(wemaywanttopointtheseelsewhere,especiallyifweareusingthird-partymodules,tokeepthemseparate)Themanifestfiletousewillbedefault.pp(Itwillobviouslybewithinthemanifestsfolder;itcanbeusefultooverridethisifweusePuppetmodulesandmanifestswithinthesameprojectformultipleenvironments.WemayhaveamanifestforourVagrantVM,oneforourproductionenvironmentandoneforauseracceptancetestingplatform,forexample.)

Wecanmodifytheseoptionsbyprovisioningconfigurationoptions,asopposedtojusttellingVagranttoprovisionwithPuppet.WhencreatingprojectsthataremanagedbyVagrant,Iliketoputallmyprovision-relatedfileswithintheprovisionfolder.Inordertooverridethese,withinthePuppetconfigurationforVagrant,wecanthenspecifyoptionsforthelocationofthePuppetmanifests(puppet.manifests_path),thenameofthePuppetmanifesttoapply(puppet.manifests_file),andthelocationofanyPuppetmodules,whichwemayreferencewithinourPuppetmanifest(puppet.module_path).Thefollowingcustomizestheseoptions:

config.vm.provision"puppet"do|puppet|

puppet.manifests_path="provision/puppet/manifests"

puppet.manifest_file="default.pp"

puppet.module_path="provision/puppet/modules"

end

Itisimportantforustohavetheabilitytoatleastchangethemanifestfile,asVagrantalsosupportsamulti-VMenvironment,whereasingleprojectcanhaveanumberofvirtualmachines(forexample,awebserverandadatabaseserver).Withthissetup,wewillneedtotellVagrantwhichmanifestfiletouseforeachofthemachines,sothatthewebservercanbeproperlyconfiguredasawebserverandthedatabaseserverasadatabaseserver.

PuppetprovisioninginactionWiththeknowledgewegainedofcreatingPuppetmodulesandmanifestsfromChapter3,ProvisioningwithPuppet,wecannowpointourVagrantconfigurationatthesefiles,andseeitinaction.IfwerunaVagrantfileonaproject,whichissuitablyconfigured,wewillseetheoutputofPuppetapplyingitssettingstoourvirtualmachineintheterminalwindow,asshowninthefollowingscreenshot:

TheconsoleoutputhighlightsdetailsofeachPuppetinstructionthatisrun,including:

Thestagetheinstructioniswithin(thisisthePuppetstage,aswediscussedinChapter3,ProvisioningwithPuppet,whichallowsustogroupclassestogethertocontroltheorderingofcertainactions)ThemoduleTheresourcetypeTheresourcenameWhethertheinstructionwasexecutedsuccessfully

UsingPuppetinclient/servermodeAsdiscussedearlier,wecanalsorunPuppetwithinourVagrantenvironmentinclient/servermodeusingthePuppetagentonthevirtualmachine.Theconfigurationrequiredforthisisminimal;wesimplytellVagranttheaddressofthePuppetserverweareusingandthenameofournode(thevirtualmachinewearesettingup):

config.vm.provision"puppet_server"do|puppet|

puppet.puppet_server="puppet.internal.michaelpeacock.co.uk"

puppet.puppet_node="vm.internal.michaelpeacock.co.uk"

end

ThenodenameisthereferenceforthemachinewithinthePuppetserver,sothePuppetserverknowshowourVMshouldbeconfigured.ThenodenameisalsousedtogenerateanSSLcertificatesothattheVMcanauthenticatewiththePuppetserver(moredetailsonthisareavailableonthePuppetwebsite,https://puppetlabs.com,andthePuppetblog,https://puppetlabs.com/blog/deploying-puppet-in-client-server-standalone-and-massively-scaled-environments.

ProvisioningwithAnsibleonVagrantInordertouseAnsiblewithinaVagrantproject,weneedtotellVagrantwheretheplaybookandinventoryfilesare:

config.vm.provision"ansible"do|ansible|

ansible.playbook="provision/ansible/playbook.yml"

end

Ansibleneedstoknowwhichmachinestoprovision;unlikewithotherprovisioners,wherethisisexplicitlyknownfromtheVagrantfileconfiguration,Ansibleusesaninventoryfiletoconfigurethis.TheinventoryfilecontainsalistofenvironmentnamesandIPaddresses;weusethisfiletorestrictwhichcommandsAnsiblerunsonspecificenvironments.Wecanomitthisfile,andVagrantwillgenerateoneforallofthevirtualmachinesitmanagesforusinthecurrentproject.

Wecanalsocreateourowninventoryfile.Ataminimum,itneedstoknowthenameofthevirtualmachine(fromourVagrantfile)andtheIPaddress.Toprovideonlythesetwopiecesofinformation,thisrequiresthevirtualmachinetoberunningonitsownIPaddress(pertheVagrantfilenetworkingconfiguration):

defaultansible_ssh_host=10.11.100.123

Alternatively,wecanprovidetheSSHporttouse,sothatAnsiblecanconnectfromourhostmachinetoourvirtualmachine:

defaultansible_ssh_host=127.0.0.1ansible_ssh_port=2222

TotellVagrantandAnsibleaboutourowncustominventoryfile,weneedtoaddittoourVagrantfileasfollows:

config.vm.provision"ansible"do|ansible|

ansible.playbook="provision/ansible/playbook.yml"

ansible.inventory_file="provision/ansible/inventory"

end

ProvisioningwithChefonVagrantVagrantalsosupportstwomethodsofusingChef:

Chef-soloChefinclient/servermodewithChefclient

Let’stakealookathowtoconfigureVagrantwithChefusingthesetwodifferentmethods.

UsingChef-soloChef-soloistheChefequivalentofPuppetstandalone.

ThesimplestwaytousethiswithinourprojectissimplytoprovideaChefrunlisttoVagrant;thistellsVagrantwhichcookbooksshouldbeapplied.ThefollowingisanexampleoftellingVagranttousethePHPcookbook:

config.vm.provision"chef_solo"do|chef|

chef.add_recipe"php"

end

ThistakesthePHPcookbookfromthedefaultcookbooksfolderandappliesittothevirtualmachine.

AswithPuppet,Vagrantmakessomeassumptionsbydefault;theyareasfollows:

Cookbooksarestoredinthecookbooksfolderwithintheprojectroot.Thechef.cookbooks_pathsettingallowsustooverridethecookbooksfolderlocation.Wecaneitherprovideasinglepathoranarrayofpaths(wrappedinsquarebrackets,separatedwithcommas)ifwewantVagrantandCheftolookinarangeoffoldersforourcookbooks.ThefollowingcodewillgointoourVagrantfiletotellVagranttooverridethecookbooksfolderwithprovision/cookbooks:

config.vm.provision"chef_solo"do|chef|

chef.cookbooks_path="provision/cookbooks"

end

WecanalsouseChefrolesbyproviding:

ThelocationoftherolesfolderTheroleswewishtoaddtotheVM

MoreinformationonChefrolescanbefoundontheOpscodewebsite(http://docs.opscode.com/essentials_roles.html).

ThefollowingcodeinourVagrantfilewillsetupourprojecttouseChefroles:

config.vm.provision"chef_solo"do|chef|

chef.roles_path="provision/roles"

chef.add_role("web")

end

UsingChefinclient/servermodeLikePuppet,Chefalsohasaclient/servermethodtoprovisionmachinesusingChefclientontheVM.TouseChefclient,weneedtotellVagrantwheretheChefserverislocated(throughthechef.chef_server_urlsetting),andprovidetheauthorizationkeythatwillbeusedtoauthenticatetheVMwiththeserver(throughthechef.validation_key_pathsetting).

ThefollowingcodeinourVagrantfilewillinstructVagranttoprovisionfromaChefserver:

config.vm.provision"chef_client"do|chef|

chef.chef_server_url="http://chef.internal.michaelpeacock.

co.uk:4000/"chef.validation_key_path="key.pem"

end

WecanalsooverridetherunlistthattheChefserverprovidesforourVMbymanuallyaddingrolesandrecipestothisconfiguration.IfwehavespecifieddifferentenvironmentsonourChefserver,wecanspecifywhichenvironmentwewanttousewiththechef.environmentconfiguration.

TipVagrantVMsthatuseChefserverwillhavethecorrespondingnodeandcliententriesontheChefserver,whichisnamedwiththehostnameoftheVM.IfwedestroytheVMandrecreateit,Chefwillgenerateanerrorbecausetheclientandnodeentriesarealreadypresentontheserver.WeneedtoremovethesefromtheChefserverwhenwedestroyaVM.ThiscanbedoneusingtheknifetoolfromChef,knifenodedeleteour-vm-hostname&&knifeclientdeleteour-vm-hostname.

ProvisioningwithSSH–arecapAswediscussedinChapter2,ManagingVagrantBoxesandProjects,wecaninstructVagranttorunaseriesofSSHcommandsontheVM.Thiscanbeusedtoprovisiontheserver.

TherearetwowaystouseSSHprovisioning:

Path:ThisprovidesafiletoexecuteInline:Thisisusedtoprovidespecificcommandstorun

Bothoftheseareshownasfollows:

config.vm.provision"shell",path:"provision/setup.sh"

config.vm.provision"shell",inline:"apt-getinstallapache2"

UsingmultipleprovisionersonasingleprojectWecanusemultipleprovisionerswithinasingleprojectifwewish;wesimplyneedtoputthemintheorderwewishforthemtobeexecutedwithinourVagrantfile.ThefollowingcommandwillfirstrunanSSHcommandbeforeprovisioningwithPuppet:

Vagrant.configure("2")do|config|

Config.vm.box="ubuntu/trusty64"

config.vm.provision"shell",inline:"apt-getupdate"

config.vm.provision"puppet"do|puppet|

puppet.manifests_path="provision/puppet/manifests"

puppet.manifest_file="default.pp"

puppet.module_path="provision/puppet/modules"

end

end

Usingmultipleprovisionerscanbeuseful,especiallyifoneismoresuitedatspecifictasksthananother,orifwerequiresomeprerequisites.Forexample,whenusingPuppetandChefinclient/servermode,theyneedtohaveanSSHkeytocommunicatewiththeserver.WecanuseashellprovisionertoinstructtheVMtodownloadthekeyswepreparedfromasecurelocation,beforethePuppetorChefprovisionerskickin.

OverridingprovisioningviathecommandlineTheremaybeinstanceswherewewanttorestrictorenforcetheexecutionofprovisioningorevenaspecificprovisionerwithinaproject.Thefollowingcommandsareallexecutedfromthehostmachine:

WecancancelarunningprovisionbypressingCMD+Cattheterminal.WecaninstructVagranttorerunprovisioningonaVMusingthevagrantprovisioncommand.Wecanalsoadd--no-provisiontotheupcommandtoinstructVagranttonotruntheprovisioningtoolswhenperformingtheupaction,forexample,vagrantup--no-provision.Bydefault,Vagrantwillonlyprovisionwhenitfirstbootsamachine.Forsubsequentbootsofanexistingmachine,Vagrantknowsthatthemachinesareconfigured,anditwillnotprovisionthem.Wecanoverridethiswiththe--provisionoption,forexample,vagrantup--provision.Wecanalsoprovisionwithjustaspecificprovisionershouldwewish,forexample,ifwewanttoinstructVagranttojustrunPuppetinstandalonemode(inaprojectthathasmultipleprovisionersconfigured),weneedtorunvagrantprovision--provision-with=puppet.

SummaryInthischapter,welearnedhowwecanapplyourknowledgeofPuppetandCheffromChapter3,ProvisioningwithPuppet,Chapter4,UsingAnsible,andChapter5,UsingChef,andconfigureVagranttousethesetoolstoprovisionourvirtualmachines.

WestartedoffbylearningtousePuppetinstandalonemodethatusesthepuppetapplycommandtoapplylocallystoredmanifestsandmodulesontothemachine.Then,wecontinuedusingPuppetintheclient/servermodethatusesthePuppetagenttoretrievetheconfigurationfromacentralservertoprovisionthemachine.

WethenlearnedhowtouseAnsibletorunplaybooksonspecificmachinesalongwiththefundamentalsofChef-solo,whichapplieslocallystoredcookbooksandrecipestothemachine.ItalsoincludedtheusageofChefinclient/servermode,whichusestheChefclienttoretrievetheconfigurationfromacentralservertoprovisionthemachine.

OtherstandardprovisionerswerealsocheckedusingSSHprovisioningandmultipleprovisioningoptionsforthesameproject.Finally,weroundedoffbyrunningmultipleprovisionerswithinasingleproject,overridingprovisioningonthecommandlineandrerunningtheprovisioningtoolswithvagrantprovision.

Now,wehavefullymasteredhowtosetup,use,andmanageVagrantalongwiththeprovisioningtoolstoworkonasinglemachineproject.InChapter7,WorkingwithMultipleMachines,wewilltakealookathowtouseVagrantandourknowledgeofprovisionerstomanageamultimachineproject,withprovisionersconfiguringdifferentmachinesfordifferentpurposesforusewithintheproject,forexample,awebserverandadatabaseserver.

Chapter7.WorkingwithMultipleMachinesSofar,wehaveseenhowwecangetVagranttoastagewhereourdevelopmentenvironmentiscontainedinVagrant-managedvirtualmachines,withoneofthekeyaspectsbeingthatthesevirtualmachinesmimicourproductionenvironment.Itgivesustheflexibilityofbeingabletoencapsulatethedevelopmentenvironmentfordifferentprojectssothatwecaneasilyswitchfromonetoanotherwithouthavingtomodifythesoftwareonourownmachines.

Inmanycases,thefeatureswelearnedsofarareenough.However,webprojectsarebecomingmoreandmorecomplex,withdeveloperscontinuallyimproving,havingtodealwithmultiplemachinesintheirarchitecturetohelpwithscalabilityandstability.Whileitcanbesaidthatscalabilityandstabilityissueswon’timpactourdevelopmentenvironment(aswewon’thavehugeamountsoftrafficcomingtoourdevelopmentenvironment,unlessweload-testit),wewanttoensurethatthecouplingbetweenserverswithinourcode(suchasapplicationcodeconnectingtoaremotedatabase)worksinourdevelopmentenvironmentbeforeweputtheprojectonline.

Thankfully,Vagranthassupportforrunningmultiplevirtualmachinesatthesametimewithinthesameproject.Wecanusethistotestmultimachinearchitecturesanddistributedsystemsonourownlocalmachinebeforeweshareourchangeswithcolleaguesinastagingenvironment,andbeforetheprojectgoeslive.Replicatingamultimachineenvironmentindevelopmentgreatlyhelpsusimprovethereliabilityofourprojectsandinstillsconfidenceintheworkthatwedo.

Inthischapter,wewilllearnthefollowingtopics:

HowtorunmultiplevirtualmachineswithinasingleVagrantprojectHowtoprovidedifferentdistinctconfigurationtothesevirtualmachines,includingthefollowing:

NamesIPaddressesonaprivatenetworksothattheycancommunicatewithoneanotherBaseboxesProvisioningSharedfolders

HowtoconnecttothedifferentvirtualmachinesoverSSHwithouthavingtoknoworremembertheirIPaddresses

UsingmultiplemachineswithVagrantInordertousemultiplevirtualmachineswithinourproject,weneedtotellVagrantaboutthem,andweneedtoprovideadditionalconfigurationfortheindividualvirtualmachines.

DefiningmultiplevirtualmachinesWithinthestandardVagrantprojectconfigurationfile,wecantellVagrantthatwewishtoassignanametoavirtualmachinebeingmanagedbytheproject.Withinthissubconfiguration,weprovidetheinformationVagrantneedsthatisspecifictothatVM.

Thesyntaxforthesubconfigurationsisasfollows:

config.vm.define:name_of_the_vmdo|name_of_the_vm|

#configurationspecifictothevirtualmachine

end

Thisisappliedtoaprojectthatrequirestwovirtualmachines,namedserver1andserver2,bothrunningtheprecise64box:

#-*-mode:ruby-*-

#vi:setft=ruby:

VAGRANTFILE_API_VERSION="2"

Vagrant.configure(VAGRANTFILE_API_VERSION)do|config|

config.vm.define:server1do|server1|

server1.vm.box="hashicorp/precise64"

end

config.vm.define:server2do|server2|

server2.vm.box="hashicorp/precise64"

end

end

ConnectingtothemultiplevirtualmachinesoverSSHWhenourmultiplemachinesbootupinourmultimachineproject,VagrantautomaticallymapsdifferentportsfromourhostmachinetotheSSHportsonthevariousguestmachines.

Let’stakealookattheconsoleoutputwhenbootingaVagrantprojectwithtwovirtualmachineswithinit:

Asshownintheprecedingscreenshot,VagrantmapstheSSHportonthevirtualmachinedesignatedserver1toport2222onthehostmachine,andtheSSHportofthemachinedesignatedserver2totheport2200.

ThisgivesustheopportunityofsimplyusingthestandardSSHcommandfromaterminal(orthelikesofPuTTYonaWindowsmachine),toconnecttolocalhostwiththeportnumberthatVagrantassignstoeachmachine.

Toconnecttothemachinethatismappedtoport2200,wesimplyrunthesshvagrant@localhost–p2200command.The–p2200optiontellsthecommandtouseanonstandardport,andspecifiestheportwewishtouse,inthiscase2200.

Alternatively,wecanusethevagrantsshcommandtoconnecttothevirtualmachines.Thedifferenceisthatinamultivirtualmachineenvironment,wemustalsoprovidethenameofthevirtualmachine.Forexample,vagrantsshserver1.Thisisthemostcommonusageofconnectingtoamachine,ratherthandirectlyconnectingtothevirtualmachineviaitsIPaddress.

NetworkingthemultiplevirtualmachinesInasinglevirtualmachineproject,theIPaddressofthevirtualmachineisn’tthatimportant.Inamultivirtualmachineproject,however,itismorelikelythatwewantthetwomachinestocommunicatewithoneanotherdirectly;inordertodothis,weneedtobeawareoftheirIPaddresses,orweneedtoforwardnonconflictingportstothelocalhostinstead.AswewanttohaveourVagrantprojectsdistributedtoourteammembers,andsomeoftheseteammembersmaybewithinthesameoffice,weneedto:

PredefinetheIPaddresssothatanyofourprojectscodethatneedstocommunicatewiththeothervirtualmachinecandoso,withouttheotherteammembersneedingtochangeconfigurationsEnsurethatthevirtualmachinesarerunningonaprivatenetworkonlythatareattachedtothemachineoftheuserrunningit;thiswillpreventtheIPaddressconflictswithinthenetwork

Inordertodothis,wesimplyusethenetworkingoptions,whichwelearnedinChapter2,ManagingVagrantBoxesandProjects.Becausewewantthevirtualmachinestoruninaprivatenetwork,itmakessensetousearangeofprivateIPaddresses,whicharedifferenttoyourownnetwork.Forexample,mynetworkrangeis192.168.1.xxx,soIwillusetherange10.11.1.xxxformyvirtualmachinenetwork(theIPaddressrangesareasubsetoftherangeofaddressespreassignedforinternalnetworks),asshowninthefollowingcode:

#-*-mode:ruby-*-

#vi:setft=ruby:

VAGRANTFILE_API_VERSION="2"

Vagrant.configure(VAGRANTFILE_API_VERSION)do|config|

config.vm.define:server1do|server1|

server1.vm.box="hashicorp/precise64"

server1.vm.network"private_network",ip:"10.11.1.100"

end

config.vm.define:server2do|server2|

server2.vm.box="hashicorp/precise64"

server2.vm.network:private_network,ip:"10.11.1.101"

end

end

Let’stestthisoutandtestwhetherwecanconnectfromonemachinetotheother:

1. Poweruptheproject(vagrantup).2. Connecttoserver1(vagrantsshserver1).3. Pingserver2fromserver1(ping10.11.1.101).

Theoutputshowsthatweareabletocommunicateoverthenetworkfromserver1toserver2asfollows:

ProvisioningthemachinesseparatelyAsthevirtualmachinesinourprojectsaregoingtobeusedfordifferentpurposes,weneedtousedifferentprovisioningforthemachines,sotheybothhaveonlythesoftwareandconfigurationsneededtodotheirjob.

Wetaketheprovisioningcode,whichwelearnedinChapter3,ProvisioningwithPuppet,andChapter6,ProvisioningVagrantMachineswithPuppet,Ansible,andChef,andweplacetherelevantcodewithinthevirtualmachine’ssubconfiguration.Therearesomekeychangesthatweneedtomake:

TheopeninglineoftheprovisioncodemustreferencetheservernameofthevirtualmachineitrelatestoForPuppet,weshoulduseadifferentmanifestfileforthetwovirtualmachinesForChef,wewillapplydifferentrolestothedifferentmachines

ThefollowingcodeprovisionsboththemachinesusingPuppet.TheybothrelyonthesamesetofPuppetmodules,thesamepaththatpointstothemanifestsfolder,however,theybothusedifferentmanifeststosetuptheprojects(alternatively,wecanconfigurethemachinesandidentifythemasnodestoaPuppetmastertoretrievetheappropriateconfiguration):

#-*-mode:ruby-*-

#vi:setft=ruby:

VAGRANTFILE_API_VERSION="2"

Vagrant.configure(VAGRANTFILE_API_VERSION)do|config|

config.vm.define:server1do|server1|

server1.vm.box="hashicorp/precise64"

server1.vm.network"private_network",ip:"10.11.1.100"

server1.vm.provision:puppetdo|puppet|

puppet.manifests_path="provision/puppet/manifests"

puppet.manifest_file="server1.pp"

puppet.module_path="provision/puppet/modules"

end

end

config.vm.define:server2do|server2|

server2.vm.box="hashicorp/precise64"

server2.vm.network:private_network,ip:"10.11.1.101"

server2.vm.provision:puppetdo|puppet|

puppet.manifests_path="provision/puppet/manifests"

puppet.manifest_file="server2.pp"

puppet.module_path="provision/puppet/modules"

end

end

end

Withintheprovisionsforeachmachine,wewouldneedtoensurethatweallowboththemachinestocommunicatewithoneanother.Forexample,bydefault,aMySQLServerwon’tacceptconnectionsfromaremoteserver,sowewouldneedtomodify(orreplace)theconfigurationfilewithonethatallowsthis,orwewouldneedtouseaPuppetmoduleorChefcookbookthatallowsustomodifythisconfigurationvalue.

TipYoushouldcheckthedocumentationforanysoftwareyouarecommunicatingwithoverthenetworktoseehowitneedstobeconfigured.WithMySQL,youneedtoeditthemy.cnffile,andsetthebindaddressto0.0.0.0.

DestroyingamultimachineprojectIfwewanttocompletelyremovethevirtualmachinesforourprojectfromourhostmachine,wecanusethevagrantdestroycommand,aswithnormalprojects.ThedifferencebeingthatVagrantwillaskustoconfirmtheremovalofeachmachinewithintheproject:

SummaryInthischapter,wesetupaVagrantprojectthatusesmultiplevirtualmachines.Duringthecourseofthischapter,welearnedhowtocreatemultiplevirtualmachineswithinasingleproject.Inordertoachievethis,wealsolookedathowtoassignspecificnamestotheseindividualmachines,howtoconnecttotheindividualmachinesoverSSH(aspreviouslyvagrantsshwouldtakeustojustasinglemachine),andhowtoconfiguretheindividualmachines,specifyingIPaddresses,baseboxes,anddifferentprovisioningoptionsforthem.

Now,welearnedthevastmajorityofVagrant’sfunctionalityandhowtouseitwithindifferentprojectscenarios.Inthenextchapter,wewilltakealookathowtobuildourowncustombaseboxtousewithourprojects,configuringablankoperatingsysteminstallationintoacompatiblebaseimage.

Chapter8.CreatingYourOwnBoxSofar,wehaveusedVagrantwiththefreelyavailablebaseboxes.TherearealsomanyotherexistingbaseVagrantboxesoutthere.InChapter9,HashiCorpAtlas,wewilltalkabouthowwecandiscoveranddistributebaseboxes.WhenwediscussedVagrantboxesinitiallyinChapter1,GettingStartedwithVagrant,andChapter2,ManagingVagrantBoxesandProjects,welearnedabouthowwecanexportaVagrantenvironmentintoanewbasebox.

Creatinganewbaseboxinvolvesuseithertakinganexistingbox,makingchangestoit,andexportingit,orcreatinganewvirtualmachineentirely,installingtheoperatingsystemandbuildingupabaseboxforexport.Inthischapter,wewilltakealookathowwecantakeaLinuxinstallationdiskandturnitintoaworkingVagrantbasebox,whichwecanfurthercustomizeasmuchaswelike.

Inthischapter,youwilllearnaboutthefollowingtopics:

HowtocreateanewVirtualBoxmachine,suitablyconfiguredforVagrantHowtoinstalltheVirtualBoxGuestAdditionsHowtosetuptheLinuxinstallationtoletVagrantloginHowtoinstallPuppetHowtoinstallChefHowtocleanuptheboxHowtoexporttheVMintoabasebox

GettingstartedInordertocreateanewbasebox,weneedtodownloadacopyoftheoperatingsystemwewanttouse(wewilluseUbuntuServerVersion13.0464-bitfromhttp://releases.ubuntu.com/raring/).WethenneedtouseVirtualBoxtocreateavirtualmachine,poweredbytheoperatingsystemwehavedownloaded.Next,weneedtoconfigurethevirtualmachineforVagrant.Finally,weneedtoexportthevirtualmachineintoaVagrantbasebox.

TipYoucanalsouseotherdistributionsofLinuxorevenWindowsifyouwish.Specificswillvarywiththeoperatingsystemused,soyouwillneedtoconsulttherelevantdocumentation.

TherequirementsforanewbaseboxaredetailedontheVagrantwebsite(https://docs.vagrantup.com/v2/boxes/base.html).

PreparingtheVirtualBoxmachineInordertocreatethevirtualmachinewithVirtualBox,weneedtoopentheVirtualBoxandclickontheNewbuttonintheupper-leftcorneroftheVirtualBoxtostarttheprocess:

Let’snamethemachinevagrant-ubuntu-raring.ThisistheformatrecommendedbyVagrant.SelectLinuxintheTypedropdownandVersionasUbuntu(64bit):

Vagrantrecommendssettingamemoryallocationof360MB.Thisistypicallysufficientforabaseinstallation,anduserscanoverridethiswithintheirVagrantfileiftheyneedmoreresources:

Weneedourvirtualmachinetohavesomestorageallocation,solet’sselectCreateavirtualharddrivenow:

WeneedtoselectVMDK(VirtualMachineDisk)asthedisktype:

Weneedtocreateadrive,whichisdynamicallyallocated:

Let’sgivethedriveamaximumlimitof40.00GB;theVagrantdocumentationsuggeststhatthisistypicallysufficientformanyprojects:

ClickingonCreatewillthensavethevirtualmachinewithinVirtualBox.Weneedtomakesomeadditionalconfigurationchanges,whicharenotapartofthecreationwizard,solet’sclickontheVMontheleft-handsideofthescreen,andthenclickontheSettingsbutton:

ThefirstadditionalchangeisAudio,solet’sturnthisoff:

WeneedtoensurethatthenetworkadapterconfiguredwithinVirtualBoxisenabledandusesNAT.Withoutthis,Vagrantwon’twork:

Finally,let’sturnoffUSBsupport,asthisisgenerallynotrequired:

Nowweneedtoswitchonthevirtualmachine.Whenitpowerson,itasksustoselectastartupdisk,whichcontainstheoperatingsystemwewishtoinstall.Clickingonthefoldericononthisscreenletsusselectacustomfile;inourcase,thiswillbeourubuntu-13.04-server-amd64.isofile.

Thevirtualmachinewillthenbootfromtheimagefileandtakeustotheinstallationprocess.Weshouldfollowthisprocesstosetupthemachine.

TherearesomespecificvaluesforsomethingsthatVagrantexpects,sowhereverappropriateweshouldensurethatwesetthemasfollows:

Byconvention,theoperatingsystem’shostnameshouldbeofthevagrant-operating-system-nameformat,forexample,vagrant-ubuntu-raringThedomainisvagrantup.comTherootpasswordisvagrantThemainaccountusernameisvagrantThemainaccountpasswordisvagrant

Inmostothercases,thedefaultoptionswillbefine,aswewillconfigureotheraspectslater.Whenpromptedastoanypackagestoinstallbydefault,weshouldselecttoinstallopenssh-server.

VirtualBoxGuestAdditionsFirst,let’slogintoournewvirtualmachinewithinVirtualBox.Onceloggedin,attheterminal,weshouldrunapt-getupdatetoupdateourpackagemanager.

VagranthasasetoftoolscalledGuestAdditionsthatprovidesomekeyintegrationpointsbetweenthevirtualmachineandVirtualBox;thisincludessupportforsharedfoldersandnetworkingintegration.

Toinstallthesetools,oncetheVMisrunning,weshouldclickontheDevicesmenuwithinVirtualBoxandclickonInstallGuestAdditions…(Host+D):

ThissimplybootsavirtualCDwithinthevirtualmachine;westillneedtoactuallyinstalltheGuestAdditions,asfollows:

1. Thefirststepistoinstallaprerequisite,whicharetheLinuxheaders:

sudoapt-getinstalllinux-headers-$(uname-r)build-essential

2. Next,wewillmountthevirtualCD,whichVirtualBoxhasloadedupintoafolderwithintheVM:

sudomount/dev/cdrom/media/cdrom

3. Finally,wewillruntheinstallationcommand:

sudosh/media/cdrom/VBoxLinuxAdditions.run

VagrantauthenticationVagrantcommunicateswithbaseboxesoverSSH.Vagrantitselfhasaprivatekey,forwhichweneedtoinstallthecorrespondingpublickeyintothevirtualmachine.Vagrantexpectsaspecificuserwithapredefinedpasswordtoalsobewithinthemachine,andtheuserneedstobeconfiguredsothatitisn’tpromptedforthepasswordwhenattemptingtoperformactionsthatrequireelevatedprivileges(sudo).

VagrantuserandadmingroupProvidedwecreatedtheVagrantuserduringtheinstallationprocess(asperthemainaccountuserandpasswordmentionedearlier),wethenneedtocreateanadmingroupandaddtheVagrantusertothisgroup.

First,weneedtocreatethegroup:

Sudogroupaddadmin

ToaddtheVagrantusertothisgroup,runthefollowingcommand:

Sudousermod-a-Gadminvagrant

ThesudoersfileInordertostopthevirtualmachineaskingfortheuser’spasswordwhenrunningelevatedactions,weneedtomodifythesudoersfile.Thisisafilethattellstheoperatingsystemwhichuserscanperformelevatedactionsandthesettingsaroundthem.Moreinformationcanbefoundathttps://help.ubuntu.com/community/Sudoers.Weneedtoaddaconfigurationlinetothisfile,whichtellstheoperatingsystemnottopromptforthepassword.Becausethefileisveryimportant,andanincorrectconfigurationwouldbreaktheoperatingsystem,thereisaprogrambuiltintoUbuntu,whichwon’tsaveifthefileisnoteditedcorrectly.

First,let’srunthisprogram:

visudo

Atthebottomofthefile,let’saddthislinetopreventtheoperatingsystemfrompromptingforthepassword:

%adminALL=(ALL)NOPASSWD:ALL

AnotherrequirementofVagrantisthatweaddthefollowinglinenearthetopofthefile:

Defaultsenv_keep="SSH_AUTH_SOCK"

Wealsoneedtodisablerequirettyinthesudoersfilebycommentingouttheappropriatelineasfollows:

#Defaultrequiretty

Tiprequirettyisanoptionthatrequiresuserstohaveaphysicalconnectiontoaserverinordertorunthesudocommands.

Insecurepublic/privatekeypairTheinsecurepublicandprivatekeypairispubliclyavailableathttps://github.com/mitchellh/vagrant/tree/master/keys/.

TipAnupcomingversionofVagrantwillchangehowVagrantworkswiththeseinsecurekeys.Whendetected,theywillbereplacedwithnewkeysforyourmachine;however,attimeofwriting,thishasnotyetbeenreleased.

Weneedtocopythecontentsofthepublickeyandpasteitintotheauthorized_hostsfile.ProvidedweareloggedinastheVagrantuser,wecanrunthefollowingcommandtoletuseditthisfile:

nano~/.ssh/authorized_hosts

Ifthe.sshfolderdoesnotalreadyexist,wefirstneedtocreateitusingthemkdircommand.Alternatively,wecandownloadthefilecontentsandputitstraightintotheauthorized_hostsfile:

wget

https://raw.github.com/mitchellh/vagrant/master/keys/

vagrant.pub–O~/.ssh/authorized_hosts

NoteThe.sshdirectoryneedstohavepermissionsof0700,andtheauthorized_hostsfileneedstohavepermissionsof0644(chmod0644~/.ssh/authorized_keys).

ProvisionersBecauseVagrantprovidessupportforprovisioners,weshouldinstalltheseintothevirtualmachinesothatVagrantcantellthemtoprovisionourenvironments.

InstallingPuppetPuppetisinstalledusingthebuilt-inpackagemanager:

sudoapt-getinstallpuppet

TipTheversionofPuppetinthevariousoperatingsystemrepositoriesmaybeslightlydated.PuppetcanalsobeinstalledmanuallyorviatherepositorysiteprovidedbyPuppetLabs.MoreinformationisavailableonthePuppetlabswebsiteathttp://docs.puppetlabs.com/guides/installation.html.

InstallingChefAspertheChefdocumentationathttps://www.chef.io/download-chef-client/,wecangetasinglecommandtoinstallChefforus:

curl-Lhttps://www.chef.io/chef/install.sh|sudobash

CleaninguptheVMBeforewepackageupthevirtualmachineintoaVagrantbasebox,let’scleanupsomeofthefilesweused.Wemadeuseofthetmpfolder,solet’semptythis.Weshouldalsocleanupourpackagemanager’scache,asthisusesadditionalspacewhenthebaseboxispackaged:

rm–rf/tmp/*

sudoapt-getclean

ExportFinally,weuseVagrant’spackagesubcommandonthehostmachine(nottheguest)topackageupthebox:

vagrantpackage--basevagrant-ubuntu-raring

ThecompletedetailsofthepackagesubcommandareavailableontheVagrantwebsite(http://docs.vagrantup.com/v2/cli/package.html).

SummaryInthischapter,welearnedhowtocreate,abaseboxforourVagrantprojectsfromscratch.Thiscanbeusedtocreatebaseboxesfromoperatingsystems,whichdon’tnecessarilyhaveboxesavailabletodownload.

Now,weknowhowtocreate,manage,distribute,andevenbuilddevelopmentenvironmentsfromscratchforourprojects!

Next,wewilltakealookatVagrantCloud,whichletsussearchforanddiscoverdifferentbaseboxesaswellaslettingusdistributeourownbox—eithertothepublicortoaprivateteam.VagrantCloudalsohasthefunctionalitytoallowustoshareourVagrantdevelopmentenvironmentwithothers—bethattodemonstratethefunctionalitywehavebuiltonaVagrant-supportedproject,ortoprovideSSHaccesstoateammemberwhocanhelpuswithsupportissues.

Chapter9.HashiCorpAtlasHashiCorpAtlas(https://atlas.hashicorp.com),formerlyVagrantCloud,isasuiteofonlineservicesprovidedbyHashiCorp(thecommercialcompanybehindVagrant),whichaddsadditionalcapabilitiestoVagrantandbringstogethermanyoftheiropensourcecomponents.Primarily,Atlassupportstwofeatures:

VagrantShare:TheabilitytoshareaccesstoyourVagrantenvironmentandtoallowotherstoremotelyconnecttoitVagrantboxdiscoveryandsharing:TheabilitytoshareVagrantboxeswithothers,hostingthemetadataforboxes,theirversions,andfacilitatingboxupdates

Thesefeaturesareavailablefreeofcharge,thoughpayingcustomerscangainaccesstoadditionalfunctionality,includingthefollowing:

CustomandstaticdomainnamesforVagrantSharePrivateboxesthatcanbesharedwithspecificteamsprivatelyBoxhosting:VagrantCloudwillactuallystoretheboxfileontheirplatformaswellasthemetadataSupportforWindowsandMacVagrantboxesGranularsupportforuseraccesscontrols

Inthischapter,youwilllearnaboutthefollowingtopics:

HowtodiscoveranduseboxesprovidedonAtlasHowtodistributeyourownboxesonAtlasHowtoallowotherstoconnecttoyourVagrantmachinethroughAtlasHowtoshareyourVagrantmachinethroughAtlas

DiscoveringboxesTheAtlaswebsitecontainsadirectoryofpublicboxesforVagrant(https://atlas.hashicorp.com/boxes/search).Withinthisdirectory,wecansearchforthespecificoperatingsystemordistributionversionthatweareinterestedin:

Foreachresult,wecanseetheboxname,whichisformattedasthenameofthedistributorfollowedbyaslash,followedbythenameordistributionname.Inthefollowingcase,wehavetheUbuntu12.04LTSreleasethatHashiCorphasprovided(namedhashicorp/precise64):

Ifweclickinabox,wecanseewhichproviderstheboxsupports.Inthiscase,wecanusetheboxwithVirtualBox,VMwareFusion,andHyper-V.Itisimportanttouseboxesthatsupporttheproviderweareusing—notallboxessupportallproviders.

InstallingnewboxesToinstallapublicbox,weusethevagrantboxaddcommand,andpassthenameofthebox:

vagrantboxaddhashicorp/precise64

ThenameoftheboxcaneitherbeaURLorfilepathtoanexistingboxfile(forexample,ifwehaveonestoredonournetworkthatwewishtouse)oranAtlasboxname,likeintheprecedingcommand.

UpdatingexistingboxesOneofthekeybenefitsofusingAtlasforboxdiscoveryisthatchangesandversionsoftheseboxescanbemanaged.Ifaparticularboxcontainsabugorsecurityvulnerability,distributorsmayupdatetheirboxestofixtheseissues,orcontainnewfunctionality.Thiscanbeuseful,asitsavesustheneedtoupdateourprovisioningconfigurationtomaketheseupdates.

WheninaVagrantprojectsfolder,wecanrunthefollowingcommandtocheckforupdatesfortheprojectsboxandupdateit:

vagrantboxupdate

Thiswilldownloadthenewbox;however,wewon’tseetheeffectofthenewboxunlesswedestroyourVagrantmachineandrebuilditfromtheupdatedbox.

Ifwewanttoupdateaspecificbox,asopposedtotheonethatistiedtotheprojectwearein,wecanusetheboxflagtoprovidethenameoftheboxwewanttoupdate:

vagrantboxupdate--boxthe-box/name

CheckingforoutdatedboxesWecanquicklychecktoseewhetheranyoftheboxesweinstalledareoutofdate,byrunningthefollowingcommand:

vagrantboxoutdated--global

Ifweomittheglobalflag,thenthecommandisonlywithinthecontextofthecurrentVagrantprojectwiththeflagitrelatestoallboxesinstalled:

DistributingboxesTodistributeboxeswithAtlas,weneedtocreateanaccountandlogintotheAtlaswebsite(https://atlas.hashicorp.com/account/new).Theusernamethatweselectwhenregisteringisusedastheprefixforboxeswedistribute—unless,ofcourse,wegoontoapaidplan,whichhasorganizationalsupport,orwecollaboratewithothersonabox.Onceloggedin,weneedtoclickontheCreateBoxlinktogototheboxcreationform(https://atlas.hashicorp.com/boxes/new).

Onthispage,weneedtoprovideanameanddescriptionforourbox.Asweareonthefreeplan,wecannotmakethisaprivatebox,soitwillbemadepublic:

AstheboxesdistributedthroughAtlascanbeversioned,toletusrolloutnewupdatestousersofthebox,weneedtocreateaninitialversionforthebox,alongwithadescriptionofwhattheversioncontains:

Next,weneedtoclickonCreatenewprovidertoaddanewproviderthatissupportedbythisversionofthebox:

Finally,wespecifytheprovider,andprovideaURLtowheretheboxcanbedownloaded.WiththefreeversionofAtlas,weneedtoprovidealinktothebox,asthereisnostorageallowanceforVagrantCloudtohostthefileforus:

Onceaboxhasbeencreatedandpublished,itcanbediscoveredandinstalled,aswediscussedintheDiscoveringboxessection,bythepublic,orbyususingthenameoftheboxinourVagrantfile,forexample,mkpeacock/testbox.

SharingandconnectingwithAtlasWithAtlas,therearethreenewVagrantcommandsatourdisposal,whichareasfollows:

vagrantconnect

vagrantshare

vagrantlogin

LoggingVagrantintoVagrantCloudInordertoshareourVagrantenvironment,weneedtoconnectourVagrantinstallationtoourVagrantCloudaccount.Wecanchecktoseewhetherthisisalreadythecasebyrunningthefollowingcommand:

vagrantlogin--check

Thiswillchecktoseewhetherwearealreadyloggedin:

Aswearenotloggedin,weneedtorunvagrantlogininordertologin.First,wearepromptedforourusernameore-mailaddressfromAtlas,andthenforourpassword:

Onceloggedin,wecanusethelogoutflagtologoutofAtlas:

vagrantlogin--logout

SharingaVagrantvirtualmachineoverHTTP(S)InordertosharethewebinterfacewithaVagrantvirtualmachine,thevirtualmachinemusteitherhaveitsownIPaddressonourlocalnetworkoranHTTP(S)portforwardedfromtheguesttothehostmachine.Vagrantrequiresthissothatyourhostmachinecanconnecttotherelevantportonyourvirtualmachine.

ProvidedwehaveeithergiventhevirtualmachineitsownnetworkaddressorforwardaporttoarecognizableHTTP(S)port,thenwecanrunthevagrantsharecommandtocreateapublicURLforthismachine.WecanalsospecifytheHTTPandHTTPSportsthatweareusingonthevirtualmachineifVagrantdoesn’tdetectthemwiththe--httpand--httpsflags:

Afterrunningvagrantshare,VagrantwillgenerateanameandURLtoaccessthesharefrom.Asweareonafreeplan,wecannotcustomizeorreserveURLs.Ourterminalsessionisnowlockedtorunthissharingsession,soweneedtoleavethisrunning.IfwevisittheURLinabrowser,weshouldbeabletoseewhateverwebservicewearerunningonourvirtualmachine:

Tostopsharing,weneedtoclosetheterminalorstopthevagrantsharecommandfromrunning:

SharingandconnectingtoaVagrantvirtualmachineBydefault,vagrantshareonlysharesHTTP(S)traffic.Wecan,however,passthe--sshflagtoalsoshareSSHaccessthatwillallowotherVagrantuserstoconnecttothemachine:

vagrantshare--ssh

Afterrunningthiscommand,wewillbepromptedtoprovideandconfirmapasswordtobeusedtoencrypttheSSHkeysothattheusersarerequiredtoprovideapasswordwhentheyconnect.Ifrequired,thiscanbeomittedwiththe--ssh-no-passwordflaginsteadof--ssh.WecanalsomakeasingleuseSSHconnectionwith--ssh-once,asshowninthefollowingscreenshot:

Aswitharegularsharecommand,wegetaURLandaname.WecanpreventHTTP(S)frombeingsharedbypassingthe--disable-httpflag.

Oncethesharingprocessisrunning,wecanprovidethenameandpasswordtowhomeverwewanttobeabletoconnecttothemachine.Theysimplyrunthevagrantconnect--sshdifficult-elephant-4464command(wherethelastparameteristhenameoftheconnectiongeneratedbyAtlas)tostartaconnectionwiththemachine,andprovidethepasswordwhenprompted:

TheuseristhenloggedintotheVagrantmachine!

SummaryInthischapter,welearnedabouttheextrafunctionalityofferedbytheVagrantCloudservice.

Wediscoveredhowtofindthird-partyVagrantboxesforusewithourprojects,howtocheckforupdatesforboxesthatuseAtlas,andhowtodistributeourownbaseboxesthroughAtlas.Finally,welookedatauthenticatingwithAtlastoshareourVagrantenvironmentwithourcolleagues.

NowthatweknowmoreaboutthefunctionalityofferedbyVagrant,wecanuseiteffectivelyinourprojects!

AppendixA.ASampleLEMPStackNowthatwehaveagoodknowledgeofusingVagranttomanagesoftwaredevelopmentprojectsandhowtousethePuppetprovisioningtool,let’stakealookathowtousethesetoolstobuildaLinux,Nginx,MySQL,andPHP(LEMP)developmentenvironmentwithVagrant.

Inthisappendix,youwilllearnthefollowingtopics:

HowtoupdatethepackagemanagerHowtocreateaLEMP-baseddevelopmentenvironmentinVagrant,includingthefollowing:

HowtoinstalltheNginxwebserverHowtocustomizetheNginxconfigurationfileHowtoinstallPHPHowtoinstallandconfigureMySQLHowtoinstalle-mailsendingservices

WiththeexceptionofMySQL,wewillcreatesimplePuppetmodulestoinstallandmanagethesoftwarerequired.ForMySQL,wewillusetheofficialPuppetmodulefromPuppetLabs;thismodulemakesitveryeasyforustoinstallandconfigureallaspectsofMySQL.

CreatingtheVagrantprojectFirst,wewanttocreateanewproject,solet’screateanewfoldercalledlemp-stackandinitializeanewubuntu/trusty64Vagrantprojectwithinitbyexecutingthefollowingcommands:

mkdirlemp-stack

cdlemp-stack

vagrantinitubuntu/trusty64ub

TheeasiestwayforustopullintheMySQLPuppetmoduleistosimplyadditasagitsubmoduletoourproject.Inordertoaddagitsubmodule,ourprojectneedstobeagitrepository,solet’sinitializeitasagitrepositorynowtosavetimelater:

gitinit

Tomakethevirtualmachinereflectiveofareal-worldproductionserver,insteadofforwardingthewebserverportonthevirtualmachinetoanotherportonourhostmachine,wewillinsteadnetworkthevirtualmachine.Thismeansthatwewouldbeabletoaccessthewebserverviaport80(whichistypicalonaproductionwebserver)byconnectingdirectlytothevirtualmachine.

InordertoensureafixedIPaddresstowhichwecanallocateahostnameonournetwork,weneedtouncommentthefollowinglinefromourVagrantfilebyremovingthe#fromthestartoftheline:

#config.vm.network"private_network",ip:"192.168.33.10"

TheIPaddresscanbechangeddependingontheneedsofourproject.

AsthisisasampleLEMPstackdesignedforweb-basedprojects,let’sconfigureourprojectsdirectorytoarelevantwebfolderonthevirtualmachine:

config.vm.synced_folder".","/var/www/project",type:"nfs"

Wewillstillneedtoconfigureourwebservertopointtothisfolder;however,itismoreappropriatethanthedefaultmappinglocationof/vagrant.

BeforewerunourPuppetprovisionertoinstallourLEMPstack,weshouldinstructVagranttoruntheapt-getupdatecommandonthevirtualmachine.Withoutthis,itisn’talwayspossibletoinstallnewpackages.So,let’saddthefollowinglinetoourVagrantfilewithinthe|config|block:

config.vm.provision"shell",inline:"apt-getupdate"

AswewillputourPuppetmodulesandmanifestsinaprovisionfolder,weneedtoconfigureVagranttousethecorrectfoldersforourPuppetmanifestsandmodulesaswellasthedefaultmanifestfile.AddingthefollowingcodetoourVagrantfilewilldothisforus:

config.vm.provision:puppetdo|puppet|

puppet.manifests_path="provision/manifests"

puppet.module_path="provision/modules"

puppet.manifest_file="vagrant.pp"

end

CreatingthePuppetmanifestsLet’sstartbycreatingsomefoldersforourPuppetmodulesandmanifestsbyexecutingthefollowingcommands:

mkdirprovision

cdprovision

mkdirmodules

mkdirmanifests

Foreachofthemoduleswewanttocreate,weneedtocreateafolderwithintheprovision/modulesfolderforthemodule.Withinthisfolder,weneedtocreateamanifestsfolder,andwithinthis,ourPuppetmanifestfile,init.pp.Structurally,thislookssomethinglikethefollowing:

|--provision

||--manifests

||`--vagrant.pp

|`--modules

||--ourmodule

||--manifests

|`--init.pp

`--Vagrantfile

InstallingNginxLet’stakealookatwhatisinvolvedtoinstallNginxthroughamoduleandmanifestfileprovision/modules/nginx/manifests/init.pp.First,wedefineourclass,passinginavariablesothatwecanchangetheconfigurationfileweuseforNginx(usefulforusingthesamemodulefordifferentprojectsordifferentenvironmentssuchasstagingandproductionenvironments),thenweneedtoensurethatthenginxpackageisinstalled:

classnginx($file='default'){

package{"nginx":

ensure=>present

}

TipNotethatwehavenotclosedthecurlybracketforthenginxclass.Thatisbecausethisisjustthefirstsnippetofthefile;wewillcloseitattheend.

BecausewewanttochangeourdefaultNginxconfigurationfile,weshouldupdatethecontentsoftheNginxconfigurationfilewithoneofourown(thiswillneedtobeplacedintheprovision/modules/nginx/filesfolder;unlessthefileparameterispassedtotheclass,thefiledefaultwillbeused):

file{'/etc/nginx/sites-available/default':

source=>"puppet:///modules/nginx/${file}",

owner=>'root',

group=>'root',

notify=>Service['nginx'],

require=>Package['nginx']

}

Finally,weneedtoensurethatthenginxserviceisactuallyrunningonceithasbeeninstalled:

service{"nginx":

ensure=>running,

require=>Package["nginx"]

}

}

Thiscompletesthemanifest.Wedostill,however,needtocreateadefaultconfigurationfileforNginx,whichissavedasprovision/modules/nginx/files/default.Thiswillbeusedunlesswepassafileparametertothenginxclasswhenusingthemodule.Thesamplefilehereisabasicconfigurationfile,pointingtothepublicfolderwithinoursyncedfolder.Theservernameoflemp-stack.localmeansthatNginxwilllistenforrequestsonthathostnameandwillservecontentfromourprojectsfolder:

server{

listen80;

root/var/www/project/public;

indexindex.phpindex.htmlindex.htm;

server_namelemp-stack.local;

location/{

try_files$uri$uri//index.php?$query_string;

}

location~\.php${

try_files$uri=404;

fastcgi_split_path_info^(.+\.php)(/.+)$;

#fastcgi_pass127.0.0.1:9000;

fastcgi_paramSERVER_NAME$host;

fastcgi_passunix:/var/run/php5-fpm.sock;

fastcgi_indexindex.php;

fastcgi_intercept_errorson;

includefastcgi_params;

}

location~/\.ht{

denyall;

}

location~*\.(jpg|jpeg|gif|css|png|js|ico|html)${

access_logoff;

expiresmax;

}

location~*\.svgz{

add_headerContent-Encoding"gzip";

}

}

TipBecausethisconfigurationfilelistensforrequestsonlemp-stack.local,weneedtoaddarecordtothehostsfileonourhostmachine,whichwillredirecttrafficfromlemp-stack.localtotheIPaddressofourvirtualmachine.

InstallingPHPToinstallPHP,weneedtoinstallarangeofrelatedpackages,includingtheNginxPHPmodule.Thiswouldbeinthefileprovision/modules/php/manifests/init.pp.

Onmorerecent(withinthepastfewyears)LinuxandPHPinstallations,PHPusesahandlercalledphp-fpmasabridgebetweenPHPandthewebserverbeingused.ThismeansthatwhennewPHPmodulesareinstalledorPHPconfigurationsarechanged,weneedtorestartthephp-fpmserviceforthesechangestotakeeffect,whereasinthepast,itwasoftenthewebserversthatneededtoberestartedorreloaded.

TomakeoursimplePHPPuppetmoduleflexible,weneedtoinstallthephp5-fpmpackageandrestartitwhenothermodulesareinstalled,butonlywhenweuseNginxonourserver.Toachievethis,wecanuseaclassparameter,whichdefaultstotrue.Thisletsususethesamemoduleinserversthatdon’thaveawebserver,andwherewedon’twanttohavetheoverheadoftheFPMservice,suchasaserverthatrunsbackgroundjobsorprocessing:

classphp($nginx=true){

Ifthenginxparameteristrue,thenweneedtoinstallphp5-fpm.Sincethispackageisonlyinstalledwhentheflagissettotrue,wecannothavePHPanditsmodulesrequiringornotifyingthephp-fpmpackage,asitmaynotbeinstalled;soinsteadweneedtohavethephp5-fpmpackagesubscribetothesepackages:

if($nginx){

package{"php5-fpm":

ensure=>present,

subscribe=>[Package['php5-dev'],Package['php5-curl'],

Package['php5-gd'],Package['php5-imagick'],Package['php5-mcrypt'],

Package['php5-mhash'],Package['php5-pspell'],Package['php5-json'],

Package['php5-xmlrpc'],Package['php5-xsl'],Package['php5-mysql']]

}

}

TherestofthemanifestcanthensimplybetheinstallationofthevariousPHPmodulesthatarerequiredforatypicalLEMPsetup:

package{"php5-dev":

ensure=>present

}

package{"php5-curl":

ensure=>present

}

package{"php5-gd":

ensure=>present

}

package{"php5-imagick":

ensure=>present

}

package{"php5-mcrypt":

ensure=>present

}

package{"php5-mhash":

ensure=>present

}

package{"php5-pspell":

ensure=>present

}

package{"php5-xmlrpc":

ensure=>present

}

package{"php5-xsl":

ensure=>present

}

package{"php5-cli":

ensure=>present

}

package{"php5-json":

ensure=>present

}

}

InstallingtheMySQLmoduleBecausewearegoingtousethePuppetmoduleforMySQLprovidedbyPuppetLabs,installingthemoduleisverystraightforward;wesimplyadditasagitsubmoduletoourprojectwiththefollowingcommand:

gitsubmoduleaddhttps://github.com/puppetlabs/puppetlabs-mysql.git

provision/modules/mysql

TipYoumightwanttouseaspecificreleaseforthismodule,asthecodechangesonasemi-regularbasis.Astablereleaseisavailableathttps://github.com/puppetlabs/puppetlabs-mysql/releases/tag/3.1.0.

DefaultmanifestFinally,weneedtopullthesemodulestogether,andinstallthemwhenourmachineisprovisioned.Todothis,wesimplyaddthefollowingmodulestoourvagrant.ppmanifestfileintheprovision/manifestsfolder.

InstallingNginxandPHPWeneedtoincludeournginxclassandoptionallyprovideafilenamefortheconfigurationfile;ifwedon’tprovideone,thedefaultwillbeused:

class{

'nginx':

file=>'default'

}

SimilarlyforPHP,weneedtoincludetheclassandinthiscase,passannginxparametertoensurethatitinstallsPHP5-FPMtoo:

class{

'php':

nginx=>true

}

HostnameconfigurationWeshouldtellourVagrantvirtualmachinewhatitshostnameisbyaddingahostresourcetoourmanifest:

host{'lemp-stack.local':

ip=>'127.0.0.1',

host_aliases=>'localhost',

}

E-mailsendingservicesBecausesomeofourprojectsmightinvolvesendinge-mails,weshouldinstalle-mailsendingservicesonourvirtualmachine.Asthesearesimplytwopackages,itmakesmoresensetoincludetheminourVagrantmanifest,asopposedtotheirownmodules:

package{"postfix":

ensure=>present

}

package{"mailutils":

ensure=>present

}

MySQLconfigurationBecausetheMySQLmoduleisveryflexibleandmanagesallaspectsofMySQL,thereisquiteabitforustoconfigure.Weneedtoperformthefollowingsteps:

1. Createadatabase.2. Createauser.3. Givetheuserpermissiontousethedatabase(grants).4. ConfiguretheMySQLrootpassword.5. InstalltheMySQLclient.6. InstalltheMySQLclientbindingsforPHP.

TheMySQLserverclasshasarangeofparametersthatcanbepassedtoconfigureit,includingdatabases,users,andgrants.So,first,weneedtodefinewhatthedatabases,users,andgrantsarethatwewanttobeconfigured:

$databases={

'lemp'=>{

ensure=>'present',

charset=>'utf8'

},

}

$users={

'lemp@localhost'=>{

ensure=>'present',

max_connections_per_hour=>'0',

max_queries_per_hour=>'0',

max_updates_per_hour=>'0',

max_user_connections=>'0',

password_hash=>'MySQL-Password-Hash',

},

}

NoteThepassword_hashparameterhereisforahashgeneratedbyMySQL.YoucangenerateapasswordhashbyconnectingtoanexistingMySQLinstanceandrunningaquerysuchasSELECTPASSWORD('password').

Thegrantmapsouruseranddatabaseandspecifieswhatpermissionstheusercanperformonthatdatabasewhenconnectingfromaparticularhost(inthiscase,localhost—sofromthevirtualmachineitself):

$grants={

'lemp@localhost/lemp.*'=>{

ensure=>'present',

options=>['GRANT'],

privileges=>['ALL'],

table=>'lemp.*',

user=>'lemp@localhost',

},

}

WethenpassthesevaluestotheMySQLserverclass.WealsoprovidearootpasswordforMySQL(unlikeearlier,thisisprovidedinplaintext),andwecanoverridetheoptionsfromtheMySQLconfigurationfile.ThisisunlikeourownNginxmodulethatprovidesafullfile—inthisinstance,theMySQLmoduleprovidesatemplateconfigurationfileandthechangesarereplacedinthattemplatetocreateaconfigurationfile:

class{'::mysql::server':

root_password=>'lemp-root-password',

override_options=>{'mysqld'=>{'max_connections'=>'1024'}},

databases=>$databases,

users=>$users,

grants=>$grants,

restart=>true

}

Aswewillhaveawebserverrunningonthismachine,whichneedstoconnecttothisdatabaseserver,wealsoneedtheclientlibraryandtheclientbindingsforPHP,sothatwecanincludethemtoo:

include'::mysql::client'

class{'::mysql::bindings':

php_enable=>true

}

LaunchingthevirtualmachineInordertolaunchournewvirtualmachine,wesimplyneedtorunthefollowingcommand:

Vagrantup

AsperChapter6,ProvisioningVagrantMachineswithPuppet,Ansible,andChef,weshouldnowseeourVMbootandthevariousPuppetphasesexecute.Ifallgoeswell,weshouldseenoerrorsinthisprocess.

SummaryInthischapter,welearnedaboutthestepsinvolvedincreatingabrandnewVagrantproject,configuringittointegratewithourhostmachine,andsettingupastandardLEMPstackusingthePuppetprovisioningtool.NowyoushouldhaveabasicunderstandingofVagrantandhowtouseittoensurethatyoursoftwareprojectsaremanagedmoreeffectively!

IndexA

Ansibleabout/UnderstandingAnsibleplaybooks/UnderstandingAnsibleinstalling/InstallingAnsibleoperatingsystems,URL/InstallingAnsibleinventory,creating/Creatinganinventoryplaybooks,creating/CreatingAnsibleplaybooksmodules/Modules–whatAnsiblecandosoftware,installing/Installingsoftwarecronmodule/Managingcroncommands,running/Runningcommandsusermodule,URL/Managingusersandgroupsgroupmodule,URL/Managingusersandgroupsroles,using/UsingAnsiblerolesGalaxy,URL/UsingAnsiblerolesused,forserverprovision/UsingAnsibletoprovisionserversprovisioningwith/ProvisioningwithAnsibleonVagrant

Ansible,filemanagementabout/Understandingfilemanagementfile,copying/Copyingafilesymlink,creating/Creatingasymlinkfolders,creating/Creatingfoldersgroupmodule,creating/Creatinggroupsusermodule,creating/Creatingusers

Ansiblesoftware,installingpackagemanager,updating/Updatingourpackagemanagernginxpackage,installing/Installingthenginxpackagenginxservice,running/Runningthenginxservice

aptmoduleURL/Updatingourpackagemanager,Installingthenginxpackage

Atlasboxes,discovering/Discoveringboxesboxes,URL/Discoveringboxesnewboxes,installing/Installingnewboxesexistingboxes,updating/Updatingexistingboxesoutdatedboxes,checkingfor/Checkingforoutdatedboxesaccount,URL/Distributingboxesboxes,distributing/Distributingboxesboxcreationform,URL/Distributingboxessharingwith/SharingandconnectingwithAtlas

connectingwith/SharingandconnectingwithAtlasVagrant,connectingtoVagrantCloud/LoggingVagrantintoVagrantCloudVagrantvirtualmachine,sharingoverHTTP(S)/SharingaVagrantvirtualmachineoverHTTP(S)Vagrantvirtualmachine,connectingto/SharingandconnectingtoaVagrantvirtualmachineVagrantvirtualmachine,sharingto/SharingandconnectingtoaVagrantvirtualmachine

authentication,Vagrantabout/Vagrantauthenticationadmingroup/Vagrantuserandadmingroupusergroup/Vagrantuserandadmingroupsudoersfile/Thesudoersfile

CChef

about/KnowingaboutChefcookbooks,creatingwith/CreatingcookbooksandrecipeswithChefrecipes,creatingwith/CreatingcookbooksandrecipeswithChefresources/Resources–whatChefcandocronresourcetype,managing/Managingcroncommands,running/Runningcommandsusers,managing/Managingusersandgroupsgroups,managing/Managingusersandgroupsgroups,creating/Creatinggroupsusers,creating/Creatinguserssudoersfile,updating/Updatingthesudoersfilecommonresourcefunctionalities/Knowingcommonresourcefunctionalitiesused,forprovisioningservers/UsingCheftoprovisionserversURL,fortutorial/UsingCheftoprovisionserversonVagrant,provisioningwith/ProvisioningwithChefonVagrant-solousing/UsingChef-soloroles,URL/UsingChef-solousing,inclient/servermode/UsingChefinclient/servermodeinstalling/InstallingChef

Chef,filemanagementabout/Understandingfilemanagementfile,copying/Copyingafilesymlink,creating/Creatingasymlinkfolders,creating/Creatingfoldersmultiplefolders,creatinginsingleprocesswithlooping/Creatingmultiplefoldersinasingleprocesswithlooping

Chef,resourcetypescron/Resources–whatChefcandoexecute/Resources–whatChefcandofile/Resources–whatChefcandogroup/Resources–whatChefcandopackage/Resources–whatChefcandoservice/Resources–whatChefcandotemplate/Resources–whatChefcandouser/Resources–whatChefcandoURL/Resources–whatChefcando

Chef,softwareinstallingabout/Installingsoftwarepackagemanager,updating/Updatingourpackagemanagernginxpackage,installing/Installingthenginxpackagenginxservice,running/Runningthenginxservice

Chef-solousing/UsingChef-solo

Chef-soloconfigurationURL/UsingCheftoprovisionservers

Chefcookbooksusing/UsingChefcookbooks

Chefrun,anatomyURL/UsingCheftoprovisionservers

client/servermodePuppetusing/UsingPuppetinclient/servermode

commandsautorunning/Autorunningcommands

configurableclasses,Puppetcreating/Creatingconfigurableclasses

cookbookscreating,withChef/CreatingcookbooksandrecipeswithChef

cronmoduleURL/Managingcron

Ffilemodule

URL/Creatingasymlink

Ggroupmodule

URL/ManagingusersandgroupsGuestAdditions,VirtualBox

about/VirtualBoxGuestAdditions

Hhostandguestmachineinteraction,managing

about/Managingintegrationbetweenhostandguestmachinesportforwarding/Portforwardingsyncedfolders/Syncedfoldersnetworking/Networking

hostnameconfiguring/Hostnameconfiguration

Iinventory,Ansible

creating/Creatinganinventory

LLEMPserver/Updatingourpackagemanager

Mmanifests

about/Defaultmanifestnginx,installing/InstallingNginxandPHPPHP,installing/InstallingNginxandPHPhostnameconfiguration/Hostnameconfiguratione-mailsendingservices/E-mailsendingservicesMySQLconfiguration/MySQLconfiguration

modules,Ansibleabout/Modules–whatAnsiblecandoApt/Modules–whatAnsiblecandoGit/Modules–whatAnsiblecandoService/Modules–whatAnsiblecandoCopy/Modules–whatAnsiblecandoURL/Modules–whatAnsiblecando

multimachineprojectdestroying/Destroyingamultimachineproject

multipleprovisionersusing,onsingleproject/Usingmultipleprovisionersonasingleproject

multiplevirtualmachinesusing,withVagrant/UsingmultiplemachineswithVagrantdefining/Definingmultiplevirtualmachinesconnecting,overSSH/ConnectingtothemultiplevirtualmachinesoverSSHnetworking/Networkingthemultiplevirtualmachinesprovisioning/Provisioningthemachinesseparately

MySQLinstalling/InstallingtheMySQLmoduleconfiguring/MySQLconfiguration

NNetworkFileSystem(NFS)/Syncedfoldersnetworking

about/Networkingnginx

installing/InstallingNginx,InstallingNginxandPHPnotifyparameter/Thenotify,subscribe,andrefreshonlyparameters

OOpscodecommunitysite,Chefcookbooks

URL/UsingChefcookbooks

Ppackagesubcommand/Exportparameters/ResourcesPHP

installing/InstallingPHP,InstallingNginxandPHPportforwarding

about/Portforwardingproject

creating/CreatingourfirstVagrantprojectprovisioners

about/ProvisionersPuppet,installing/InstallingPuppetChef,installing/InstallingChef

provisioningabout/ProvisioningwithVagrant/ProvisioningwithinVagrantwithPuppet,onVagrant/ProvisioningwithPuppetonVagrantwithAnsible,onVagrant/ProvisioningwithAnsibleonVagrantwithAnsible,onVagrant/ProvisioningwithAnsibleonVagrantwithChef,onVagrant/ProvisioningwithChefonVagrantwithSSH/ProvisioningwithSSH–arecapoverriding,viacommandline/Overridingprovisioningviathecommandline

provisioning,optionsShell/AutorunningcommandsPuppet/AutorunningcommandsAnsible/AutorunningcommandsChef/Autorunningcommands

Puppetabout/Puppetidempotentfeature/Puppetused,forcreatingmodules/CreatingmodulesandmanifestswithPuppetused,forcreatingmanifests/CreatingmodulesandmanifestswithPuppetclasses/Puppetclassesdefaultmanifests/DefaultPuppetmanifestsresource/Resourcesnotifyparameter/Thenotify,subscribe,andrefreshonlyparameterssubscribeparameter/Thenotify,subscribe,andrefreshonlyparametersrefreshonlyparameter/Thenotify,subscribe,andrefreshonlyparametersfilemanagement/Filemanagementcronresourcetype,managing/Cronmanagementcommands,running/Runningcommandsuserresourcetype,managing/Managingusersandgroups,Creatingusersgroupresourcetype,managing/Managingusersandgroups

userresourcetype,URL/Managingusersandgroupssudoersfile,updating/Updatingthesudoersfileconfigurableclasses,creating/Creatingconfigurableclassesmodules/Puppetmodulesused,forserverprovision/UsingPuppettoprovisionserversprovisioningwith,onVagrant/ProvisioningwithPuppetonVagrantusing,instandalonemode/UsingPuppetinstandalonemodeprovisioning,inaction/Puppetprovisioninginactionusing,inclient/servermode/UsingPuppetinclient/servermodeURL/UsingPuppetinclient/servermodeblog,URL/UsingPuppetinclient/servermodeinstalling/InstallingPuppet

Puppet,filemanagementabout/Filemanagementfile,copying/Copyingafilesymlink,creating/Creatingasymlinkfolders,creating/Creatingfoldersmultiplefolders,creating/Creatingmultiplefoldersinonego

Puppet,resourcetypes/Resourcestypes,URL/Resourcesrequisites/Resourcerequirementsexecution,ordering/Resourceexecutionorderingexecuting,instages/Executingresourcesinstages

Puppet,resourcetypescron/Resourcesexec/Resourcesfile/Resourcesgroup/Resourcespackage/Resourcesservice/Resourcesuser/Resources

PuppetForgeURL/Puppetmodules

Puppetmanifestscreating/CreatingthePuppetmanifestsnginx,installing/InstallingNginxPHP,installing/InstallingPHPMySQLmodule,installing/InstallingtheMySQLmoduleURL/InstallingtheMySQLmodule

Puppetsoftware,installingabout/Installingsoftwarepackagemanager,updating/Updatingourpackagemanagernginxpackage,installing/Installingthenginxpackage

nginxservice,running/RunningthenginxservicePuTTY

URL/ConnectingtothevirtualmachineoverSSH

Rrecipes

creating,withChef/CreatingcookbooksandrecipeswithChefrecipes,Chef

URL/UsingCheftoprovisionserversrefreshonlyparameter/Thenotify,subscribe,andrefreshonlyparameters

Sservers

provisioning,Chefused/UsingCheftoprovisionserversSSH

provisioningwith/ProvisioningwithSSH–arecapmultiplevirtualmachines,connectingto/ConnectingtothemultiplevirtualmachinesoverSSH

SSHprovisioningabout/Autorunningcommands

standalonemodePuppetusing/UsingPuppetinstandalonemode

subscribeparameter/Thenotify,subscribe,andrefreshonlyparameterssudoersfile

URL/Thesudoersfileabout/Thesudoersfile

/Thesudoersfilesupervisord

URL/CreatingmodulesandmanifestswithPuppetabout/DefaultPuppetmanifests

supervisormoduleURL/DefaultPuppetmanifests

symlinkcreating/Creatingasymlink

syncedfoldersabout/Syncedfolders

Ttemplatemodule

URL/Copyingafile

Uusermodule

URL/Managingusersandgroups,Creatingusers

VVagrant

about/IntroducingVagrant,ToomanyVagrants!URL/IntroducingVagrant,RequirementsforVagrant,ConnectingtothevirtualmachineoverSSHconfigurationfile/IntroducingVagrantrequisites/RequirementsforVagrantVirtualBox,installing/InstallingVirtualBoxinstalling/InstallingVagrantdownloadpage/InstallingVagrantproject,creating/CreatingourfirstVagrantproject,CreatingtheVagrantproject-controlledguestmachines,controlling/ManagingVagrant-controlledguestmachinesvirtualmachine,poweringup/PoweringupaVagrant-controlledvirtualmachinevirtualmachine,suspending/Suspendingavirtualmachinevirtualmachine,resuming/Resumingavirtualmachinevirtualmachine,shuttingdown/Shuttingdownavirtualmachineprovisioning,options/Autorunningcommandsprovisioningwith/ProvisioningwithinVagrantprovisioning,withChef/ProvisioningwithChefonVagrantmultiplevirtualmachines,using/UsingmultiplemachineswithVagrantdocumentation,URL/Gettingstartednewbasebox,URL/Gettingstartedauthentication/Vagrantauthentication

Vagrantauthenticationinsecurepublickeypair/Insecurepublic/privatekeypairinsecureprivatekeypair/Insecurepublic/privatekeypair

Vagrantboxesmanaging/ManagingVagrantboxesaddsubcommand/ManagingVagrantboxes,AddingVagrantboxeslistsubcommand/ManagingVagrantboxes,ListingVagrantboxesoutdatedsubcommand/ManagingVagrantboxes,Checkingforupdatesremovesubcommand/ManagingVagrantboxes,RemovingVagrantboxesrepackagesubcommand/ManagingVagrantboxes,RepackagingaVagrantboxupdatesubcommand/ManagingVagrantboxes,Updatingthecurrentenvironment’sboxadding/AddingVagrantboxeslisting/ListingVagrantboxesupdates,checkingfor/Checkingforupdatesremoving/RemovingVagrantboxesrepackaging/RepackagingaVagrantboxcurrentenvironmentsbox,updating/Updatingthecurrentenvironment’sbox

Vagrantboxes,Atlasdiscovering/Discoveringboxesnewboxes,installing/Installingnewboxesexistingboxes,updating/Updatingexistingboxesoutdatedboxes,checkingfor/Checkingforoutdatedboxesdistributing/Distributingboxes

Vagrantvirtualmachine,Atlassharing,overHTTP(S)/SharingaVagrantvirtualmachineoverHTTP(S)

VirtualBoxinstalling/InstallingVirtualBox

VirtualBoxmachinepreparing/PreparingtheVirtualBoxmachine

virtualmachinecleaningup/CleaninguptheVMlaunching/Launchingthevirtualmachine

virtualmachine,Vagrant-controlledmanaging/ManagingVagrant-controlledguestmachinespoweringup/PoweringupaVagrant-controlledvirtualmachinesuspending/Suspendingavirtualmachineresuming/Resumingavirtualmachineshuttingdown/Shuttingdownavirtualmachinestarting,fromscratch/StartingfromscratchoffVagrantfilechanges,updating/UpdatingbasedonVagrantfilechangesconnectingto,overSSH/ConnectingtothevirtualmachineoverSSH

YYamlAin’tMarkupLanguage(YAML)

about/UnderstandingAnsible

top related