ConfigurationManagementwithChef-Solo
TableofContents
ConfigurationManagementwithChef-Solo
Credits
AbouttheAuthor
AbouttheReviewers
www.PacktPub.com
Supportfiles,eBooks,discountoffers,andmore
Whysubscribe?
FreeaccessforPacktaccountholders
Preface
Whatthisbookcovers
Whatyouneedforthisbook
Whothisbookisfor
Conventions
Readerfeedback
Customersupport
Downloadingtheexamplecode
Errata
Piracy
Questions
1.IntroductiontoChefandChef-Solo
GettingstartedwithChef
UnderstandingChef-Solo
Terminologies
Listofterminologies
Node
Workstation
Cookbooks
Recipes
Resources
Roles
Attributes
Templates
Databags
Differentusecases
PHPWordPress
Python/Djangoapplication
AnoverviewofChef
Summary
2.SettingUpanEnvironmentforChef-Solo
InstallationonLinuxandUbuntu
InstallingChefasaRubygem
InstallingChefasapackagemanager
UsingtheOmnibusinstaller
PrerequisitesofChef-Solo
Cookbooks
Thefolderstructure
Attributes
Files
Recipes
Templates
Downloadingrecipes
Chef-Soloconfiguration
Executionofrecipes
Summary
3.SettingUpaDevelopmentEnvironment
Introducingvirtualmachine
Systemvirtualmachines
Processvirtualmachines
ExecutingrecipeswithVagrant
Provision
CreatingaHelloWorldrecipe
Summary
4.DevelopingCookbooks
ExploringKnife
Developingrecipesandcookbooks
Berkshelf
TheinstallationofBerkshelf
ThecreationofaBerksfile
Understandingrecipes
Resources
Attributes
Metadata
Summary
5.MoreaboutCookbooksandRecipes
Usingfiles
Exploringtemplates
Databags
Roles
Restartingservicesandserverhandling
Summary
6.Chef-SoloandDocker
Docker
InstallingDocker
TheworkingofDocker
Dockerfiles
RecommendedwaystouseChef-Solo
Chefserver
WebUI
Erchef
Messagequeues
Summary
Index
ConfigurationManagementwithChef-Solo
ConfigurationManagementwithChef-SoloCopyright©2014PacktPublishing
Allrightsreserved.Nopartofthisbookmaybereproduced,storedinaretrievalsystem,ortransmittedinanyformorbyanymeans,withoutthepriorwrittenpermissionofthepublisher,exceptinthecaseofbriefquotationsembeddedincriticalarticlesorreviews.
Everyefforthasbeenmadeinthepreparationofthisbooktoensuretheaccuracyoftheinformationpresented.However,theinformationcontainedinthisbookissoldwithoutwarranty,eitherexpressorimplied.Neithertheauthor,norPacktPublishing,anditsdealersanddistributorswillbeheldliableforanydamagescausedorallegedtobecauseddirectlyorindirectlybythisbook.
PacktPublishinghasendeavoredtoprovidetrademarkinformationaboutallofthecompaniesandproductsmentionedinthisbookbytheappropriateuseofcapitals.However,PacktPublishingcannotguaranteetheaccuracyofthisinformation.
Firstpublished:June2014
Productionreference:1190614
PublishedbyPacktPublishingLtd.
LiveryPlace
35LiveryStreet
BirminghamB32PB,UK.
ISBN978-1-78398-246-2
www.packtpub.com
CoverimagebyBéchirCharfi(<[email protected]>)
CreditsAuthor
NaveedurRahman
Reviewers
AnirudhBhatnagar
StuartEllis
JorgeMoratilla
CommissioningEditor
EdwardGordon
AcquisitionEditor
SubhoGupta
ContentDevelopmentEditor
SriramNeelakantan
TechnicalEditors
VenuManthena
ShrutiRawool
CopyEditors
JanbalDharmaraj
KarunaNarayanan
ProjectCoordinator
AboliAmbardekar
Proofreaders
MariaGould
PaulHindle
Indexer
RekhaNair
Graphics
DishaHaria
ProductionCoordinator
ShantanuZagade
CoverWork
ShantanuZagade
AbouttheAuthorNaveedurRahmanisaself-taughtprogrammerandanavidtraveler.Whenheisnotexperimentingwiththelatestinprogramminganddeployment,heisoutcampingandwatchingcricket.
HisadventuresinprogrammingbeganataveryyoungagewhenhegotintroducedtoGW-BASIC.Now,hehasexperienceworkingforoneofthebiggesttechnamesintheMiddleEast.
HavingworkedatthelargesttechnologycompanyintheMiddleEast,Naveedhashelpedteamscreateanddeployapplicationswritteninvariouslanguagesusingconfigurationmanagementtools.
Iwouldliketothankmyfamilyforsupportingmethroughouttheprocessofwriting.Also,thehelpofPacktPublishingstaffhasbeenincredible.Iwouldliketothankmyprojectcoordinatorandcontentdevelopmenteditorwhosupportedmeinwritingandfinalizingthecontent.Also,thetechnicalreviewersprovidedmewithaclearguidelinetomakethisbookmoreeffective.Moreover,theirvaluablecritiquesallowedmetorefinemywork.
AbouttheReviewersAnirudhBhatnagarisatechnologyconsultantwithanextensiveexperienceinAgileproductdevelopmentandconsulting.HestartedhiscareerworkingasaJavadeveloperwithproduct-basedcompaniessuchasAdobeSystems,India,wheremostofhisexperiencewasinJava,J2EE,Spring,Hibernate,XML,WebServices,REST,CMS,SSO,ESB,andLiferay.Currently,heisworkingasaPrincipalConsultantinXebia,IndiawithspecializationinContinuousDeliverymethodology,andworkingondevelopingaPaaSforserviceorchestrationusingMuleESB,ActiveMQ,Elasticsearch,Jenkins,Maven,Chef,andAWS.Hehasbeencontributingtothesoftwarecommunitythroughhisblogs,articles,projects,meetups,andconferences.Recently,hehasstartedaDevOpscommunityinNewDelhiandhasspokenatDevOpsDaysIndia2013.
StuartEllisworksforaRubyonRailsandmobilesoftwaredevelopmentcompany,wherehehasmanyhats.Inhiscurrentandpreviousroles,hehasdevelopedsoftwarewith.NETandRuby,writtenSQLinasurprisingnumberofdialects,manageddifferentcombinationsofWindowsandLinux,andstudiedhistory.
JorgeMoratillahasaBachelor’sdegreeinComputerScienceandhasbeenworkingforInternetcompaniessince1998.HehasbeenworkingasacontractorforcompaniessuchasSunMicrosystemsandOracle,workingasacertifiedinstructorandfieldengineerforseveralyears.HehasalargebackgroundworkingwithtechnologiesandproductssuchasLinux,Solaris,LDAP,andCheckPoint.Recently,hehasbeenworkingindevelopmentcompanies,mainlyasasystemadministrator,andperformingseveraltasksrelatedwithAgilemanagement,testing,andContinuousDeployment.AsacoordinatorofthetechnicalgroupMadridDevOps,hepromotestheadoptionofacultureofcontinuousimprovementintheenterprise.Youcanmeethimattalksandhangoutsheorganizesinthecommunity.
IwouldliketopersonallythankmywifeNuriaandsonEduardoforbeingsounderstandingandsupportivewhileIwasreviewingthisbook.Also,IwouldliketothankmydearmomMilagrosanddadToñi,whoputinalltheefforttogivemeaneducation.Finally,Iwouldthankalsoallthosewhohavecontributedtomypersonalandprofessionaldevelopmentthroughtheyears.
www.PacktPub.com
Supportfiles,eBooks,discountoffers,andmoreYoumightwanttovisitwww.PacktPub.comforsupportfilesanddownloadsrelatedtoyourbook.
DidyouknowthatPacktofferseBookversionsofeverybookpublished,withPDFandePubfilesavailable?YoucanupgradetotheeBookversionatwww.PacktPub.comandasaprintbookcustomer,youareentitledtoadiscountontheeBookcopy.Getintouchwithusat<[email protected]>formoredetails.
Atwww.PacktPub.com,youcanalsoreadacollectionoffreetechnicalarticles,signupforarangeoffreenewslettersandreceiveexclusivediscountsandoffersonPacktbooksandeBooks.
http://PacktLib.PacktPub.com
DoyouneedinstantsolutionstoyourITquestions?PacktLibisPackt’sonlinedigitalbooklibrary.Here,youcanaccess,readandsearchacrossPackt’sentirelibraryofbooks.
Whysubscribe?FullysearchableacrosseverybookpublishedbyPacktCopyandpaste,printandbookmarkcontentOndemandandaccessibleviawebbrowser
FreeaccessforPacktaccountholdersIfyouhaveanaccountwithPacktatwww.PacktPub.com,youcanusethistoaccessPacktLibtodayandviewnineentirelyfreebooks.Simplyuseyourlogincredentialsforimmediateaccess.
PrefaceChef-Soloisanopensourceversionofchef-clientoriginallydevelopedbyChefSoftware,Inc.Itisacompleteframeworktoautomateinfrastructureoperationsforbuildingserversorapplicationsfromscratchoraddingnewconfigurationstoexistingsystems.TheseserversaremanagedbycodewritteninRubyanditalsoprovidesthefacilitytotestandreproduce.
Thebookwilltakethereaderthroughtheworkflowofmanagingoneormoreservers.Also,itincludesmanysamplerecipestohelpyougetstarted.
Throughouttheprocess,wewillhavealookatthedifferentinteractionpointsandyouwilllearnhowChef-Solohelpstominimizeyoureffortstobuildandefficientlymanagedifferentmachines.YouwillbeabletohandleoneormoreserversfromthecodewritteninRuby.Thisbookwillalsohelpyoutounderstandtheneedforaconfigurationmanagementtoolandanin-depthexplanationofChef-Solo.
Thisbookwillprovideclearinstructionstothereaderonhowtoconvertyourinfrastructureintocode.Also,itexplainsdifferentvirtualmachinesandcertaindeploymentautomationtoolsincludingVagrantandDocker.
WhatthisbookcoversChapter1,IntroductiontoChefandChef-Solo,explainsaboutChef,chef-client,andChef-Solo.ItexplainsaboutthecoreconceptsinChefandtheterminologieswithsomeusecases.
Chapter2,SettingUpanEnvironmentforChef-Solo,guidesyoutoinstallChef-SoloonyourUbuntumachine,anddiscussescookbooksandtheirstructureindetail.Italsoprovidesstep-by-stepinstructionsonhowtoruncookbooksusingChef-Solowithcustomconfigurations.
Chapter3,SettingUpaDevelopmentEnvironment,explainsvirtualmachinesandtheirproviders.Inthischapter,wewillsetupthedevelopmentenvironmentusingVagrantandexecutesomesamplerecipes.
Chapter4,DevelopingCookbooks,looksdeeperintodevelopingrecipesandhowtomanagetherecipesincookbooks.Italsoprovidesmoredetailedinformationonmetadata,attributes,templates,files,resources,anddatabags.Also,itincludessometoolstomanageandcreatecookbooks,forexample,KnifeandBerkshelf.
Chapter5,MoreaboutCookbooksandRecipes,continueswiththelastchapter’scookbooksandmanagestheremainingcontentswithfilesandtemplates.ThischapterincludesPython/Djangocookbooksandinformationaboutupstreamservice.
Chapter6,Chef-SoloandDocker,coverstheinstallationofDockerandcreationofDockerimagesusingChef-Solo.Also,thischapterincludessomerecommendationsonhowtoworkonrecipesofongoingprojectsandkeepthemalignedwithChef-Solo.
WhatyouneedforthisbookYouneedonlyasingleUbuntumachinetogetstarted.Thisbookcontainsastep-by-stepguidetosetupadevelopmentenvironment.Onceyouhavesuccessfullyinstalledeverything,youcaneasilyreproducethesameonmultiplemachines.
WhothisbookisforThisbookisforsystemadministratorsandsystemengineerswhohaveanunderstandingofconfigurationmanagementtoolsandinfrastructure.Ithelpsyoutounderstandtheneedforthesetoolsandprovidesyouwithastep-by-stepguidetomaintainyourexistinginfrastructure.Italsocontainsthemostfrequentlyusedapplicationrecipestogetstartedimmediately.
ConventionsInthisbook,youwillfindanumberofstylesoftextthatdistinguishbetweendifferentkindsofinformation.Herearesomeexamplesofthesestyles,andanexplanationoftheirmeaning.
Codewordsintext,databasetablenames,foldernames,filenames,fileextensions,pathnames,dummyURLs,userinput,andTwitterhandlesareshownasfollows:“Thesolo.rbfileisusedtospecifyalltheconfigurationdetails.”
Ablockofcodeissetasfollows:
{
"run_list":[
"recipe[nginx::default]",
"recipe[git::default]",
]
}
Whenwewishtodrawyourattentiontoaparticularpartofacodeblock,therelevantlinesoritemsaresetinbold:
#Toupdate
execute"updateapt"do
command"apt-getupdate--fix-missing"
end
Anycommand-lineinputoroutputiswrittenasfollows:
$sudoapt-getinstallcurl
Newtermsandimportantwordsareshowninbold.Wordsthatyouseeonthescreen,inmenusordialogboxesforexample,appearinthetextlikethis:“ItshoulddisplaytheWelcometonginx!page.”
NoteWarningsorimportantnotesappearinaboxlikethis.
TipTipsandtricksappearlikethis.
ReaderfeedbackFeedbackfromourreadersisalwayswelcome.Letusknowwhatyouthinkaboutthisbook—whatyoulikedormayhavedisliked.Readerfeedbackisimportantforustodeveloptitlesthatyoureallygetthemostoutof.
Tosendusgeneralfeedback,simplysendane-mailto<[email protected]>,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<[email protected]>withalinktothesuspectedpiratedmaterial.
Weappreciateyourhelpinprotectingourauthors,andourabilitytobringyouvaluablecontent.
QuestionsYoucancontactusat<[email protected]>ifyouarehavingaproblemwithanyaspectofthebook,andwewilldoourbesttoaddressit.
Chapter1.IntroductiontoChefandChef-SoloChefisaconfigurationmanagementsystemtoautomatetheprocessofdeployingserverstoanyphysical,virtual,orcloudlocation.EachsetupinvolvesthebasicstructurewithoneChefserveranddifferentnodesmanagedbythechef-client.ChefinfrastructureismanagedbyRubycodeanditallowsyoutotest,build,andreplicateyourinfrastructure.
ThischapterwillguideyouthroughthebasicsofChefandhowitcanhelpyouinbuildinganinfrastructure.WewilldiscussChef,Chef-Solo,andaddresssomecommonproblemsinbuildinganinfrastructureandhowChefcanhelpustosolvetheseproblems.
Wewillcoverthefollowingtopicsinthischapter:
ChefexplanationsandconceptsChef-SoloTerminologyforChefDifferentusecasesConcepts
GettingstartedwithChefChefisacompleteframeworktoautomateinfrastructureoperationstobuildserversorapplicationsfromscratchoraddnewconfigurationstoexistingsystems.Serversaremanagedbycode,writteninRubyanditprovidesthefacilitytotestandreproducemachines.
Chefbasicinfrastructurecontainsatleastoneserverandonenode.Eachnodeismaintainedandsetupbychef-clientandisresponsibleforexecutingrecipesandconfiguringenvironmentstorunapplications.Itcontainstheabstract-levelconfigurationofaserveroranapplication.
Tinycodeblocksinrecipescontainasetofcommandsthatexecuteonasystemsequentially,andgraduallyconfigurethewholeenvironment.Thecompleteprocessisfullyautomatedandwithouthumanadministration;Chefcansetupseveralnodes.
Forinstance,ifyouwant100serverswithPython/DjangorunningNginxwithuWSGIandyouwanttohavethesameinstallationsoneachnode,Chefcanmakethishappeninminutes;italsoprovidesyouwiththeswitchtoturnyournodesonandoff.Itcancheckforrevisioncontrolsystemandisresponsibleforpullingrecentupdatesfromtherepository.Youcaneasilyrevertthesystemtothepreviousstateifsomethingdoesnothappenaccordingtoyourneeds.WithChef,systemadministratorscanspendlesstimeonmaintenanceandmoretimeoninnovation.
Traditionalinfrastructureisslowandtedious;itinvolvesmanystepstobuildserversandrunningapplications.Allyourconfigurationsareinoneplaceandyouwillnotworryabouttheseveralconfigurationsofdifferentservers.Whilescalingyourapplication,itishighlyrecommendedtouseChef,asyoucaneasilysplityourappontodifferentserversbyusingrolesandnodes.Youdonothavetoinstallthesameapplication10timesononemachineoranyother,justcreateanewnodeinChefserverandinafewminutes,theserverwillbereadytohandletheapplication.Also,thereisnoneedtomaintainthedocumentationofservers,astherecipes’codeisself-explanatoryandeasytograspforanewuser.
ChefisdevelopedbyChefSoftware,Inc.andrecentlytheyreleasedVersion11.0.ChefcodeiscompletelyrewritteninVersion11.0,swappingoutApacheCouchDBforPostgreSQLandRubyforErlang.TheresultismassiveandnowasingleChefservercanhandlemorethan1000nodes(clients).
Chefisprovidedinthefollowingthreeversions:
PrivateChef:Thisisanenterpriseversionthatsupportsmulti-tenancytoprovideahighlyscalableservertohandleseveralnodes.Itshouldbelocatedintheclient’spremisesandmanagedbehindafirewall.HostedChef:ThisisanSAASservicemanagedbyChefSoftware,Inc.Itisacloud-basedserviceandhighlyavailable(24/7x365),withrolesandresource-basedaccesscontrols.Itdoesnotrequireafirewall.OpensourceChef:Thisisacommunity-drivenversionwithalmostidentical
features,anditshouldbemanagedlocallyandbehindthefirewall.Thelatestfeaturesinitiallywerereleasedforthecommercialversionandthengraduallyreleasedintheopensourceversion.Thesystemadministratorwillberesponsibleforapplyingupdates,definingroles,datamigrations,andensuringthattheinfrastructurescalesappropriately.
Chefhasbeenprimarilydividedintothefollowingthreeparts:
Chefserver:Chefserverisresponsibleforhandlingnodesandprovidingcookbookstoclients.chef-client:Thechef-clientactuallyexecutestherecipesandconfiguresthesystem.Italsoresolveseachapplicationdependency.TheChefarchitectureisbasedontheThinserver,Thickclientmodel.Thereisnoneedforcontinuouscommunicationwiththeserver,astheclientretrievesthecookbooksfromtheserverandprocessesrecipesontheclientend.Theserverdistributesdatatoeachnodeincludingcookbooks,templates,files,andotheritems.Theservercontainsthecopyofallitems.Thisapproachensuresthateachnodehaspersistentdataandfiles.Knife:Knifeisatoolthatprovidesaninterfacebetweenlocal-repoandtheserver.Itisusedtoretrievecookbooks,policies,roles,environments,andotheritems.
UnderstandingChef-SoloChef-Soloisanopensourceversionofchef-client.Itexecutesrecipesfromthelocalcookbooks.Itisalimitedversionofchef-clientandhasmuchfewerfeaturesthanit.Itdoesnothavethefollowingfeatures:
Nodedatastorage:Nodedatastorageisusedtokeepvaluesconsistentacrosseachnodeinalargeinfrastructure.Searchindexes:Searchindexisafulllistofobjectsthatarestoredbytheserver,includingroles,nodes,environments,anddatabags.Theyareafullytext-basedsearchanditsqueriescanbemadeusingwildcard,range,andfuzzylogic.WhileusingKnife,asearchcanbemadebyusingasubcommandfromKnife.
Thefollowingcommandisanexample.TosearchbyaplatformID,usethefollowingcommand:
knifesearchnode'rackspace:*'–i
Theresultfortheprecedingcommandwouldbeasfollows:
4itemsfound
ip-1B45DE89.rackspace.internal
ip-1B45DE89.rackspace.internal
ip-1B45DE89.rackspace.internal
ip-1B45DE89.rackspace.internal
TipDownloadingthesamplecode
YoucandownloadthesamplecodefilesforallPacktbooksyouhavepurchasedfromyouraccountathttp://www.packtpub.com.Ifyoupurchasedthisbookelsewhere,youcanvisithttp://www.packtpub.com/supportandregistertohavethefilese-maileddirectlytoyou.
Similarly,youcansearchbyinstancetype,node,environment,nestedattributes,andmultiplearguments.
Centralizeddistributionofcookbooks:AsChef-Soloworksindividually,itdoesnothavetheabilityfordistributionofcookbooks.EvenifyouhavedeployedChefserver,Chef-Solowillnotbeabletoretrieverecipesfromacentralizedsource.CentralizedAPIforintegrationwithotherinfrastructurecomponents:ThereisnocentralizedAPIforChef-Solotoretrieveotherconfigurationsfromadifferentmachine.Forinstance,ifyourapplicationneedsdatabaseconnectivity,youwillnotbeabletogettheIPofthedatabasesource.Therearemultiplesolutionstoaddressthisproblem,whichwewilldiscussintheupcomingchapters.Authentication:Chef-Solohasnoauthenticationmodule;anyonecanexecutetherecipes:
#chef-soloprivileges
testALL=(ALL)NOPASSWD:/usr/bin/chef-solo
#testisnameofnon-rootuser.
Persistentattributes:ThereisnocentralizedcookbooksystemforChef-Solo;itjustexecutestherecipesfromalocalcookbook.
AlthoughChef-Solohasfewerfeatures,itprovidesthecoreuseofdevelopingcookbooks.
Moreover,Chef-Soloprovidesasimplewaytostart.Youcanbuildthesystembyusingcookbooksandit’sextremelyusefulforbootingnewmachines.
Likechef-client,Chef-Solocanbeusedforservers,applications,oranyphysicalmachine.
TerminologiesWewillnowdiscusssometerminologiesaboutChef.Aswehavealreadydiscussed,Chefhastwodifferenttypes,namelyChefserverandChef-Solo.Chef-Soloprovidesasimplewaytostart.ThefollowingterminologiesmentionedareusedforChefserveraswellasChef-Solo.
ListofterminologiesAgeneralizedlistofChefterminologiesarementionedinthefollowingsection.
NodeAnyphysical,virtual,orcloudmachinewherechef-clientwillrunistermedasanode.Therearethefollowingfourtypesofnodesthatcanbemanagedbychef-client:
Cloudnode:Thisisaserverhostedonanycloud-basedservicesuchasRackspace,Amazon,VirtualPrivateCloud,OpenStack,GoogleComputeEngine,orWindowsAzure.Differentpluginsareavailableforsupportingdifferentcloudtypes.Itcanbeusedtocreateinstancesusingcloud-basedservices.Physicalnode:Physicalnodeisaserveroravirtualmachinethathasthecapabilityofsending,receiving,andforwardingdatathroughanetworkchannel.Insimplewords,anetworkmachinethatrunsthechef-client.Virtualnode:Avirtualnoderunsasasoftwareimplementationbutbehaveslikeapropermachine,forexample,VirtualBox,Docker,andsoon.Networknode:Thisisadeviceattachedtothenetworkandcapableofsending,receiving,andforwardingdata,andmanagedbychef-client.Routers,switches,andfirewallsareaperfectexampleofnetworknodes.
WorkstationAworkstationisamachine,whereKnifeconfiguresandsendsinstructionstoanode.Knifeisusedtomanagenodes,cookbooksandrecipes,roles,andenvironments.AcommercialKnifeversioncanbeusedtosearchindexdataontheserver.
Foraproductionenvironment,workstationauthenticationismanagedbyRSAoraDSAkeypair.Authenticationensuresthataworkstationisproperlyregisteredwiththeserver.
Moreover,Chef-repoismaintainedontheworkstationanditisdistributedinchef-clientsfromtheworkstation.Oncethedistributionisdone,chef-clientexecutestherecipesandinstallseverythingonthesystem.
CookbooksCookbooksareacollectionofrecipes.Eachcookbookdefinesthepolicyandscenariotoinstallandconfigureanyparticularmachine.Forinstance,installingPostgreSQLneedslibpq-devandotherpackages.Itcontainsallthecomponentsthatneedtobeinstalledonthesystem.
Additionalconfigurationscanbesetupusingcookbooks:
AttributestosetonnodesDefinitionsofresourcesDependencycontrolFiledistributionsLibrariestohelpChef-SolotoextendRubycode,forexample,Berkshelf,Librarian-Chef
TemplatesCustomresourcesandprovidersRolesMetadataofrecipesVersions
CookbooksarewritteninRubycode.It’sgoodtohaveknowledgeaboutRuby,butit’snotmandatory.TheRubycodeusedincookbooksisverysimpleandself-explanatory.Whileusingcookbooks,youdonotneedtomaintainthedocumentationoftheserversetup.
Thesolepurposeofacookbookistogiveareasonablesetofresourcestoachef-clientfortheinfrastructureautomation.
RecipesRecipesarethefundamentalconfigurationelementsincookbooks.Arecipecontainsasetofcommandsthatneedstobeexecutedstepbystep.Arecipecanincludeadditionalrecipeswithinarecipe.
Eachcodeblockcontainsasetofinstructions.Forexample,takealookatthefollowingcode:
#Toupdate
execute"updateapt"do
command"apt-getupdate--fix-missing"
end
#Forinstallingsomepackages
%w{
curl
screen
make
python2.7-dev
vim
python-setuptools
libmysqlclient-dev
mysql-client
}.eachdo|pkg|
packagepkgdo
action:install
end
end
RecipesarewritteninRubycode,anditcontainsthesetofresources;eachcodeblockiswrappedinaresource.Inthepreviousexample,executeandpackageisaresourcetohandlecodeinsideablock.
Therearecertainrulesforwritingrecipes:
Itshouldmaintainaproperorder.Forinstance,ifyouwanttouseMySQL,youmustspecifythelibmysqlclient-devpackagefirstandtheninstallMySQL.Recipesmustbeplacedinthecookbookfolder.Itmustdefineeverythingthatneedstobeinstalledinaparticularenvironment.
Recipesmustbedeclaredinrun_listtoexecuteinanyrecipe.Anyadditionalrecipethatyouspecifyshouldbecontainedinthesamecookbookfolderoryoushouldhavesomedependencyresolvedtoincludetherecipe(Berkshelfallowsyoutoincludetherecipefromgithub.com).
ResourcesAresourceisanintegralpartofanyrecipe.Itdefinestheactionstobetakeninarecipe.Itcouldbeaservice,apackage,agroupofauser,andsoon.Forexample,itwillinstructchef-clienttocheckwhetheraparticularpackageneedstobeinstalledornot,orwhenaserviceneedstoberestartedornot,andwhichdirectoryorfileneedstobecreatedbywhichuser.Eachresourceiswritteninacodeblockanditexecutesinthesameorderasmentionedintherecipe.Chef-Soloensuresthateachactionhastobetakenasspecifiedintherecipe.Afterthesuccessfulexecutionofresources,itreturnsthesuccesscodetochef-client.Incasethereisanerror,itreturnswithanerrorcodeandchef-clientexitswithanerror.
Thefollowingisanexampleofadirectoryresource:
directory"/var/log/project"do
owner"root"
group"root"
recursivetrue
action:create
end
Thechef-clientwilllookupthedirectoryresourceandcallload_current_resourcetocreateanewdirectoryresource.Theclientwilllookupthedirectory;ifit’snotcreated,itwillcreatethedirectoryinthelogsfolder,andifthedirectoryalreadyexists,nothingwillhappenandtheresourcewillbemarkedascompleted.
ThefollowingisanexampleofaGitresource:
git"/home/user/webapps/project"do
repository"[email protected]:opscode-cookbooks/chef_handler.git"
reference"master"
action:sync
enable_submodulestrue
user"root"
group"root"
end
ThementionedGitresourcewillpullthecodefromtherepositorywithallsub-modules.
Itwillswitchthebranchtomasterandasyncwillensurethatrecentchangeshavebeenpulledfromtheremoterepositorytothelocalrepository.
Theresourceismainlydividedintothefollowingfourparts:
TypeNameAttributesActions
Thecodingconventionoftheresourceisshowninthefollowingcode:
resourcetype"name"do
attribute"value"
action:action
end
Intheprecedingcode,resourcetypeisthenameofaresource,forexample,directory,file,apache_site,andsoon.
Aswehavediscussedearlierthateachresourcehasseparateactions,theactioncommandisusedtoexecutetheseactions.
Eachresourcehasitsowntypeofactionsandattributes.Thedirectoryresourcehasacreateandadeleteaction.Eachresourcehasitsowndefaultactionsandattributes.Similarly,thedefaultactiondirectoryresourceiscreate.Andithasgroup,inherits,mode,owner,path,provider,recursive,andrightattributes.
RolesInsimplewords,thereusableconfigurationofseveralnodes,forexample,database,Web,andsoon,arecalledasroles.Theydefinecertainpatternsandprocessesthatneedtobeinstalledindifferentnodes.Whenarolerunsagainstanyrecipe,attributeshavebeenoverwrittenwithroleattributes.
Eachnodecanhavezeroormorerolesassignedtoitandthenrun_listofroleswillbeexecutedonthenode.
Anattributecanbedefinedbothinanodeandinarole.Roleshouldhaveatleastthefollowingattributes:
name:Thisattributegivesthenameoftheroledescription:Thiscontainsthedescriptionoftherolerun_list:Recipesneedtobeexecutedwiththisrole
Rolescanbedeclaredintwoways:wecandefineitinRubyorinJSON.IncaseofJSON,therearesomeadditionalattributes,suchaschef_type,json_classthatneedtobedefined.Detailedinformationaboutrolesisavailableinthenextchapter.
AttributesInsimpleterms,attributesarevariablesthataredefinedinacookbooktobeusedbyrecipesandtemplatestocreateconfigurationfiles.Whenchef-clientexecutestherecipes,itloadsalltheattributesfromcookbooks,recipes,androles.
Attributesaredeclaredintheattributesfolderundercookbooks.Whenanyrecipeisexecuted,itcheckswithinthecontextofthecurrentnodeandappliesonthatnode.
Forexample,Nginxcookbookattributesaregivenasfollows:
default["nginx"]["dir"]="/etc/nginx"
default["nginx"]["listen_ports"]=["80","443"]
Similarly,Gitattributesaregivenasfollows:
default["project"][:project_path]="/home/chef/webapps/project"
default["project"][:repository]="[email protected]:opscode-
cookbooks/chef_handler.git"
Wehavealreadydiscussedabouttheattributes’precedenceintheRolessection.Wewilldiscussattributesinmoredetailintheupcomingchapters.
TemplatesAtemplateisasimpleconfigurationfilethathasaplaceholderforattributes.TemplatesfilesarewritteninEmbeddedRuby(.erb)format.Forexample,todeployNginx,youneedthenginx.conf.erbfile.
Asampleofatemplatefileismentionedasfollows:
server{
listen80;
server_name<%=node["project"]["domain"]%>;
access_log<%=node["project"]["logs_dir"]%>/<%=node["project"]
["project"_name]%>_access.log;
error_log<%=node["project"]["logs_dir"]%>/<%=node["project"]
["project"_name]%>_error.log;
location/{
client_max_body_size20M;
client_body_temp_path/tmp/
expires-1;
proxy_passhttp://localhost:8000;
proxy_set_headerX-Real-IP$remote_addr;
send_timeout5m;
keepalive_timeout5m;
gzipon;
}
}
Intheprecedingexample,thefollowingattributeswillbereplacedandtheconfigurationfilewillbecopiedtoaspecificdirectorywitharealvalue:
node["project"]["domain"]="http://mydomain.com"
node["project"]["logs_dir"]="/var/logs/project"
DatabagsAdatabagisaglobalvariabledefinedinJSONandaccessiblefromaserver.
Thefollowingisanexample:
{
"project":{
"dbdomain":"dbdomain.com",
"dbuser":"database_user",
"dbpassword":"database_password"
},
"run_list":[
"recipe[git::default]",
"recipe[nginx::default]",
"recipe[project::default]"
]
}
Intheprecedingexample,Dbdomain,dbuser,anddbpasswordarethedatabags.
DifferentusecasesThebestwaytolearnChefistoseereal-worldexamples.Wewillnotinstallandcreatenodesinthecurrentchapter,butwewillexplainthedependenciesofdifferentenvironments.MoredetailedinformationaboutinstallationoftheseenvironmentswillbeexplainedinChapter2,SettingUpanEnvironmentforChef-Solo.
PHPWordPressThissectionassumesthatyouarealreadyfamiliarwithWordPress.TosetupaWordPresssite,weneedthefollowingpackagesinstalledonanymachine:
ApacheWebserverMySQLDatabaseserverPHP
Chef-SolowillberesponsiblefordownloadingWordPressandconfiguringApacheandPHPalongwithitsdependencies.ChefSoftware,Inc.alreadyhasaWordPressrecipe.Wecanusethesamerecipetoinstallanewblog.
Python/DjangoapplicationInthisexample,wewillconfigureanodeforPythonapplication,assumingourPythonapplicationisbuiltinPythonusingaDjangoframeworkwithaMySQLdatabase.
Torunthewebserver,wewilluseNginx.Thecompleterequirementswilllooklikethefollowing:
PythonDjangoframeworkNginx
Asyoucansee,quitealonglistneedstobeinstalledonasystemtoworkproperly.Afterdefiningtherecipes,alltheinstructionsarewrittenincodefilesandafterexecutionoftheserecipes,theserverwillbeupandrunning.
Chefprovidesuswiththefacilitytoautomatetoachieveefficiency,scalability,reusability,anddocumentation.
AnoverviewofChefTheideaofChefistoautomatethewholeprocess;itisrarethatanysingleindividualknowseverythinginsuchalargeinfrastructure.Also,Chefhasalargecommunitythatparticipatestosolvelargeproblems.
ThebasicprincipleofChefisthattheuserknowseachbitoftheenvironment;forexamplewhicharethepackagesthatneedtobeinstalled,requirementsofyourapplications,andsoon.Thebestpersonforanyapplicationdevelopmentistheteamwhodevelopedthesystem.Whilecreatingasystem,theycanwritedowntherequirementsandeasilyconvertthemintoRubycode.
Moreover,anylargeorganizationusesanumberofdifferentpackagestohandlewebapplications,forinstance,youhaveaPythonapplication,runningonNginx,usinguWSGI,cachingwithmemcaheandredis,andusingElasticsearchforquicksearch.
Allthementionedpackageshavealistofdependencies.Onceyouhavetherecipes,youcanrunthemonceorseveraltimesonthesamesystemandtheresultswillbeidentical.Thechef-clientkeepstrackofthechangesinresources.Ifanyresourceitemisupdated,thenitrunstheresourceagainandmarksitassuccessful.
ChefisdesignedonaThinServer,ThickClientapproach.Theclientdoesnotneedcontinuouscommunicationtotheserver.Oncetheclientreceivesthesetofinstructions(cookbooks),itwillexecuteandreporttotheserver.Theserverisresponsibleforthedistributionofcookbooks,templates,environments,andsoon,viatheworkstation.Also,theserverwillkeepacopyofallconfigurations.
Moreover,whilecreatingtherecipes,anordershouldbemaintained.Aswehavealreadydiscussed,recipesarebasedonseveralresources.Eachresourcecontainsasetofactionsandareexecutedonebyone.Theresourcesexecutesequentiallyandtheorderneedstobemaintained.Forexample,ifyoutrytoinstallPostgreSQLbeforelibpq-dev,youwillgettheerrorofmissingdependencyandtherecipescriptwillexitwithanerror.
SummaryInthischapter,wehavediscussedChef,chef-client,andChef-Solo.WealsodiscussedsomecoreconceptsofChefandhadalookatdifferentusecases.Also,weelaborateduponcertainChefterminologiessuchasnodes,workstations,cookbooks,recipes,resources,roles,attributes,templates,anddatabags.
Inthenextchapter,wewilldiscussthecookbooksinmoredetailandsetupaLinuxmachinewithChef,andwillexecutesomeopensourcerecipes.
Chapter2.SettingUpanEnvironmentforChef-SoloWehavealreadydiscussedsomebrieftheoryaboutChef-Solointhepreviouschapter,butwecan’tgetanywhereuntilwe’veinstalledChef-Soloandhavehadahands-onexperiencewithChef.
Thischapterwillguideyouwithastep-by-stepinstallationofChef-Solo.Weneedsomeadditionalpackagestogetitworking.Also,wewillhavealookintotheconfigurationstogetitworking.
Wewillcoverthefollowingtopicsinthischapter:
InstallationonLinuxandUbuntuPrerequisitesofChef-SoloChef-SolocookbookConfigurationsDownloadingafewsamplecookbooksExecutionoftherecipes
InstallationonLinuxandUbuntuChefprovidesuswithanumberofwaystogetstarted.Wecangetitworkingusingdifferentmethods.Eachmethodhascertainadvantagesanddisadvantages.Chef-SolocanbeinstalledasaRubygem,oraDebianpackageandisnotavailableasRedHatPackageManager(RPM)packagesforRedHatbasedLinux.
Thedetailedinstallationmethodsarediscussedinthefollowingsections.
InstallingChefasaRubygemChefiswritteninRuby,andbeforegettingstartedwithChef-Solo,wehavetoinstallRuby.Theinstallationissimpleenoughanditrequiresonlytwopackagestogetstarted.Rubydevelopersmaypreferthisparticularmethodtogetstarted.
apt-getinstallRuby1.9.3Ruby1.9.3-devbuild-essential
ThiswillinstallRubyVersion1.9.1andalsoafewrequiredextensions.AfterinstallationofRuby,wecaneasilyinstallChefusingitasaRubygem.WecaninstallRubybyusingthefollowingsnippet:
gem1.9.3install--no-ri--no-rdocchef
Also,youcaninstalldifferentversionsofChefwithdifferentversionsofRuby.
Foradevelopmentmachine,thatisaboutallyouwillneedapartfromacookbook,andsomedependencies.
TheadvantagesofinstallingChefasaRubygemareasfollows:
Itisasimplemethodandeasiertoimplement.Rubydevelopersideallypreferthismethodtogetstarted.ItusesthecommonlyusedRubylibrariesandgems(extensions),andyouhavetorelyonRubygemglobally.Aswehavealreadydiscussed,Chef-SolowillusegloballyusedRubylibraries,andyourrecipescanuseanygeminstalledonyoursystem.
ThedisadvantagesofinstallingChefasaRubygemareasfollows:
AsRubyhasaverymaturesystemofRubyVersionManager(RVM),somedevelopersarenotverycomfortablewiththeRubyversiongloballyinuseasRVMenablesyoutohavemultipleRubyenvironmentsonthesamesystem,eachhavingdifferentRubyversionsandsoftware.Rubygemisnotinstalledasasystempackage.Itcanworkwellinasystemglobally,butcannotbeintegratedwiththeoperatingsystempackagemanager.Differentoperatingsystemsprovidedifferentmethodstohandlethepackages.
Also,asystemwideRubyinstallationandaRubygemwillnotensurethatyourrecipeswillworkperfectlywithspecificgemversions.Forinstance,ifyourrecipeisdependentonx-gem2,anx-gem3canbreakyourrecipe.
TipPleasenotethatapt-getpackagemanagerisavailableforUbuntu,andsimilarly,YumisavailableforRedHat.
InstallingChefasapackagemanagerInstallingChefasapackagemanagermethodinstallsChef-SolousingOpscode(ChefwasoriginallydevelopedbyOpscode)publishedpackagesfordifferentdistributionsandoperatingsystems.Theprocessisprettystraightforward.Thestepsareasfollows:
1. AddtheOpscoderepositorytoyoursystem.2. Createthenewfileas/etc/apt/sources.list.d/opscode.listoreditthe
mentionedfile/etc/apt/sources.list.3. Allthedistributionsarelistedathttp://apt.opscode.com/conf/distributions:
debhttp://apt.opscode.com/<codename>-0.10main
4. FetchandtrusttheOpscodeGPGkey.Installtheopscode-keyringpackageforautoupdatesbyusingthefollowingcommands:
$sudowget-O-http://apt.opscode.com/[email protected]|
sudoapt-keyadd-
$sudoapt-getupdate
$sudoapt-getinstallopscode-keyring
5. Finally,installChefbyusingthefollowingcommandline:
$sudoapt-getinstallchef
TheadvantagesofinstallingChefasapackagemanagerareasfollows:
Chefisinstalledasapackagehere,andcanbeeasilyupgradedusingapt-getupgrade.Itcanbeusedaspreinstalledonavirtualmachine(VM).WecaneasilyincludethepackagewithVMusingthevm-buildertool.
ThedisadvantageofinstallingChefasapackagemanagerisasfollows:
AddingkeysandaPPArepositoryisacomplexmethodtoinstallanypackage.ItwouldbegreatifChefgetsintroducedasacompletepackage.
UsingtheOmnibusinstallerTheOmnibusinstallerisafullinstallationandanexecutablescript.ThankstoOpscode,theyprovidetheexecutablescripttoinstallpackagesanddependencies.
Executethefollowingscriptbyusingthefollowingcommand:
$sudocurl-Lhttps://www.opscode.com/chef/install.sh|bash
TipCurlutilityisnotpartofUbuntu.Youcaninstallbyusingthefollowingcommand:
$sudoapt-getinstallcurl
Itwilldownloadtherecentversionandinstallalongwitheverydependency.Pleasenotethatinthebackground,thebashscriptwilldownloadthecompatibleversionandinstallit.InUbuntu,youcanlateruseDebianpackagemanagement(dpkg)toseetheinstalledOmnibuspackagesandremovethemifdesired.SoevenwithOmnibus,apt-getpurgechefwillworkcorrectly.
Theinstallationwillbeplacedinthe/opt/cheffolderanditwillcontainafullRubyinstallationinthe/opt/chef/embeddedfolder.
TheadvantagesoftheOmnibusinstallerareasfollows:
Personally,IpreferusingthismethodasitinvolvesverysimpleandeasystepstoinstallChef.IhavebeenusingitondifferentmachineswithgreatsuccessasitisolatestheRubyenvironmentandtherewillnotbemuchofachancetobreaktherecipes.Itprovidesacompletedebianpackage.Andlater,youcanupgradeitorremoveitwithasystempackagemanager.
ThedisadvantageoftheOmnibusinstallerisasfollows:
Third-partygeminstallationwillbedifficultandwhileexecutingtherecipes,weneedtouseafullpath(ifthepathisnotincludedintheglobalpath,youcanalwaysaddthegemdirectoryinthepathvariable)
PrerequisitesofChef-SoloWealreadydiscussedaboutinstallationsetupsforChef-Solo.IfyouareusingtheOmnibusmethod,youdon’tneedtoworryaboutanydependencies.However,forinstallationasaRubygemorpackagemanagement,pleaseensurethatthefollowingpackagesareinstalledonyourmachine.
Usethefollowingcommandtoinstalltherequiredpackages:
$sudoapt-getinstallRuby1.9.3build-essential
ForOmnibus,makesurecurlisinstalledonyourmachine:
$sudoapt-getinstallcurl
Tipcurlisacommand-linetoolfortransferringdatawithURLsyntax.ItsupportsvariousprotocolsincludingHTTP,FTP,andFTPS.
SomedependenciesforBerkshelfareasfollows:
$sudoapt-getinstalllibxslt-devlibxml2-devopensslzlib1g
ToensurethatChef-Soloinstallscorrectly,gototheterminalandwritethefollowingcommand:
$chef-solo-v
TheprecedingcommandwilldisplaytheChefversionasshowninthefollowingscreenshot:
CookbooksCookbooksareacollectionofrecipesandtheyconsistofbasicandfundamentalunitsofvariouspoliciesanddistributions.Eachcookbookcontainscompletesetupstoinstalleverydistributiononamachine.
Forinstance,weneedawebserver,soweareinstallingNginxtoactasawebserver.TheNginxcookbookshouldcontainallthepackagenamesthataredependenttoinstallNginx.Moreover,itshouldprovidestep-by-stepinstructionstothemachinetomakethishappen.
Let’shaveadetailedlookathowtodevelopacookbook.
ThefolderstructureCookbooksshouldideallyconsistofthefollowingfolderstructure.Astheyareacollectionofdifferentrecipes,whileexecutingtherecipebydefault,Chef-Solowilllookforadefaultfolder:
attributes
default.rb
files
default
file.txt
recipes
default.rb
templates
default
file.erb
metadata.rb
AttributesAswehavealreadydiscussedabouttheseterminologiesinthelastchapterhere,onceagain,wewilldiscusstheroleofeachfile.
Intheattributesdirectory,thedefault.rbfilewillbeusedtodeclareallvariablesthatwearegoingtouseintheexecutionofrecipesgivenoutinthefollowingcode:
default['nginx']['version']='1.4.4'
default['nginx']['package_name']='nginx'
default['nginx']['dir']='/etc/nginx'
default['nginx']['script_dir']='/usr/sbin'
default['nginx']['log_dir']='/var/log/nginx'
ThecodethatisusedhereistakenfromtheOpscodeNginxrecipeavailableathttps://github.com/opscode-cookbooks/nginx.
VariablesaredeclaredintheRubysyntax.Nowthroughouttherecipe,wecanusedefault['nginx']['version']togettheversionofNginx.
All.rbfilessupporttheRubysyntax,sowecanusecontrolstructuresforconditionaldeclarations.Inthefollowingexample,weareselectingannginxuserasperplatform:
casenode['platform_family']
when'debian'
default['nginx']['user']='www-data'
default['nginx']['init_style']='runit'
when'rhel','fedora'
default['nginx']['user']='nginx'
default['nginx']['init_style']='init'
default['nginx']['repo_source']='epel'
when'gentoo'
default['nginx']['user']='nginx'
default['nginx']['init_style']='init'
else
default['nginx']['user']='www-data'
default['nginx']['init_style']='init'
end
FilesThefilesfolderisusedtocopythefilestoyournewmachine.Forinstance,ifwehaveaconfigurationfileandwanttocopyittoaspecificlocation,wewillplaceitinthefilesfolderandcopythattoaspecificdirectoryasmentionedintherecipe.
RecipesTherecipesfolderistheplacewheretherealmagicoccurs.Intherecipesfolder,wehaveadefault.rbfilethatcontainsasetofinstructionstoinstallandconfigureanymachine.
ForinstallationonUbuntu,firstweneedtoupdatethepackages.ThefollowingcodewillbeusedtoupdateUbuntupackages.Addthefollowingcodeblockintherecipe:
execute"updateapt"do
command"apt-getupdate"
ignore_failuretrue
end
Afterupdatingsystemsapt,weneedtoinstallsomemandatorypackagestogetstarted:
%w{
curl
screen
vim
python-setuptools
libreadline-dev
libevent-dev
libpq-dev
}.eachdo|pkg|
packagepkgdo
action:install
end
end
Aswehavealreadydiscussedabouttheresources,eachresourceisresponsibleforperformingaparticularscenario.
Thepreviouscodeinstallsafewpackages.Firstly,itwritesallthepackagenamesthatneedtobeinstalledinthe%w{}blockandthen,eachdo|pkg|loopsthroughallpackages’listsandinstallsthemonebyone.
Thementionedresourcewillinstallcurl,screen,make,python2.7,andvimpackages.
Youmighthavenoticedduringinstallationthateachresourcehasdifferentattributes,whichcanbeusedtoperformaspecificaction.Similarly,wehaveadifferentresource,git,forperformingGitcloneandsubmoduleoperations.
Moreover,ifwewanttoexecutesomeshellscript,wecandothisviatheexecuteresource.ThefollowingisanexampleofthescriptresourcetoinstallPythonpackageswithPythonPackageManager(pip):
script"pip_install"do
interpreter"bash"
user"root"
group"root"
cwdnode[:project][:project_path]
code<<-EOH
#simpleshellcodecanbewrittenheretoexecute
gitcheckoutmaster
#assumingwehavepythonrequirementsfileindirectory,itcanbeused
intherecipebyusingthefollowingcode
pipinstall-rrequirements.txt
EOH
end
Thecodeblockgivenoutintheprecedingexamplewillexecuteasashellscript,checkoutthepreferredbranch,anditwillalsoinstallthePythonrequirementsfile.Youmighthavenoticedthatwehavesomestatementswiththe#sign.Thesevaluesareanattributethatwehavealreadyseenintheattributes:thedefault.rbfile.
UsingGitinaexecuteresourceisnotarecommendedpractice.PleaserefertotheGitcookbookandwecanusethegitresourcetoexecuteGitcommands.
Inthefollowingcode,wewilluseonefileandcopythattoourdesireddirectory:
cookbook_file"/home/user/file.txt"do
source"file.txt"
owner"root"
group"root"
end
Theprecedingcodeblockwillberesponsibletocopyfile.txtin/home/user/.
Foralistofcompleteresourcesandattributes,pleaserefertotheChefSoftware,Inc.documentationprovidedearlierinthechapter.
TemplatesTemplatesareEmbeddedRuby(.erb)files,bywhichyoucandisplaytheattributevalues.Theyareusedtocreateconfigurationfilesinournewmachine.AsampleNginxconfigurationfileisgivenoutasanexampleinthefollowingcode:
server{
listen80;
server_name<%=node['hostname']%>;
access_log<%=node['nginx']['log_dir']%>/localhost.access.log;
location/{
root<%=node['nginx']['default_root']%>;
indexindex.htmlindex.htm;
}
}
TipPleaserefertothefollowinglinkfordetailedinformationonERBfiles:
http://ruby-doc.org/stdlib2.1.1/libdoc/erb/rdoc/ERB.html
SamplefilecontainsthebasicconfigurationoftheNginxwebserver.Attribute<-=node['hostname']%>andotherattributeswillbereplacedbytheactualvalue(whichwehavedefinedintheattributesfile).
Youmayhavenoticedthatweusedadefaultfolderoradefaultfileineachinstance.Sowhatexactlyisdefault?WhilerunningtherecipeinChef-Solo,weneedtopassarecipename;chef-clientwilllookforthesamenameinthementionedfolder.Yourcookbookcanbeacollectionofmanyrecipes,imaginingyouarewritingacookbookfordatabase,anditcontainstwotypesofrecipes,thatisPostgreSQLandMySQL.Inthiscase,wehavetocreatetwofilesintheRecipesfolder,postgresql.rbandmysql.rb.Similarly,inattributes,files,andtemplates,eachrecipewilllookforthesamenamefolder/filenametouseasvalues.
Wecanmaintainonecookbookfordifferenttypesofdatabaseinstallations.Torunarecipe,wewillenlisttherecipenamesinrun_list[database::mysql]toinstallMySQL.Chef-Solowillusethefilesmentionedasfollows:
attributes
mysql.rb
files
mysql
file.txt
recipes
mysql.rb
templates
mysql
file.erb
Themetadata.rbfilecontainsthename,maintainerinformation,description,andsomedependencyinformationasfollows:
name'nginx'
maintainer'Opscode,Inc.'
description'Installsandconfiguresnginx'
version'2.4.3'
recipe'nginx','Installsnginxpackageandsetsupconfigurationwith
Debianapachestylewithsites-enabled/sites-available'
depends'apt','~>2.2'
DownloadingrecipesLet’sdownloadafewrecipesonatestenvironmentandexecutethemwithChef-Solo.
First,we’llmakeafoldernamedcookbooksanddownloadtheNginxrecipetoexecute.AswehavealreadyinstalledChef-Soloinourworkingenvironment,usethefollowingcommandtocreateafoldernamedcookbooks:
$mkdircookbooks&&cdcookbooks
$gitclonehttps://github.com/opscode-cookbooks/nginx
Gitprovidestwomethodstodownloadrepositoriestoalocalstorage.WecanuseGitand/orhttpsprotocoltoclonetherepository.Ourmainobjectiveistoplacecookbooksunderthecookbooksdirectory.
Chef-SoloconfigurationAfterhavingdownloadedafewrecipes,wewanttorunthoserecipesandmakethesystemready.Thesolo.rbfileisusedtospecifyalltheconfigurationdetails.Itsdefaultconfigurationisloadedeverytime.Byadefaultconfiguration,thefileexistsat/etc/chef/solo.rb,butwecanuseitwithacustompath.Thesolo.rbfilecancontainseveralsettingsbutmainlyitisusedforthecookbook’spath,databag’spath,environment,environmentpath,log_location,andsoon.
Youcanreadallthedetailedinformationabouteachconfigurationatwww.getchef.com.
Oursolo.rbfileisprettysimpleandcontainsonlyafewsettings.
Createanewsolo.rbfilewiththefollowingcontent:
file_cache_path"/var/chef/cache"
file_backup_path"/var/chef/backup"
cookbook_path["/home/<username>/cookbooks"]
#Analternativeandmoreuseablemethodistouserubycodetoget
directorypath
cookbook_pathFile.expand_path('/cookbooks')
log_level:info
verbose_loggingfalse
Nowcreateanothernginx.jsonfile(anynamecanbeused)toinstructChef-Solotoexecutetherecipeasfollows:
{
"run_list":[
"recipe[nginx::default]"
]
}
ExecutionofrecipesNowwehaveeverythinginplace,let’sexecutetherecipetoinstallNginx.
$chef-Solo-c./solo.rb-jnginx.json
Pleasenotethattheprecedingcommandwillfailwithanerrorbecausetheotherrequiredcookbooksarenotthere.ToinstallanNginxrecipe,weneedsomeotherdependentrecipesinthecookbooksfolder.
AsyounoticedintheNginxcookbooks/metadata.rbfile,theNginxrecipeisdependentonthefollowingrecipes.Beforeproceeding,wewilldownloadthecookbooksthatcontaintherequiredrecipeswithinthecookbooksfolder.Intheupcomingchapters,we’lllearnhowtodownloadandexecuterecipeswithadependencyresolver(forexample,Berkshelf):
depends'apt','~>2.2'
depends'bluepill','~>2.3'
depends'build-essential','~>1.4'
depends'ohai','~>1.1'
depends'runit','~>1.2'
depends'yum','~>3.0'
depends'yum-epel'
depends'rsyslog'
Afteryouhavedownloadedalltheprecedingrecipes(pleasenotethatyoumustdownloadallthedependenciestoinstallNginx),ourfolderstructurewilllooklikethefollowing:
cookbooks
nginx
apt
bluepill
build-essential
ohai
rsyslog
runit
yum
yum-epel
solo.rb
nginx.json
Let’sdownloadtheserecipesfromGitandexecutewithChef-Solo.Aftercompletingtherecipe,youshouldbesuccessfulandaservice[nginx]startedmessagewillappear,asshowninthefollowingscreenshot:
Nginxisinstalledandreadytouse.Crosscheckifitisinstalledproperlybyusingthecurlcommandortypelocalhostinthebrowser.
ItshoulddisplaytheWelcometonginx!page.
DownloadsomesamplecookbooksforApache2,MySQL,andinstallthemviaChef-Solo.Also,youcaninstallvariousrecipesusingonesinglerecipeasshowninthefollowingcodesnippet:
{
"run_list":[
"recipe[nginx::default]",
"recipe[git::default]",
]
}
Addtherecipesinrun_listandChefwillexecutetherecipesforyou.
SummaryInthischapter,wehaveinstalledChef-SoloonourUbuntumachine,anddiscusseditindetailcoveringcookbooksandtheirstructure.Wealsocoveredsomestep-by-stepinstructionsonhowtoruncookbooksusingChef-Solo.WealsohadalookintoChef-SolocustomconfigurationandusedJSONtorunrecipes.
Inthenextchapter,wewilldiscussmoreindetailaboutcookbooksandwilldevelopthemforacompletesystemenvironment(Python,Django,Nginx,MySQL,anduWSGI).
Moreover,wewilllookintothecommunitymaintainedrecipestoinstalldifferentapps.
Chapter3.SettingUpaDevelopmentEnvironmentInthepreviouschapter,weinstalledChef-SoloonourlocalenvironmentandexecutedrecipeswithNginx.However,imagineifwewereworkingondifferentprojectsandsomeprojectsrequiredifferentwebserversandconfigurations.Itwouldbedifficulttoinstalleverythingonthesamesystem.
Inthischapter,we’llinstallVirtualBoxwithVagranttosetupourboxandexecutedifferentrecipesindifferentboxes.
Wewillcoverthefollowingtopicsinthischapter:
IntroductiontoVirtualBoxSettingupVagrantExecutingtheNginxrecipewithVagrantCreatingahelloworldrecipe
IntroducingvirtualmachineVirtualmachineisasoftwareimplementationthatexecutesandrunsanoperatingsystemlikeaphysicalmachine,andanyprogramcanrunonthisnewmachine.
VirtualmachineprovidesvariousadvantagesovertheinstallationofOS.Mainly,virtualmachinesfordifferentemulatorsandincloud-basedarchitectureprovidetotalisolation,andacompleteisolationensuresthatanyservicesorpackagesarenotaffectingyourmainOS.Moreover,youcaneasilycreate,delete,export,andimportdifferentenvironments.Manylargehostingprovidersusevirtualmachinesforbackups,disasterrecovery,deployments,andadministrationtasks.
OperatingsystemtaskssuchasCPUusage,memory,harddisk,andUSBaremanagedbythevirtualizationlayer.Thevirtualizationlayertranslatestheserequeststotheunderlyinghardwarelayer.
Mainly,virtualmachinesareclassifiedintotwolevelsbasedontheiruse.Theyareexplainedinthefollowingsections.
SystemvirtualmachinesSystemvirtualmachinesprovideacompleteoperatingsystem,andyoucaninstallanysoftwarelikearealmachine.Itusuallyusesthesamearchitectureandisbuiltwithapurposetotestorrunprogramsinarealenvironment.Forexample,MicrosoftprovidesvariousversionsofWindowswithdifferentInternetExplorerversions.Windowsvirtualmachinesareusedtocheckthebrowsercompatibility.Forinstance,wewouldwanttocheckoursiteinIE8,IE9,andsoon.Forthis,wecaninstalldifferentVMsonthesamemachine.MicrosoftprovidesfreeVMsthatarelicensedspecificallyforbrowsertesting,onlyathttp://www.modern.ie/en-us/virtualization-tools.Moreover,incloudcomputing,virtualmachinesareusedtoprovideaplatformtorundifferentenvironments.Itisanefficientuseofamachineintermsofhardwarecostandsystemeffectiveness.
ProcessvirtualmachinesAprocessvirtualmachine(alsocalledanapplicationvirtualmachine)executesasanormalapplicationonanoperatingsystemandsupportsonlyasingleprocess.Thepurposeofprocessvirtualmachinesistoprovideaplatform-independentprogrammingenvironmentthatabstractsdetailsoftheunderlyinghardwareandtransformsanapplicationintoaportablesoftware.Whenanapplicationstarts,itwillinitiateoneprocess,andwhenitexits,itwilldestroytheprocess.Itprovidesahighlevelofabstractionandcanbewritteninanyhigh-levelprogramminglanguage.Unlikesystemvirtualmachine,itallowsustoperformspecifictasksonanoperatingsystem.GoodexamplesofprocessvirtualmachinesareJVM,Microsoft.NETFramework,andLua.
VirtualmachineswereoriginallydefinedbyPopekandGoldbergas“anefficient,isolatedduplicateofarealmachine”.
Therearevarioussoftwareavailableassystemvirtualmachines.Theyareasfollows:
VirtualBox:VirtualBoxoffersmanyfeaturesfreeofcharge,supportedbyOracle.Configurations(virtualmachine’sparametersanddescriptions)arestoredintheXMLfiles.Itprovidesyouwithaneasyinterfacetoexportsettingsfromoneboxtoanother.ItisavailableforWindows,Linux,andMacOSathttp://www.virtualbox.org/.Parallels:ParallelsisbestforMac,butitisavailableforWindowsandLinuxaswell.Parallelsoffersclipboardsharing,synchronization,andsharedfoldersbetweentwomachines(likeothercompetitors).WhenyouswitchfromyourbaseOStoavirtualmachine,itautomaticallyincreasestheprocessingpowertothatofthevirtualmachine.ThebasepriceofParallelsisaround80USD.Itisavailableathttp://www.parallels.com/.VMware:VMwareprovidestwokindsofboxes:VMPlayerandVMWorkstation.VMPlayerisusedforprimarypurposesandprovidesabasicfunctionalitytotestthebasiccontentinyourbox.Meanwhile,VMWorkstationisafull-fledgedboxthatprovidesvariousmethodstocreate,export,andcloneabox.Also,ithasthecapabilityofhardwareoptimization,driver-lessprinting,andsoon.AttheEnterpriselevel,it’sleadingintheindustryandcostsaround200USD.
Also,vSphereisanotherserversolutionfromVMware.It’sacompletesuiteandhasacombinationofvCenter,ESXi,vSphereclient,andsoon.
Fordetailedinformation,pleaserefertotheVMwaresiteathttp://www.vmware.com/.
QEMU-KVM:QEMU-KVMisaforkoftheQEMUproject,anditisavailableforonlyLinuxmachines(thelatestversionis2.0RC).Itisapowerfulsystemwithabuilt-inLinuxkernel-basedvirtualmachine.ThemainfeatureofQEMUisthatitcanexecuteaguestmachineonthehosthardware.Thismeansyoucancarryyourboxwithyouandexecuteitwithouthavingadministrationpermissions.Withoutadministrationaccess,itcanbeusedtobuildthumb-drive-basedvirtualmachines.Thumb-drive-basedvirtualmachinesaresoftwarethatcanrunonflashdrives.For
example,GoogleChrome,PortableUbuntu,andsoon.Andyes,wecanuseitfreeofcharge.WindowsVirtualPC:ThisisavailableonlyforWindowsandoffersaverybasicfunctionality.ItprovidesavirtualmachineforWindows,andyoucaninstallearlierversionsofWindowsonit.ItisdesignedforusergroupsthatarestrictlyusingtheWindowsenvironmentandneedtotestapplicationsonearlierversions.
We’llusetheVirtualBoxandinstallUbuntuVersion12.04togetstarted.TheinstallationofVirtualBoxissimple.Luckily,VirtualBoxisavailableinthemainapt-getrepository,andwecaninstallitwiththefollowingcommand:
$sudoapt-getinstallvirtualbox
IfyouareusingSynapticonUbuntu,itwillbeavailableinthesoftwarelistorcanbeinstalledbyUbuntuSoftwareCenter.
BeforerunningaVirtualBox,pleasemakesurethatCPUvirtualizationisswitchedoninyourBIOS.Pleasenotethatnotallx86systemscannotvirtualize.
VirtualBoxprovidesvariousboxestoinstalldifferentoperatingsystems.Thelistoftheoperatingsystemscanbefoundatthefollowinglink:
http://virtualboxes.org/images/
Inourcase,weneedabox,butwedonotactuallyneedagraphicalinterfacetoperformindividualtasks.Wecanusesomeautomateddeploymenttools,suchasVagrant,toaddabox(aboxisaVagranttermusedtodescribeanykindofvirtualmachinethatVagrantmanages)andexecuteourrecipesinanewsystem.
SomeadvantagesofusingVagrantarementionedinthefollowingpoints:
VagrantisanautomatedtoolthatfacilitatestoautomatethevirtualenvironmentWecanmanagevirtualmachinesusingVagrant
Vagrantisanopensourcetoolformanagingvirtualmachines.ItwasdevelopedbyMitchellHashimotoandJohnBender.ItcanbeusedtomanagevirtualmachinesinVirtualBox,afullx86virtualizerthatisalsoopensource(GPLv2).Initially,itwastiedtoVirtualBox,butafterVersion1.1,it’snolongerrelatedtoVirtualBoxandcanbeusedwithVMwareandAmazonEC2.ThecurrentversionsalsosupportMicrosoftHyper-V.ThereisanoptionalpluginforGoogleComputeEngine.
Vagrantprovidessimplemethodstoarrangereproducibleandtransportableworksituations.Itisolatesthedependenciesandconfigurationsinasinglefile.Withasinglecommand,yoursystemwillbereadytouse.Also,itprovidesamethodtoexecuterecipeswithaVagrantfile,soyourenvironmentwillbereadywiththevagrantupcommand.
TheinstallationofVagrantcanbedoneusingaDebianpackage(DebianpackagesworkonbothDebianandUbuntumachines).WeneedtodownloadtheDEBfilefromhttps://www.vagrantup.com/downloads.html.
Downloadtheversionasperyouroperatingsystemandinstallit.Inourcase,wewilldownloadtheDebianUbuntuversion.
NoteWeneedtoinstallthefollowingversionsofVirtualBoxandVagrant:
VirtualBox:4.3Vagrant:1.5.3
Vagranthassomebasiccommandsthatcanbeusedfordifferentpurposes.Theyareelaboratedinthefollowingtable:
Command Function
$vagrant
initThiscreatesabasicconfigurationfilewithdefaultsettings
$vagrantupThisstartsanewmachineassettingsdefinedinVagrantfile(theconfigurationfileforaVagrantproject)
$vagrant
suspendThissuspendstherunningguest
$vagrant
haltThisstopstherunningmachineandsendsashutdownsignaltothemachine
$vagrant
resumeThisresumestheVagrantmachinethatwassuspendedearlier
$vagrant
reloadThisreloadsthecurrentguest
$vagrant
statusThisisusedtocheckthestatusofVagrantwithVagrantfile
$vagrant
provisionThisisusedtoexecutetheprovisioningcommandsonabox
$vagrant
destroy
Thisisusedtodeletethecurrentinstanceoftheguest;thiscommandwilldeletethevirtualdiskandeveryfilealongwitheverysetting
$vagrantboxThisisusedtohandleboxcommands,suchasadd,list,remove,andrepackagefilestodeletethecurrentinstanceoftheguest
$vagrant
packageThisisusedtopackagethecurrentboxenvironmentintoareusablebox
$vagrantssh ThisisusedtologintoarunningmachineusingSecureShell(SSH)withaVagrantuser
$vagrant
plugin
Thisallowsustomanagepluginssuchasvagrant-omnibus,vagrant-aws,andvagrant-windowsthatextendVagrantwithmorefunctionalities
Now,inournextstep,wewilladdaboxintheVagrantmachineandcreateaVagrantfiletogetstarted.
Tip
Vagrantboxesarefreelyavailableinawidevariety.Wecandownloadadifferentoperatingsystemfromhttps://vagrantcloud.com/.
Toaddabox,usethefollowingcommand:
vagrantboxaddhashicorp/precise32
YoucanalsouncommentthefollowinglineinVagrantfile:
config.vm.box='hashicorp/precise32'
TheprecedingcommandfindsthecurrentURLforprecise32fromHashiCorp(thecompanybehindVagrant),downloadsit,andenablesyoutoreceiveupdatestothatbox.
Thevagrantboxaddcommandwilldisplaythemessageasshowninthefollowingscreenshot:
Now,ourboxhasbeensuccessfullyadded.WestartthismachineandloginviaSSH,asshowninthefollowingcommands,tomakesurethateverythingisfine:
#precise32isnameofbox
$vagrantinitprecise32
Thisisdemonstratedinthefollowingscreenshot:
VagrantcreatedVagrantfileinthesamedirectory.However,beforelookingintothisfile,wewillstartourmachineandloginviaSSHusingthefollowingcommand:
#Tostartmachines
$vagrantup
Thisisdemonstratedinthefollowingscreenshot:
Now,ourtestmachineisready.UsingSSH,wecanlogintoanewmachineandcheckwhethereverythingisinstalledperfectlyornot.Now,itbehaveslikeafull-fledgedUbuntumachine.Wecanuseitforseveralpurposes.
$vagrantssh
Usingtheprecedingcommand,wewilllogintoanewmachineusingSecureShell(SSH)withaVagrantuser.
Underthehood,Vagrantwillsetupavirtualmachineonalocalmachine.Bydefault,port2222ofyourlocalmachineisusedtoconnecttoport22ofthevirtualmachine.Itgeneratesaprivatekeyandkeepsitunderthe.vagrantdirectory.Youcanaddadditionalsettingsusingthevagrantssh.configcommand.Moredetailedinformationonssh.configcanbefoundatthefollowinglink:
http://docs.vagrantup.com/v2/vagrantfile/ssh_settings.html
Usingthevagrantsshcommand,youwillseethefollowingoutput:
Onceyouareloggedintoamachine,youcanlogoutusingtheCtrl+Dcommand.
ExecutingrecipeswithVagrantOurnewmachineisready.Now,wecaninstallChef-Soloonit,aswediscussedinthepreviouschapter.Eventhoughitisatedioustask,wewillcoveritsmoothlyusingVagrant.
VagrantallowsustoautomatethisprocesswithVagrantfile.WehavealreadycreatedaVagrantfile.Now,let’shavealookatthefileandexecutearecipewithit.
ThemainobjectoftheVagrantfileistodescribetheprecisesortofmachineneededforaparticulartaskandtoexplainhowtoprovideconfigurationsandasetoftaskstoanewmachine.OneprojectcontainsoneVagrantfilethathasthefootprintofanewmachine.
Here,youmightbethinkingifVagrantprovidesuswiththebasicfootprint,whydoweneedotherconfigurationtoolstosetupthemachine?ThemaindifferenceisVagrantcancontainonlyabstract-leveltasks,andallactivitiescanbeperformedinabox,butChef-Solohastheabilitytomanagethewholemachine.Also,Vagrantisdesignedtohandlevirtualmachines.TheVagrantfilesyntaxisinRuby.It’snotmandatorytohavereasonableknowledgeofRuby.Wejustneedsomebasicsyntaxtoconfigureourmachine.
AswehavealreadycreatedVagrantfile,ifwetakealookatthefile,ithasalotofcommentedcodeinsideit.Ithasasetofinstructionsthatwecanconfigurestepbysteptocustomizeourmachine.
Let’ssetupsomebasicconfigurationsandprovisionourmachine.
ProvisionProvisioningisaprocessinVagrantthatallowsyoutoalterconfigurations,installthird-partysoftware,andperformmanyothertaskswiththevagrantupcommand.
WecaninstallsoftwarefromSSHtoanymachine,butprovisioningallowsustoperformthesameactioninanautomatedway.Forinstance,ifwewantapt-getupdateoneveryrunofthemachine,wecaneasilyautomatethistaskusingthefollowingcodementionedinVagrantfile:
config.vm.provision"shell"do|s|
s.inline="apt-getupdate"
end
YoucanprovisionVagrantusingthefollowingcommands:
Forthefirsttime,vagrantupisused.Itprovisionsthenewmachines;afterthat,weneedtoprovidethe–provisionflagtoprovisionthemachine.AftermodifyingVagrantfile,thevagrantprovisioncommandwillservethepurpose.Thevagrantreload–provisioncommandwillrebootthemachinealongwithprovisions.
Moreover,ifyoudonotwantanynewprovisionsonanexistingmachine,weneedtousethe--no-provisionflag.
Let’smakesomechangesinourmachineandprovisionit.
InVagrantfile,uncommentthefollowingline:
config.vm.synced_folder"../data","/data"
Intheprecedingline,thefirstargumentistheactualfolderinouroperatingsystem,andthesecondargumentisavirtualfolderthatneedstobecreatedinthevirtualmachine.
Inthepreviouschapter,werantherecipewithChef-Solo.Now,wewillrunthesamerecipewithVagrantbox,forwardtheport8080tovagrant80ports,andcheckwhethereverythingworksornot.
MovetotheVagrantfileChef-Soloblock;itwilllooklikethefollowingcode:
config.vm.provision"chef_solo"do|chef|
chef.cookbooks_path="../data/cookbooks"
chef.roles_path="../data/roles"
chef.data_bags_path="../data/data_bags"
chef.add_recipe"mysql"
chef.add_role"web"
#YoumayalsospecifycustomJSONattributes:
chef.json={:mysql_password=>"foo"}
end
Now,uncommentthelineofcookbooks_pathandaddarecipeline.OncewearedonewithourNginxobject,we’lllookintothis.
Createafoldernamedcookbooksonefolderupanddownloadthenginxrecipefromhttps://github.comasshowninthefollowingsetofcommands:
$mkdircookbooks
$cdcookbooks
$gitclonehttps://github.com/opscode-cookbooks/nginx
Updatethecookbooksfolder’spathinVagrantfile:
chef.cookbooks_path="../cookbooks"
#updaterecipenameinadd_recipe
chef.add_recipe"apt"
chef.add_recipe"nginx"
PleasenotethatVagrantshipswithChefVersion10,butChef10isalreadyoutdated,andallnewrecipesarecompatiblewithChef11.
ToinstallChef11,wehavetwomethods.WecaneitherdownloadtheboxwithChef11,whichisavailableontheVagrantboxsite(http://www.vagrantbox.es/)orusethevagrant-omnibusplugintoinstallit.
TheomnibuspluginallowsustoinstallanyspecificversionofChef,orwecanwritelatesttodownloadandinstallthelatestversion.
Fortheinstallationofthevagrant-omnibusplugin,runthefollowingcommand:
$vagrantplugininstallvagrant-omnibus
Thisisdemonstratedinthefollowingscreenshot:
Now,it’stimetoopenVagrantfileandspecifytheomnibuspluginsettings:
config.omnibus.chef_version=:latest
TheprecedinglinewillmakesurethatthelatestversionofChefisinstalledonourbox.
Now,startthemachineusingthefollowingcommand:
$vagrantup
Beforestartingthemachine,Chef11willbeinstalledonourbox,andwewillseetheoutputwithChefVersion11.However,here,ourrecipefailsbecausethedependenciesarenotbeingresolved,asshowninthefollowingscreenshot:
Let’sdownloadallthedependenciesandtryagain.
Thedependenciesforthenginxrecipeareasfollows:
apt
bluepill
build-essential
ohai
runit
yum
yum-epel
rsyslog
Afterdownloadingalltherecipes,reloadtheboxagainusingthefollowingcommand:
$vagrantprovision
Provisiontheboxagain.Thenginxreciperansuccessfully.Nginxisreadyintheboxandisabletoreceiveconnections.
SSHtoboxandchecktheNginxserviceusingthefollowingcommand:
$psaux|grepnginx
YoucanalsochecktheNginxserviceusingthefollowingcommand:
$curl127.0.0.1
Itwillgiveoutaresult,asshowninthefollowingscreenshot:
Nginxinstallsperfectly.Now,ournexttaskistoforwardport8080tobox80connections.
UncommentthefollowinglinementionedinVagrantfile,anditwillservethepurpose:
config.vm.network"forwarded_port",guest:80,host:8080
Gotohttp://127.0.0.1:8080/,anditshoulddisplaytheNginxpage.Now,wehaveacompleteboxready,withNginxinstalledinouroperatingsystem.
YoucanfindthecompleteVagrantfileinthecodeexample.
CreatingaHelloWorldrecipeNow,ournexttaskistocreateasimplePHPproject,andwhenweaccesshttp://localhost:8080,itshoulddisplayourHelloWorldpage.
Todoso,weneedPHP5andApache2.
Now,wecandestroyouroldboxandstartanewonewithvagrantup.Alternatively,wecancreateanewboxwithApache2andPHP.
UsethesameVagrantfileandreplaceNginxwithApache2.
NotethatApache2hasthefollowingdependencies.Beforewestart,weneedtocloneindividualcookbooksintoourcookbooksfolder.
It’satedioustasktoclonetherepoonebyone.Inthenextchapter,wewilluseasoftwaretooltoresolvethedependencies.
TheApache2dependenciesareasfollows:
apt
iptables
logrotate
pacman
ChangetheNginxconnectiontoApache2,removetheoldbox,andcreateanewboxusingthefollowingcommand:
$vagrantdestroy
$vagrantup
Therecipeswillexecute,andwehaveournewApache2boxinstalled.Gotohttp://127.0.0.1:8080,andwewillseeApache2’spage.
OurnextstepistocreateaPHPproject,whichcanbedoneasfollows:
1. Createanewfolderincookbooks:
$mkdirdemoapp
2. Thefolderstructureofthecookbookwilllookasfollows:
demoapp
attributes
default.rb
files
default
test.php
recipes
default.rb
metadata.rb
README.md
3. Createthefolderstructureandcreatefiles.Theimportantbitofthecookbookisdefault.rb:
$mkdirattributes
$mkdirtemplates
$mkdirfiles
$mkdirrecipes
$touchmetadata.rb
$touchREADME.md
$touchattributes/default.rb
$touchrecipes/default.rb
$mkdirfiles/default
$touchfiles/default/test.php
4. Now,ourfolderstructureisready.Thenextstepistocreatearecipe.First,wewilldisablethedefaultApachesite.Addthefollowingcodeblockintherecipes/default.rbfile:
apache_site"default"do
enabletrue
end
Inthenextstep,wewillcopythetest.phpfileinthe/var/wwwdirectory.Thefollowingcodeblockwillmovethetest.phpfileinthe/var/wwwdirectory:
cookbook_file"/var/www/test.php"do
source"test.php"
owner"root"
group"root"
end
Thecookbook_fileresourcewillcopythefileintothespecifiedlocation.
Afterthecompletionoftherecipe,weneedtoinstructVagranttoinstallourdemoappcookbook:
config.vm.provision"chef_solo"do|chef|
chef.cookbooks_path="../cookbooks"
chef.add_recipe"apt"
chef.add_recipe"chef-dotdeb"
chef.add_recipe"apache2"
chef.add_recipe"apache2::mod_php5"
chef.add_recipe"demoapp::default"
end
Beforeexecutingourrecipe,weneedtosetupourenvironmentusingapt,dotdeb,andapache2cookbooks.Themod_php5recipeispartoftheapache2cookbook,anditwillinstalleverydependencyneededforPHP.Then,wecanexecuteourrecipetosetupourprojectinanewvirtualmachine.
Ourfirstrecipeisprettysimpleandjustresponsibleforcopyingonefiletoaspecificlocation.However,forthecompleteproject,thismethodishecticandtedious.
Afterrunningtherecipe,browseto127.0.0.1:8080/test.php,andyoushouldbeabletoseethePHPfilecontent,asshowninthefollowingscreenshot:
Inthenextchapter,wewilldeployWordPresswithPHPandMySQL.
SummaryInthischapter,wediscussedvirtualmachinesanddifferentproviders.Welookedintosomedifferentsoftwareusefulforvariousoperatingsystems.Then,weinstalledVirtualBoxinourenvironment.
WeinstalledVagrant,anautomateddeploymenttool,withVirtualBox,andinstalledtheChef-Soloplugintoexecuteourrecipes.Wecreateddifferentboxeswithdifferentconfigurations.
WelookedatthedefaultChefversionandupgradedourboxwiththelatestChefversionaspertheindustrystandards.Then,weexecutedsomerecipesanddevelopedonesimplerecipeinPHPtogetstarted.
Inthenextchapter,wewilldiscussmoreaboutcookbooksandthedependency’resolver.Moreover,wewilldeployourfull-fledgedWordPresssiteusingChef-SolointheVagrantbox.
Chapter4.DevelopingCookbooksWehavealreadydiscussedthefolderstructureandsomebasiccontentofcookbooks.It’sdifficulttocreatefoldersonebyoneinaspecificmannerandcreatefilesinsidethem.
Inthischapter,wewilldiscusscookbooksindetail;wewillalsodiscusshowwecanavoiderrorswhiledevelopingcookbooks.Chefcomeswithsomehandytoolstoinitializethefolderstructuresofcookbooks.
Inthischapter,wewilllookatthefollowingtopics:
WhatisKnife?TheinstallationofKnifeBerkshelfCookbooks’contentsRecipes,metadata,attributes,andresources
ExploringKnifeInaChefinfrastructure,KniferunsfromthecommandlineandinteractsbetweentheChefserverandchef-client.Ithelpsmanagecookbooks,nodes,roles,andsoon.
AsweareworkingwithChef-Solo,wewilluseKnifetoinitializeanddownloadourcookbooks.InanenterpriseChefenvironment,Knifecomeswithmanyhandycommandsandcanbeusedformanagingdifferentnodesanduploadingcookbooks,databags,roles,andmuchmore.AcompletelistofKnifecommandscanbefoundathttp://docs.opscode.com/.
Also,Chefprovideschef-dk,whichincludesallthenecessarypackagesyouneedtogetstartedwithChef.ItincludesBerkshelf3.0andTestKitchen(anintegrationtestingframework).
TherearenoextrastepsinvolvedintheinstallationofKnife.KnifeisapartofChefserverandgetsinstalledwithChef.AswehavealreadyinstalledChefonourmachine,let’sconfirmtheinstallationofKnifeusingthefollowingcommand:
$knife–v
Theprecedingcommandwillgiveoutanoutputasshowninthefollowingscreenshot:
DevelopingrecipesandcookbooksCookbooksarecollectionsofrecipes,andcontaineachstepofinstructions.AswealreadyhaveKnifeinstalledonourmachine,let’screateabasicfolderschemaforacookbook.OurgoalistodeveloparecipethatwillinstallPHP,MySQL,Apache2,andWordPress.
Thenameofourcookbookiswpblog:
$knifecookbookcreatewpblog
Bydefault,theprecedingcommandwillgeneratethecookbookstructureinthe/var/cheffolder.Incaseofanyotherfolderpath,usethe-oflag.
$knifecookbookcreatewpblog-o<cookbooks_folder_path>
Theprecedingcommandwillyieldanoutputasshowninthefollowingscreenshot:
Nowthatwehavesuccessfullycreatedafolderstructureofacookbook,let’stakealookatitandaddsomefilestogetstarted.
Thefolderstructureofwpblogwilllooklikethefollowingscreenshot:
Asourfolderstructureisalreadycreated,let’screateadefaultrecipeusingthefollowingstepstoexecuteandcreateVagrantboxtotestourrecipe:
1. Asstatedinthepreviouschapter,createthevagrantfileandaddanewboxusingthefollowingcommands:
$vagrantboxaddprecise32<box_path>
$vagrantinit
2. Editthevagrantfileinthesamedirectoryandaddtheboxnameandcookbook’spath:
chef.cookbooks_path="../my-recipes/cookbooks"
3. Addtherecipenameinchef.add_recipewpblogandexecutethebox.4. Aftertheexecutionofthesecommands,ourbaseboxiscreatedwithanUbuntu
image.Forverification,wecanlogintoanewboxusingSSHandcheck.5. Now,let’sfindoutsomedependenciesforourPHPapplicationanddownloadthe
relevantcookbooksfromhttp://community.opscode.com.
Apache2dependenciesarementionedintheapache2/metadata.rbfile:
$knifecookbooksitedownloadapache2
$knifecookbooksitedownloadapt
$knifecookbooksitedownloadbuild-essential
$knifecookbooksitedownloadiptables
$knifecookbooksitedownloadlogrotates
$knifecookbooksitedownloadpacman
6. Afterdownloadingalltherecipes,youcanextractthefilesonebyone,orasimpleLinuxcommandcandothisforyou:
$ls*.tar.gz|xargs-itarxf{}
7. Now,everydependencyofApache2ispresentinthecookbooksfolder.Openthemetadata.rbfileinthewpblogrecipeandaddApache2independs.
8. Thenextstepistocreatethedefault.rbfileandaddthefollowingblocktoinstallApache2:
#createfilecookbooks/wpblog/recipes/default.rb
$touchdefault.rb
9. Addthefollowinglineindefault.rb:
include_recipe"apache2"
10. Now,forwardthe8081porttothe80vagrantandprovisionthevagrantboxusingthefollowingcommands:
#PortforwardinginVagrantfile
config.vm.network:forwarded_port,guest:80,host:8081
#Provisioningthebox
$vagrantprovision
11. Oncetheprovisioniscompleted,openthebrowserandtypehttp://localhost:8081/,asshowninthefollowingscreenshot:
12. Now,Apache2isinstalled.ThenextstepistoinstallsomepackagesinourboxandsetupApachewiththehelpofourrecipe.
BerkshelfAswenoticedinthepreviouschapter,itisverydifficulttomaintainanddownloadtherecipesonebyoneandkeepatrackofthem.Chefcomeswiththefollowingtwopluginsthathelpusovercomethisproblem:
Librarian-ChefBerkshelf
Botharetoolstomanagedependentcookbooks.
Librarian-ChefisusedtofetchthecookbooksfromthecentralrepositoryandinstallthemusingKnife.It’sabundlertoresolveeverydependencyofanapplication,download,andinstallation.Also,ithasthecapabilitytodownloadpublicandcommunitycookbooks.
EachcookbookcancontainoneCheffileandallthenecessaryinformationtodownloadthecookbooks.
Thefollowingisanexample:
site"http://community.opscode.com/api/v1"
cookbook"git"
cookbook"timezone","0.0.1"
cookbook"rvm",
:git=>"https://github.com/fnichol/chef-rvm",
:ref=>"v0.7.1"
cookbook"nginx",
:path=>"/cookbooks/nginx"
CheffileisusedtodownloadtherecipesfromGitoranyothersource.Beforetheexecutionofthemainrecipe,chef-clientwilldownloadtherecipesfromsourcesandinstallthemonanewnode.
Berkshelfhasalmostthesamefeatures,butsomeofthemhavemoreadvantagesthanLibrarian-Chef.Inanabstractlevel,Librarian-Chefmaintainsallthecookbooksinacentralrepository;ontheotherhand,withBerkshelf,wecaneasilyclone,edit,anduploadindividualrecipes.
TheLibrarian-Chefcommandworksonlyinacookbooksfolderpath(whichwespecifyinknife.rb)andlooksfortherelevantcookbookspecifiedinCheffile;ontheotherhand,theBerkshelfcommandworkssystemwideandcandownloadtherelevantrecipes.
WorkingwithBerksfileiseasierthanworkingwithCheffile.EachcookbookcancontainoneBerksfile;thismeansthateachcookbook’sdependencycanberesolvedindividually.So,wedonotneedtoworryordownloadtherecipesonebyonetoexecuteourownrecipe.
Beforeexecutionofanyrecipe,Berkshelfwilllookforeverydependencyinthedepends.rbfileanddownloaditinthecookbooksfolder.Thefolderstructureofcookbookswilllookasfollows:
wpblog
cookbooks
php
apache2
mysql
wpblog
Afterspecifyingthedependencyofwpblog,Berkshelfwilldownloadeachdependencyoftheindividualrecipeandexecuteitonthesystem.Berkshelfallowsustomanagecookbooksasfirst-classcitizens.
WithoutBerkshelf,thewholeprocedureofdownloadingandunpackingcookbooksisdifficultandtedious.
TheinstallationofBerkshelfBeforecreatingBerksfileforourrecipe,weneedtoinstalltheBerkshelfpluginforVagrant.VagranthasanawesomepluginforBerksfile;itworksperfectlywithBerkshelf.
$vagrantplugininstallvagrant-berkshelf
TipThelatestversionofVagrantis1.5.x,andvagrant-berkshelfVersion2.0.0.rc3iscompatiblewiththelatestVagrantandVirtualBox4.3.Also,itisdependentonthegeocodeRubygem.YoucaninstallthisRubygemusingthefollowingcommand:
$sudogeminstalldep-selector-libgecode
Pleasenotethatifyouareusingsystemwidegeocode,Vagrantcancausesomeproblems.ItisrecommendedtousethegeocodeRubygem.
Theoutputofasuccessfulinstallationwilllookasshowninthefollowingscreenshot:
ThecreationofaBerksfileAftertheinstallationoftheBerksfileplugin,wewillnowcreateBerksfileinourcookbookandlistallthedependenciesthere:
#CreationofBerksfile
$touchBerksfile
Oncethefileiscreated,pastethefollowingcontentinBerksfile:
source'https://api.berkshelf.com'
cookbook"apache2",github:"opscode-cookbooks/apache2"
cookbook"wpblog",path:"../wpblog"
Thesyntaxisprettysimple;weassignedthesourceoftheBerkshelfAPIserverandsettheURLofapache2fromhttps://github.com/.Similarly,thewpblogpathisfromthelocalcookbooksfolder.
Now,wecansafelydeletealltherecipesinourcookbooksfolderandaddtheBerksfilepathinVagrantfile.ThenextstepistomentiontheBerksfilepathinVagrantfileandremovethecookbooksfolderpath.AseverydependencywillberesolvedusingBerks,wedonotneedthecookbookspathinVagrantfile.
RemovethefollowinglinefromVagrantfile:
chef.cookbooks_path="../cookbooks"
AddthefollowinglinesinVagrantfile:
config.berkshelf.enabled=true
config.berkshelf.berksfile_path="<Berksfile_folder_path>"
Nowthateverythingisinplace,let’sdestroyouroldboxandcreateanewonewithBerkshelf:
$vagrantdestroy
$vagrantup
Ifyounotice,duringtheexecutionoftherecipes,BerkshelfdownloadedallthedependenciesfromGitandplacedtheminthecookbooksfolder:
Aftertheexecutionoftherecipes,wecanseetheBerksfile.lockfileinthesamefolderasBerksfile,anditcontainsthelistofallthecookbookstobedownloadedandinstalled.
Behindthescenes,Berkshelfdownloadsthemainrecipe(inourcase,apache2isourmainrecipe)andchecksfordependentcookbooks.Inourcase,aswehaveseen,Apache2isdependentonthreetofourcookbooks.BeforetheinstallationofApache2,BerkshelfwilldownloadallthecookbooksandlistthemintheBerksfile.lockfile.
TheBerksfile.lockfilewilllooklikethefollowingscreenshotafterinstallation:
Now,wedonotneedtoworryabouttherecipesonebyone,andwecaneasilyspecifytherecipesthatwewanttoinstall.
Oncetheinstallationisfinished,openthehttp://127.0.0.1:8081/URL.
Theoutputshouldlooksimilartotheearlierscreenshot.Apache2isinstalledperfectlywithoutyouhavingtoworryaboutdependencies.
UnderstandingrecipesAswehavealreadydiscussed,recipesarefundamentalunitsofcookbooksandcontainstep-by-stepinstructionstoconfigurethemachine.
OurgoalistoinstallWordPress,PHP,andApache2.TherearesomedefinedtaskswhenweinstallanyLinuxdistribution.Themostcommontaskistoupdatethepackagesofanoperatingsystem.Anaptcookbookprovidesuswiththefacilitytoupdatepackagesautomatically.Wewillincludeanaptcookbooktoensurethatallthepackagesareupdated.
Openthemetadata.rbfileinwpblogandaddthefollowingdependencies:
depends'rvm'
depends'apt'
depends'apache2'
depends'php'
depends'mysql'
Let’sincludethephp,mysql,andapache2recipesinourwpblogrecipeandprovisionthemachine.
Thefinalcodeofdefault.rbwilllooklikethefollowinglinesofcode:
include_recipe"apt"
include_recipe"apache2"
include_recipe"apache2::mod_php5"
include_recipe"mysql::client"
include_recipe"mysql::server"
include_recipe"database::mysql"
include_recipe"php"
Theaptrecipewillensurethateverypackageonanewmachineisupdated;thephprecipewillinstallPHPonanewmachine,whilethemysql::clientandmysql::serverrecipesinstalltheclientandserverversionssequentially.Similarly,apache2isresponsiblefortheinstallationofApache2.ThefollowingcommandrunsanyconfiguredprovisionsagainsttherunningVagrantmachine:
$vagrantprovision
Nowthatwehaveourbasictoolkitonanewmachine,let’sfirstinstallsomepackageswiththehelpofresources.
ResourcesResourcesareakeypartofarecipe;theydefinewhichactionneedstobetaken,whichfilesneedtobecreated,andwhichserviceneedstoberestarted.Resourcesareresponsiblefortakinganyparticularactiononanode.TheyarewritteninasmallblockofRubycodethatrunssequentiallyasdefinedintherecipe.Thechef-clientlooksforaresource,andonsuccessfulexecutionoftheresource,itwillreturnthesuccesscodetothechef-client.Incaseofanyerror,chef-clientwillterminatetheoperationanddisplayanerror.
Asournewmachineisready,let’susesomeresourcesandinstallsomebasicpackages.Wewillinstallthevimandscreenpackagesonournewmachine.Thevimpackageisusedforeditinganydocument,whereasthescreenpackageisamultiplexerthatallowsausertostartmultipletasksinsideasingleterminal.
Primarily,aresourcehasfourcomponents:type,name,attributeswithvalues,andaction.Mostofthetime,attributeshavedefaultvalues,andtheycanbeusedtosendnotificationstodifferentresources.Alltheresourcesshareasetofcommonactions,attributes,conditions,andnotifications.
Thelistofallthepredefinedresourcescanbefoundontheopscodesiteatthefollowinglink:
http://docs.opscode.com/resource.html
Forinstallingvim,theresourcewilllookliketheoneshowninthefollowingcode:
package"vim"
version"7"
action:install
end
TipIfyouarenotsureabouttheversionofvim,youcanremovetheversionlineanditwillinstallthelatestversionwithintheaptrepository.
Asstatedearlier,recipesarewritteninRubycode.Wecanloopthroughalistofpackagesandinstallthem,orwecanmentiontheresourcestoinstallmultiplepackagesonebyone.Foracleanerapproach,itisrecommendedthatyouinstallvariouspackagesinasingleresource:
%w{
curl
screen
vim
}.eachdo|pkg|
packagepkgdo
action:install
end
end
Theprecedingcodewillinstallthreepackages:curl,screen,andvim.Addthisresourceinwpblog/default.rbandprovisionthebox.Oncetheprovisioniscompleted,thementionedpackageswillbeinstalledonthenewmachineandavailableforuse.
Aswenoticed,theoutputofhttp://l27.0.0.1:8081/isNotfound.Apachehasbeensuccessfullyinstalled;now,weneedtoenableanysiteinApacheusingresource.
Pastethefollowingcommandinrecipes/default.rb:
apache_site"default"do
enabletrue
end
TheApachesiteresourcewilllookforasiteinApache’ssites-availablefolder.Onceitisfound,itwillenablethedefaultsite.Again,provisionthebox,andnow,youshouldbeabletoseetheItWorks!page,asshowninthefollowingscreenshot:
Now,weneedtocreateaMySQLdatabasethatourapplicationcanuse.Wealreadyincludedthemysqlrecipeinourdefault.rbfile.Let’susetheMySQLresourceandcreateadatabasewithadefaultusernameandpassword:
mysql_databasenode['wpblog']['database']do
connection(
:host=>'localhost',
:username=>'root',
:password=>node['mysql']['server_root_password']
)
action:create
end
Theprecedingcodeblockwillcreatethewpblogdatabasewiththeusernameasrootandarootpassword.Wearehardcodingthenameofthedatabaseinourrecipe.Itisbetterifwedonothardcodethedatabasenameintherecipeanduseitfromthe/attributes/default.rbfile.Inthenextsection,wewilluseadatabasenameandpasswordfromthe/attributes/default.rbfile.
AttributesAttributesaredefinedinacookbookandthenusedtooverridethedefaultsettingsonamachine.Whenchef-clientexecutes,itloadsalltherecipesandchecksforalltheattributesinanode.Attributesdefinedinacookbooktakeprecedenceoverthedefaultattributes.Thechef-clientappliesnewsettingsandvaluesaccordinglyonanewnode.
Theorderoftheattributes’precedenceismentionedasfollows:
AdefaultattributedeclaredincookbookattributesAdefaultattributedeclaredinarecipeAdefaultattributedeclaredinanenvironmentAdefaultattributedeclaredinarole
Now,wewillcreateadatabasenameinourattributes/default.rbfileanduseitinthemysql_serverresource:
#wpblog/recipes/default.rb
Default.wpblog.database='wpblog'
#Replacethenameofdatabasewithattribute,nowfinalresourcewilllook
likethis:
mysql_databasenode['wpblog']['database']do
connection(
:host=>'localhost',
:username=>'root',
:password=> node['mysql']['server_root_password']
)
action:create
end
Provisiontheboxagain,andnow,MySQL,Apache2,andPHParereadyinournewbox.TherootuserofMySQLisalreadycreatedwiththeinstallationofthedatabase.Now,wewillcreateanapplication-specificusertoperformthecreate,update,delete,andselectoperations.
Addthefollowingattributesintheattributes/default.rbfile:
default.wpblog.db_username='wpblog'
default.wpblog.db_password='random_password
ThefollowingresourcewillcreateaMySQLuserfortheapplication:
mysql_database_usernode['wpblog']['db_username']do
connection(
:host=>'localhost',
:username=>'root',
:password=>node['mysql']['server_root_password']
)
passwordnode['wpblog']['db_password']
database_namenode['wpblog']['database']
privileges[:select,:update,:insert,:create,:delete]
action:grant
end
Theoutputoftherecipeisshowninthefollowingscreenshot:
TipIfyouwanttospecifyanyparticularlisteningportonApache,youcaneasilydosobydefininganattributeindefault.rb.
Anexamplecodeforlisteningport80isasfollows.
Createthedefault.rbfileinwpblog/attributes/default.rb:
$touchdefault.rb
#wpblog/attributes/default.rb
default.apache.listen_ports=[80,443]
MetadataThemetadataofanycookbookisdefinedinthemetadata.rbfile.Itisusedtodefinethebasicinformationofacookbook,forexample,thenameoftheauthor,maintainername,description,version,andmostimportantdependencies.DependenciesareusedbyBerkshelftodownloadalltherelevantcookbooksfromthepublicorprivaterepository.
Ourmetadata.rbfilewilllooklikethefollowingcode:
name'wpblog'
maintainer'YOUR_COMPANY_NAME'
maintainer_email'YOUR_EMAIL'
license'Allrightsreserved'
description'Installs/Configureswpblog'
long_descriptionIO.read(File.join(File.dirname(__FILE__),'README.md'))
version'0.1.0'
depends'apt'
depends'apache2'
depends'php'
depends'database'
SummaryInthischapter,wediscussedtheKnifepluginandhowitcanbeusedtocreateandfetchcookbooksfromasite.Thecreationoffilesisdifficultandtedious.OnceweinstalledApache2withrecipes,wediscussedLibrarian-ChefandBerkshelf.WediscussedthedifferenceinbothtoolsandstartedusingBerkshelftoresolvedependencies.
ThechaptercontainstheBerkshelfconventionsandexplainshowtheycanbeusedwithoneormanyrecipestodownloaddependentcookbooks.WeplannedtodeveloptheWordPresscookbookwiththehelpofBerkshelf.
Afterthis,thechapterexplainedthefundamentalsofrecipes,andwiththehelpoftheWordPresscookbook,wediscussedeachaspecttodevelopusablerecipes.
Moreover,thechapterprovidesanexplanationofattributes,resources,andmetadata.Wesawtheuseofresourcesinmanyaspects.WiththehelpofMySQLresources,wecreatedtheMySQLdatabaseandMySQLuserwhichwewillusetoconfigureWordPressinthenextchapter.
Chapter5.MoreaboutCookbooksandRecipesInthepreviouschapter,westarteddevelopingaWordPressrecipeandsuccessfullycreatedastackwithApache,PHP,andMySQL.Wealsodiscussedrecipes,attributes,andmetadata.Inthischapter,wewillextendthesamerecipeandconfigureWordPresswiththehelpoftemplatesandfiles.Bydefault,WordPressshowstheconfigurationpagetosavethesettingsinthedatabase.Withthehelpoftemplates,wewillcreateaconfigurationfilewithourdatabasesettingsasdefinedintheattributes.
Inthischapter,wewillcoverthefollowingtopics:
FilesTemplatesRolesDatabagsPython/DjangocookbookwithNginxanduWSGIRestartserviceswithupstreamandserverhandling
UsingfilesFilesareusedasaresourcetomanagefilesonaneworexistingnodetocreate,delete,orupdatefilecontents.Theycontainuserandgroupinformationalongwiththepermissionthatneedstobeassigned.
Thesyntaxofthefilesismentionedinthefollowingcode:
file"/tmp/testfile"do
owner"root"group"root"
mode"0755"
action:create
end
Theprecedingcodeblockwillbeusedtocreateatestfileinthe/tmpfolder,bytherootuser.Theactionattributespecifiestheactionthatneedstobecreated.
ExploringtemplatesAtemplateisanEmbeddedRuby(ERB)filethatisusedtocreateconfigurationfilesbasedonvariablesandlogicdefinedbyacookbook.AtemplatecancontainmixedRubycodeorexpressions;itprovidesagreatwaytomanageconfigurationfilesonanynode.
Templatesareusedwithatemplateresource,andeachresourceincludesactions,attributes,andfilesources.Templateresourcesareveryclosetofileresources;theonlydifferenceisthattemplatesarebasedonRubycode,andontheotherhand,fileresourcesareusedtocopyfilestoaparticularlocation.
Templatesshouldhavethefollowingtwocomponents:
Atemplateresource,whichinstructsthechef-clienttoperformanyactionAtemplatefileinthetemplatesfolder
Thefolderstructureofcookbooktemplateswilllooksimilartothefollowing:
default
ubuntu-12.04
ubuntu-14.04
Ifwenoticeourcookbooksdirectory,wewillseethatthetemplatesfolderisalreadycreatedbyKnife.Let’scompleteourrecipeandcreateaWordPressconfigurationfilewithatemplate.
WewillextendouroldrecipeandaddactionstodownloadandconfigureWordPress.Wealreadycreatedadatabaseanddatabaseuserinourrecipe.Now,thenextstepistodownloadWordPressandunzipit.
Here,wewilluseremote_fileandthedirectoryresourcetodownloadthelatestWordPressversionandcopyittoadocumentrootdirectoryofApache.Let’saddthefollowingcodeblocktowpblog/recipes/default.rb:
wordpress_file=Chef::Config[:file_cache_path]+"/wordpress-
latest.tar.gz"
remote_filewordpress_filedo
source"http://wordpress.org/latest.tar.gz"
mode"0644"
end
directorynode["wpblog"]["path"]do
owner"root"
group"root"
mode"0755"
action:create
recursivetrue
end
TipThecompletedocumentationofremote_fileandthedirectoryresourceisavailableatthefollowinglinks:
http://docs.opscode.com/resource_directory.html
http://docs.opscode.com/resource_remote_file.html
Bothchef-clientandChef-SolocreateaChef::Config[:file_cache_path],soitisavailableexplicitly.Thislocationisusedinseveralcookbooks,anditisrecommendedforcachedfiledownloadsinrecipesbecauseitisalocationthatisknowntoChef.
Thewordpress_filevariablewillbeusedtoreturnthecachedpathoftheWordPresspath.Thebenefitofusingcache_pathistopreventdownloadingthesamefileagainandagain.WordPresswilldownloadChefandsaveittothecachepathfolderinordertoavoidgettingitdownloadedforeveryrun.
Inthepreviouscode,thesourceisspecifyingthedownloadpathoftheWordPressarchive,andsimilarly,modeissettingthefilepermission;the0644permissioncanbeusedbytheownertoread/writeafile.Thedirectoryresourcewillbeusedtocreateadirectoryinourdefinedpath.
Beforeproceedingfurther,weneedtodefineapathinourwpblog/attributes/default.rbfile:
default.wpblog.path="/var/www/wpblog"
Let’sunzipthelatestWordPressfilewiththeexecuteresource.TheexecuteresourceisusedtoexecuteanyShellscriptinChef:
execute"expand-Wordpress"do
cwdnode['wpblog']['path']
command"tar-xzf"+wordpress_file
createsnode['wpblog']['path']+"/wp-settings.php"
end
Thisisdemonstratedinthefollowingscreenshot:
Thecreatesactionwillensurethatwp-settings.phpdoesnotexecutethesamecodeblockagainifitalreadyexistsinthefolder.Analternatenot_ifisalsoavailableforthesameoperation.
Provisiontheboxagain,andwecanverifyourchangesusingvagrantsshorbytypinghttp://localhost:8081/wpblog/inthebrowser,asshowninthefollowingscreenshot:
Now,thenextstepistocreatethewp-config.php.erbtemplateandplaceitinthewpblogfolderwithourdatabasesettings.WordPressprovideswp-config-sample.phpbydefault;wewillcopythisfiletoourtemplatesfolderandaddtheattributestoreplacewithactualvalues.
Also,forthecreationofauniquesalt(asaltisasecretkeythatisusedtogeneratehashestopreventattacks)andgenerationofasecretkey,wewillusetheWordPresssaltgenerationservice(http://api.wordpress.org/secret-key/1.1/salt/).Ifyouopenthewp-config-sample.phpfile,itismentionedincommentstogeneratesaltusingtheWordPressservice.
Thebasicversionofthewp-config.php.erbfileisshowninthefollowingscreenshot:
Nowthatourtemplateisready,let’spassvariablevaluesfromtherecipe,includingthe
WordPresssaltandsecrets.
Addthefollowingcodeblocktowpblog/recipes/default.rb:
#Followinglinewillcachethefilepathofwp-salt.php
wp_salt=Chef::Config[:file_cache_path]+'/wp-salt.php'
iffile.exist?(wp_salt)
salt_file=File.read(wp_salt)
else
require'open-uri'
salt_file=open('https://api.Wordpress.org/secret-key/1.1/salt/').read
open(wp_salt,'wb')do|file|
file<<salt_file
end
end
Thefile.existmethodwillensurethatthecodeisnotexecutingagain;open-uriwillopenthesaltserviceURL,andlikethefileoperation,wewillreadthedataandcreateanewfilenamedwp-salt.php:
templatenode['wpblog']['path']+'/wp-config.php'do
source'wp-config.php.erb'
mode0755
owner'root'
group'root'
variables(
:database=>node['wpblog']['database'],
:db_username=>node['wpblog']['db_username'],
:db_password=>node['wpblog']['db_password'],
:wp_salt=>salt_file)
end
Now,wewillusethetemplateresourcetoreadvariablenamesfromattributesandsendthemtothewp-config.php.erbfile.Intemplate,wecanpassthevariablesusingthevariableinresource,orwecandirectlyprintusingnode[:wpblog][:database].
Savethefileandprovisiontheboxagain.Openhttp://localhost:8081/wpblog/.Now,wecanseetheWordPressinstallationpage,asshowninthefollowingscreenshot:
WehavesuccessfullyinstalledWordPresswithChef-Solo;onlytheconfigurationofApacheisleft.Let’scompletetheremainingbitwiththehelpoftemplatesandattributes.
Createanewfileinwpblog/templates/default/site.conf.erbandaddthefollowingcode,asshowninthefollowingscreenshot:
NowthatwehavetheApacheconfigurationready,let’sinstructourrecipetousethisfileandenableourcustomsite.
Theapache2cookbookprovidestheweb_appresource.Withtheweb_appresource,wecanenableourcustomsiteintheApacheconfiguration.AmoredetaileddocumentationontheApacheresourceisavailableatthefollowinglink:
https://github.com/onehealth-cookbooks/apache2
Thebestpracticeistocreatecustomresourcesandprovidersinsideacookbooktopreventcodeduplication.
Addthefollowingcodetothewpblog/recipes/default.rbfile:
web_app'wpblog'do
template'site.conf.erb'
docrootnode['wpblog']['path']
server_namenode['wpblog']['server_name']
end
Asweareassigningserver_nameintheresource,wehavetodeclareitfirstinthe/attributes/default.rbfile:
#wpblog/attributes/default.rb
default.wpblog.server_name='wpblog'
Also,weneedtodisablethedefaultsite,aswehavetheapache_siteresourcesettoenabletrueinourrecipe.Let’schangeittofalsetodisablethedefaultsite,asshowninthefollowingscreenshot:
Nowthateverythingisinplace,let’sprovisiontheboxagainordestroytheboxandcreateitagaintoverifyeverything:
$vagrantdestroy
$vagrantup
Onceyourrecipeiscompleted,openhttp://localhost:8081/,andthebrowseroutputshoulddisplaythehomepageofWordPress.
Youmightbethinkingthatit’salonginstallationprocesstopreparetheWordPressnode.However,ifyouhavetocreatetheWordPressnodeonatimelybasis,youdonotrequirethesametediousstepseverytime.Onceyourrecipeisready,wecanexecuteit,andournewinstanceisreadytoservethetraffic.
DatabagsAdatabagisaglobalvariablethatisstoredinJSONandcanbeaccessedbyChef.Itisindexedforsearchingandloadedbychef-clientwhileexecutingtherecipe.
WecanusedatabagsdirectlyinaJSONfileorcreatethemusingKnifeSolo.First,wewilluseasimplerapproach,thatis,updatingthepasswordwithaJSONfile.
Beforeweproceedfurther,wewillcreateaJSONfileunderthesamefolderofVagrantfileandusethisfiletorunrecipes.ThebenefitofthisapproachisthatChef-SolorequiresaJSONfiletoexecuterecipes,andwecantestourJSONfilewithVagrant.Thestepsareasfollows:
1. CreateyourfileinthesamefolderwhereVagrantfileexists:
#wpblog.json
{
"wpblog":{
"db_password":"dbpass1234"
},
"run_list":[
"recipe[wpblog::default]"
]
}
2. Commentontheadd_recipelineinVagrantfileandaddthefollowingcodeblockinVagrantfile:
chef.json.merge!(JSON.parse(File.read("wpblog.json")))
Now,Vagrantfilewilllooklikethefollowingscreenshot:
3. ProvisiontheboxagainandlogintoanewmachineusingSSHtoverifythatthenewpasswordhasbeenupdated:
#cat/var/www/wpblog/wp.config|grepWP_PASSWORD
Theoutputoftheprecedingcommandisshowninthefollowingscreenshot:
Wecanseeournewpasswordfromthedatabagthathasbeenupdated.YoumightbewonderingabouttheuseofadatabaginaJSONfileasitissavedinthediskspace.Imaginethat,inacloudenvironment,youcreateasystemvariabletosavethepassword,butitisnotavailableonthediskspace.Whileexecutingtherecipe,youcanretrieveitfromasystemvariableandpopulateitaccordinglyintheconfigurationfile.
TipAnalternatemethodusingKnifeismoresecure.Knifeprovidesadecentmethodtocreatedatabagsfromacommandline.Hereisanimportantpointtonote:ifyouareusingtheChefserver,thenbydefaultKnifewillcreatethedatabagsontheChefserver.However,aswearerunningourrecipeswithChef-Solo,weneedafewadditionalpluginstogeneratedatabagsandsavethemlocally.
KnifeSoloallowsyoutogeneratedatabagsindividuallywithoutanyChefserverintegration.
TheinstallationcommandsfortheKnifeSoloandKnife-Solodata_bagareasfollows:
$sudoapt-getinstallruby1.9.1-full
$sudogeminstallknife-solo
$sudogeminstallknife-solo_data_bag
TipAsanalternatemethod,wecanuseChefDevelopmentKit(chef-dk).Now,Knifeisofficiallyapartofchef-dk.
Wewilluseadatabagforoursensitiveinformation.AsperourWordPressrecipe,wewillusethedatabasepasswordwithdatabags.KnifeSolosupportsdifferentencryptionmethodstoencryptsensitiveinformation.
Databagscanalsobecreatedusingthefollowingcommand:
$knifesolodatabagcreateappswpblog--json'{"id":"wpnlog",
"db_password":"newpassword"}'
UpdatethedatabagsdirectorypathinVagrantfile:
chef.data_bags_path="../cookbooks/wpblog/data_bags"
Now,thefinalversionofVagrantfilewilllooklikethefollowingscreenshot:
AfterthecreationofdatabagsandVagrantfile,reloadtheVagrantmachine,assomeoftheconfigurationpathshavebeenchanged.Itisrecommendedthatyoureloadthemachineonceusingthefollowingcommandline:
$vagrantreload
Onceyourmachinehasbeenreloadedandprovisioned,verifythedatabasepasswordchangesusingSSHtothevirtualmachine.Now,the/var/www/wpblog/wp-config.phpfileshouldhavetheupdateddatabasesettingswiththenewdatabasepassword.
Moreover,wecanuseasecretkeyfiletoencryptthedatabaginformation.
Anexampleofanencrypteddatabagcanbeseeninthefollowingcommand:
$knifesolodatabagcreateappswpblog-ssecret_key
Anexampleofanencrypteddatabagwiththesecretkeyspecifiedinafilecanbeseeninthefollowingcommand:
$knifesolodatabagcreateappswpblog--secret-file'SECRET_FILE'
NoteNotethatthesecretfilepathshouldbespecifiedinsolo.rb;otherwise,Chef-Solowillterminatetherecipewithanerror.
RolesTheterm“role”isusedtodefinecertainpatternsandprocessesofconfigurationonasingleorseveralnodes.Imaginethatifyourapplicationhashightrafficandoneserverisnotabletohandleallrequests,youmightneedanotherservertohandlerequests.YouneedApache(oranyotherwebserver)acrossallnodes.Inthiscase,youcancreatetherolenameWebServer,anditcontainstherunlistoftheApacheserverwithsiteconfigurations.Rolesaredefinedinthesamewayasthenormalrecipeswithrun_list.Similarly,wecancreateadatabaseroletosetupadatabaseserver.
TipNotethattheuseofroleswiththeChefserveriscontroversial.It’sfinetousethemwithChef-Solo.
Let’shavealookatsomereal-worldexamples.
Now,wewillcreateacookbooktosetupaPython/DjangoappwithNginxanduWSGI.Wewillnotexplaineachbitofcodeaswedidinthepreviousexample,assumingthatnowwehaveanunderstandingoftherecipestructureandtheimportantcodeblocks.
Createanewcookbooknameddjango_appandanewVagrantboxtoexecutetherecipe.
Followthesamestepsforcreatingcookbooksandsomeattributes.Assumingthatwehavealreadycreatedthedjango_appcookbook,createafoldernamedrolesinthecookbooksfolderandupdatethepathinthenewVagrantfile.
FollowthesameinstructionstocreateVagrantfileforanewapplicationandforwardport8082totheport80Vagrantbox.
TheVagrantfileofthenewmachinewilllooklikethefollowingscreenshot:
ThecontentsoftheVagrantfilearealmostthesame;createtheJSONfileunderthesamefolderandaddthefollowingcode:
{
"run_list":[
"role[web_server]"
]
}
Now,wewillcreatetheroleofweb_server.
Undertherolesdirectory,createanewfileofweb_server.rbandupdatethefollowingcontent:
name"web_server"
description"Aroletoconfigurenginxwebserver"
run_list"recipe[apt]","recipe[nginx]"
Now,ifyounoticethatBerkshelfwilldownloadthecookbooksbeforeexecutingtherole.OnceBerksfiledownloadsalltherecipes,thenrolewillusethosedownloadedcookbooks.Inthiscase,weneedtomentionnginxinBerksfile.
TipThedependenciescanbedeclaredinthemetadata.rbfileordirectlyinBerksfile.Itisrecommendedthatyoumentionthedependencyinthemetadata.rbfile.TheBerksfilewillreadthemetadata.rbfileanddownloadthedependencies.Otherwise,weneedtomentionthemexplicitlyinBerksfile.
Now,weaddnginxinBerksfile:
source'https://api.berkshelf.com'
cookbook"apt",github:"opscode-cookbooks/apt"
cookbook"nginx",github:"opscode-cookbooks/nginx"
StarttheVagrantboxusingthefollowingcommand:
$vagrantup
Onceitiscompleted,openhttp://localhost:8082/,andyouwillseetheNginxpage,asshowninthefollowingscreenshot:
Additionally,wewillusethecustomlogdirectoryanddisablethedefaultsiteusingthesamerolebyperformingthefollowingsteps:
1. Addthefollowinglinesinroles/web_server.rb:
default_attributes"nginx"=>{
"log_location"=>"/var/log/nginx.log",
"default_site_enabled"=>false
}
2. Provisiontheboxagain,andthedefaultsitehasnowbeendisabled.Let’sstartcreatingourrecipetosetuptheproject.AddthedependenciesinBerksfile:
#Berksfile
source'https://api.berkshelf.com'
cookbook"apt",github:"opscode-cookbooks/apt"
cookbook"nginx",github:"opscode-cookbooks/nginx"
cookbook"python",github:"opscode-cookbooks/python"
cookbook"user",github:"fnichol/chef-user"
cookbook"django_app",path:"../django_app"
3. Addthedependencieslistinmetadata.rb:
depends'python'
depends'user'
Now,ourrecipewillhavetheinstructionstoinstallaPythonvirtualenvironment.Clonethecodefromhttps://github.comandaddtheconfigurationfileinthesites-enabledfolder,asshowninthefollowingscreenshot:
Wehaveuseddifferentresourcesintherecipe.Initially,weincludedpython::piptoinstallPythonpackages.Then,weinstalledthevirtualenvironmentVersion10withthehelpofthepython_pipresource.Theuser_accountresourcebelongstotheuserrecipethatwehavealreadydefinedinNginx.WearecreatingoneuserandafewPythonprojectfilesunderthisuser.ThegitresourcewillusetoclonetherepositoryfromGitHub;thefullpathofGitHubisdefinedinthe/attributes/default.rbfile.
Wehavedefinedthefollowingattributesinattributes/default.rb:
default.django_app.app_name='django_app'
default.django_app.home_dir='/home/webuser'
default.django_app.virtual_env=File.join(node.django_app.home_dir,
'django_env')
default.django_app.repository=
'https://github.com/navidurrahman/django_app'
default.django_app.path=File.join(node.django_app.virtual_env,
node.django_app.app_name)
default.django_app.user='webuser'
default.django_app.group='webuser'
default.django_app.nginx_conf='site.conf'
default.django_app.uwsgi_path=File.join(node.django_app.virtual_env,
node.django_app.app_name,'uwsgi.ini')
TipAttributescanbedefinedusingtwosyntaxes.Wecaneitherusedefault['django_app']['user']ordefault.django_app.user.It’samatterofstylewhichoneyouwanttouse.
Fordetailedinformationaboutaccessormethods(anaccessormethodisusedtoreturnthevalueofavariable),pleaserefertohttp://docs.opscode.com/essentials_cookbook_attribute_files.html#accessor-methods.
Whileexecutingtherecipe,Nginxwillbeinstalledfromtheweb_serverrole.Now,ourweb_serveriscompletelyindependentfromthedjango_apprecipe.InthenextcookbookwherewerequireNginxtobeinstalled,wecandirectlyusetheweb_serverroletoinstallNginx.
Similarly,wecanseparatethedatabaserecipe.Rolesprovideuswithacleanerwaytoavoidcoderepetition.
Executetherecipeusingvagrantupandbrowsetohttp://localhost:8080.
Youwillseethepageasshowninthefollowingscreenshot:
RestartingservicesandserverhandlingWehaveuseduWSGIwithNginxtodeployaDjangoapplication.AuWSGIprojectaimsatdevelopingafullstacktobuildhostingservices.Ithasapluggablearchitecturetosupportmoreplatforms,andacommonconfigurationstyle.TodeploytheDjangoapplication,wehaveusedthe.inifiletosavealltheconfigurationsofthePythonapplication.
We’llnotgointothedetailsofauWSGIapplicationnow.PleaserefertothefollowinguWSGIdocumentationfordetailedinformation:
http://uwsgi-docs.readthedocs.org/en/latest/
Aninterestingbitofourrecipeistorestartserviceswithanupstreamscript.AservicetellsChef-SolotouseoneoftheOS-specificproviders.First,wecreatea.conffileintheinitfoldertohandletheservicescript.Then,theserviceresourceofChefsupportsmultipleattributesforstart,reload,andstatuscommands:
template"/etc/init/django_app.conf"do
source"django_app.conf.erb"
owner"root"
group"root"
mode"0755"
end
Onceourservicegetsregistered,wewilluseaserviceresourcetostartourserviceimmediately.
Theserviceresourcetellsthechef-clienttousedifferentprovidersaspertheplatform.Theplatforminformationisalreadycollectedbychef-clientusingOhai.
OhaiisasoftwaretoolthatisusedtodetectattributesonanodeandthenprovidetheseattributestoChef-Soloatthestartofeveryrun.
Thefollowingcodeblockregisterstheservicefordjango_app:
servicenode[:django_app][:app_name]do
providerChef::Provider::Service::Upstart
supports:status=>true,:restart=>true,:reload=>true
action[:enable,:start]
end
Attheend,wewillstartthedjango_appservice,andnow,ournewserverisabletohandletrafficimmediately.Thebenefitofthisserviceisthatiftheapplicationgetskilledforsomereason,itwillrespawntheprocessagainandensurethattheapplicationisupandrunning.
Now,youhavetherecipereadyforaDjangoapplication.Youcancreateoneormoreserverswithinthespanofafewminutes.
SummaryInthischapter,wecontinuedwithWordPressrecipesandlookedintotheuseoffiles.Wealsomodifiedthedefaultdatabasesettingswithtemplatesandsetupanewserverbyprovidingdatabaseinformationwithtemplates.
Wehadadetaileddiscussionontemplates,templatevariables,andalsofetchedthevaluesfromdefaultattributesanddatabags.Moreover,weinstalledtoolstoworkwithdatabagsusingChef-Solo.
AfterthecompletionoftheWordPressrecipe,westartedwithaPython/Djangoapplicationrecipeandlookedattheusageofroles.Wethendevelopedtheweb_serverroletodeployNginxandcheckedoutcasesthatrequirethedeploymentofNginxrepeatedlywithoutcoderepetition.
Finally,wealsodelvedintohowourserverwillbereadyandhowtorestarttheserviceiftheapplicationprocessgetskilledforsomereason.
Chapter6.Chef-SoloandDockerInthepreviouschapter,wesuccessfullydevelopedourrecipesandtestedthemwithVagrant.Also,weexecutedourrecipeswithChef-Solo.Inthischapter,wewilllookatanotherinterestingtoolfordeploymentandexecuteournginxrecipewithChef-Solo.
Wewillcoverthefollowingtopicsinthischapter:
DockerExecutingrecipeswithChef-SoloonaDockercontainerSomerecommendedpracticesforusingChef-SoloChefserverandChefinfrastructure
DockerDockerisanopensourcesoftwareusedtoautomatethedeploymentofanyapplicationinaportableandself-sufficientcontainer.Itcanrunvirtuallyanywhere.
Initially,DockerwasbuiltontopofLinuxContainers(LXC)andprovidedaverylightweightcontainertobuildanddevelopapplications.Initsrecentversion,DockerhasreplacedLXCwithitsownbuilt-inlibrary(libcontainer).YoucanstilluseDockerwithLXCinsteadoflibcontainer.ItcanbetestedonalaptopandisscalableonVMs,OpenStackclusters,serverinstances,oronallofthese.ThemainconceptofDockeristodevelopitonceandrunitanywhere.Dockerhastoolingtomakeitveryeasytodistributeanddeploycontainers.Wehavehadvirtualizationtechnologyforalongtime,butbeforethat,youhadtocreatemultipletypesofimagesbecauseeveryvendorhadtheirownimageformat,andthereweren’ttoolsorcentralrepositoriestomakeiteasytotransfercopiesofimages.
Currently,Dockerisindevelopmentandveryneartoproductionrelease,butitisworthhavingalookatDocker.Primarily,Dockerisusedforthefollowingpurposes:
AutomatingthepackaginganddeploymentofapplicationsCreatinglightweight,privatePlatformasaService(PaaS)environmentsAutomatedtestingandcontinuousintegration/deploymentDeployingandscalingwebapplications,databases,andbackendservices
BeforegettingstartedwithChef-SoloandDocker,let’shaveabriefdiscussiononhowitisdifferentfromthetraditionalvirtualbox.
Asdiscussedearlier,itisbuiltonaLinuxcontainer,whichallowsDockertousemultipleOSresources,andithasAdvancedMulti-layeredunificationFilesystem(AuFS).ThebeautyoftheAuFSfilesystemisthatyoucanhavearead-onlyandwrite-onlypartofthefilesystem.Also,thecontainerscansharetheread-onlyfilesystemwiththeindividualwritingpart.Itmeansmanycontainerscansharetheread-onlypartamongeachother.
AuFSisastackableunificationfilesystem,whichunifiesseveraldirectoriesandprovidesamergedsingledirectory.AuFSisthedefaultfilesystemofDocker,butothertypesofstoragesuchasB-TreeFilesystem(BTRFS)arealsosupportedbyDocker.
Traditionalvirtualsystemsdidnotsharetheirownsetofresourcesanddidminimumsharingbetweeneachother.TheAuFSapproach,inthiscase,makestheLXCverylightweight,andittakesjustafewsecondstostartacontainer,andinsomecases,lessthanasecond.
Ifyouarelookingforacompletevirtualizationtool,thenDockerisnotagoodchoice.Wehavelearnedinthepreviouschaptersthatwecanbuildnewinstanceswithcookbooksandrecipes.However,everytimethemachinebootsup,therecipestakesometimetobootanewinstance,anditneedsextradependenciestoconfigurethesystem.Comparatively,aDockerimagestoresitselfonthefilesystemanddoesnotneedanyexternalresources.
Dockerprovidesadecentwaytoobtainasnapshotofthecurrentoperatingsystem.Itisan
actualimplementationofWriteonce,runanywhere.Inthischapter,wewillcreateabasicDockercontainerfirst,andthen,wewillextendthiscontainerwiththehelpofChef-Solo.
InstallingDockerCurrently,Dockerissupportedonlyon64-bitmachines.Itrequiresthe3.8kernelversiontoexecuteproperly.IfyouareusingUbuntu12.04,upgradethekernelversionfirst,asprecisioncomeswithkernel3.2bydefault.
Wecanupgradethekernelversionusingthefollowingcommand:
$sudoapt-getinstalllinux-image-generic-lts-raringlinux-headers-
generic-lts-raring
NoteYoucanusethementionedcommandonLinux12.04.Ubuntu14.04hasthe3.8kernelVersionbydefault.
TheDockerinstallationcanbedoneusingthefollowingcommands:
$echo"debhttp://get.docker.io/ubuntudockermain"|sudotee
/etc/apt/sources.list.d/docker.list
#CheckthatHTTPStransportisavailabletoAPT
if[!-e/usr/lib/apt/methods/https];then
apt-getupdate
apt-getinstall-yapt-transport-https
fi
#AddtherepositorytoyourAPTsources
echodebhttps://get.docker.io/ubuntudockermain>
/etc/apt/sources.list.d/docker.list
#Thenimporttherepositorykey
apt-keyadv--keyserverhkp://keyserver.ubuntu.com:80--recv-keys
36A1D7869245C8950F966E92D8576A8BA88D21E9
#Installdocker
apt-getupdate;apt-getinstall-ylxc-docker
ItalsoprovidesaShellscripttoexecuteandinstall.WecanuseanalternativemethodtoinstallDockerasfollows:
$curl-shttps://get.docker.io/ubuntu/|sudosh
Let’sconfirmtheDockerversionusingthefollowingcommand:
$docker-v
Theoutputofthiscommandisshownasfollows:
AnothermethodtoinstallDockeristouseboot2docker,alightweightdistributionbasedonTinyCoreLinux(TCL).Itworksonany64-bitsystemthatcanrunVirtualBox(Linux,OSX,orWindows).
TheworkingofDockerDockercontainersareinitiallycreatedbyabaseimage.WecanpullanyimagefromtheDockermainregistry(aDockerimageserveriscalledaregistry)andstartfromthatpoint.Mostly,LinuxversionsareavailableonDocker.Inshort,thisrepositoryprovidesaGitHub-typeversioncontrolsystem.WecanpulltheDockerimages,makesomechanges,andcommitthesechangestothemainrepository.Currently,docker.ioprovidesonlypublicrepositories,butinfuture,theyareplanningforprivaterepositories.Youcansearchfordifferentimagesathttps://index.docker.io/.
ThereareseveralarticlesavailableonlinetosetupaprivaterepositoryforDocker.Wealreadyinstalleditonourlocalmachine.Let’spullabasicUbuntuimageandstartwithaHelloworldexampleusingthefollowingcommand:
$sudodockerrunubuntu/bin/echohelloworld
Thisisdemonstratedinthefollowingscreenshot:
TheprecedingcommandwilllookforanUbuntuimagefromthelocalfilesystem.Ifit’snotavailableonthelocalfilesystem,DockerwillpulltheUbuntuimagefromthemainrepositoryandrunthecontainer.
The/bin/echopathwillbeusedtodisplaytheHelloworldexample.
Let’stakealookatsomebasiccommandsofDocker,whichwewilluseinourexamples.
Todownloadaprebuiltimagefromthemainrepository,usethefollowingcommands:
$sudodockersearch<Name>:ThiswilleasethepullofDockerimageswithconcisenames$sudodockerpullubuntu:ThisisusedtoruntheShelloftheimagecontainer
$sudodockerrun-i-tubuntu/bin/bash:ThiswillstarttheShellofaDockercontainer$sudodockerimages:Thisisusedtolistallthedockerimages
ThereareseveralothercommandsavailableforDocker.FordetailedinformationaboutDockercommands,pleasechecktheDockerdocumentation.ItcontainsdetailedinformationabouttheusageofDocker.Also,aninteractiveDockershellwillgothroughthebasiccommandsofDockeravailableathttp://docs.docker.io/.
DockerfilesAswehaveseen,wecanexecuteindividualcommandsfromtheShell.Dockerprovidesadecentmethodtoinvokeseveralcommandsandinstructsthenewcontainertoperformaspecificjob.
DockerfilesisascriptbasedondifferentDockercommands.Eachcommandcontainsaninstruction,anditconfiguresthenewmachinestepbystep.Itcancontainalltheinformationfrompullingarepositorytostartinganyserver.
Theyhaveacleanandsimplesyntaxthatmakesafilemorereadableandclear.Itisdesignedtobeself-explanatoryandallowscommentinglikeotherprogramminglanguages.
Hereisanexampleofafilesyntax:
#Comments
commandargumentargument…
#ToechoHelloWorld
RUNecho"HelloWorld"
Let’screateabasicDockerfileandusethesameexampleofHelloWorldasfollows:
1. AddthefollowingcontenttoDockerfile:
#Dockerfile
FROMubuntu
RUNecho"HelloWorld"
2. BuildtheDockercontainerwiththefollowingcommand:
$sudodockerbuild-tlocal/test_docker
3. Ournewcontainer’snameislocal/test_docker,andwewilllookforDockerfileinthesamefolder,asdemonstratedinthefollowingscreenshot:
4. Now,DockerusedthesameUbuntuimageinalocalrepositoryandcreatedanotherrevisionoftheimagewithHelloWorld.Nexttime,itwillstartthecontainerwithinmicroseconds.
5. Now,wewillinstallChef-SoloonaDockerimageandexecuteourrecipeonit.
Thankstotheopensourcecommunity,theDockerprebuiltcontainerwithChef-Solois
alreadyavailableonDocker.ioatthefollowinglink:
https://index.docker.io/u/linux/chef-solo/
Alternatively,ifyouwanttobuildacontainerfromscratch,thefollowingcontentwillservethepurpose.RemovetheHelloworldcommandandaddcommandstoinstallChef-SoloandBerkshelf.
Now,ourfinalDockerfilewilllookasfollows:
Havealookatthefollowingcommands:
FROMubuntu
RUNapt-get-yupdate
RUNapt-get-yinstallcurlbuild-essentiallibxml2-devlibxslt-devgit
RUNcurl-Lhttps://www.opscode.com/chef/install.sh|bash
RUNecho"gem:--no-ri--no-rdoc">~/.gemrc
RUN/opt/chef/embedded/bin/geminstallberkshelf
ThisisanalternatemethodtobuildanUbuntuimagewithChef-Solo.Inourexample,wewillusetheopensourceimageandinstallBerkshelftoexecuterecipes.
Let’sextendourHelloworldDockerfiletoinstallBerkshelfandsomeadditionalpackagesasfollows:
FROMpaulczar/chef-client
MAINTAINERPaulCzarkowski"[email protected]"
AswealreadyknowthatChef-Solorequiressolo.rbandsolo.jsontoexecuterecipes,let’screatesolo.rb,solo.json,andBerksfileinthesamefolder,asmentionedinthefollowingcommands:
#Solo.rb
root=File.absolute_path(File.dirname(__FILE__))
file_cache_pathroot
cookbook_pathroot+'/cookbooks'
Inthefollowingcodesnippet,wecanseethatthesolo.rbfileisjustsettinguptherootpathofcookbooks:
#Berksfile
site:opscode
cookbook'build-essential'
cookbook'git'
cookbook'nginx'
Berksfilewillresolvethedependencyofthenginxcookbook.Also,werequireoneJSONfiletoexecuterecipes,aspresentedinthefollowingcode:
#solo.json
{
"run_list":[
"recipe[nginx::default]"
]
}
KeepallthefilesinthesamefolderandextendtheDockerfiletoexecutetherecipeasfollows:
RUNapt-get-yupdate
RUNapt-get-yinstallpython-software-properties
RUNapt-get-yupdate
ADD./Berksfile/Berksfile
ADD./solo.rb/var/chef/solo.rb
ADD./solo.json/var/chef/solo.json
RUNcd/&&/opt/chef/embedded/bin/berksinstall--path/var/chef/cookbooks
RUNchef-solo-c/var/chef/solo.rb-j/var/chef/solo.json
RUNecho"daemonoff;">>/etc/nginx/nginx.conf
CMD["nginx"]
Anotheropensourceutility,ezbake,isextremelyusefultopackandrunDockerimages.However,itrequirestheinstallationofalocalBerskhelf;itwilldownloadtherecipeslocallyandexecuteanewdockercontainer.
Youcanfinddetaileddocumentationonthisatthefollowinglink:
https://github.com/paulczar/ezbake
OncetheDockercontainerisfinished,itwillgiveusannginxdirectivesothatwecanrunthisprocessintheforeground.
Runthefollowingcommandagaintobuildthecontainer:
$sudodockerbuild-tlocal/test_docker
Toruntheapp,usethefollowingcommand,wherethenginxrecipeisrunningonport80:
$sudodockerrun-d-p80:80local/test_docker
Thisisdemonstratedinthefollowingscreenshot:
TipCurrently,IhaveinstalledDockerinaVagrantbox,andthe8081portofthesystemisforwardingtoport80.Onceeverythingisinstalled,http://localhost:8081/shoulddisplaythedefaultnginxpage.
Dockerisunderheavydevelopment,andit’snotrecommendedthatyouusethein-productionversion.
Youmightbethinking:ifDockerprovidesuswitharevisioncontrolsystem,thenwhatdoweneedCheffor?
WeneedconfigurationtoolstobuildDockerfromtheentrypoint;thereareseveralcaseswhereweneedtobuildtheOSimagefromthestart.
RecommendedwaystouseChef-SoloInmanycases,weneedsomedefaultsystemconfigurationonmanyservers.Insteadofrepeatingthesamecodeagainandagain,itisalwaysbettertouseroles.
Aswehaveanexampleofweb_serverinthepreviouschapter,wecancreaterolesforwebservers,databases,andsoon,dependingonthenatureoftheinfrastructure.
Generally,wecomeacrossthisscenariowhenthingsworkperfectlywhenwearedevelopingapplications,butinaliveenvironment,somebugsalwaysshowup.Mostofthetime,thesekindsofproblemsoccurbecauseoftheinconsistentbehavioroftheproductionandstagingenvironments.ItistruethatwecannotovercomealltheissueswithChef,butwecanavoidtheproblemsbycheckingforissuesateverystep.
Thefollowingtwomethodsareusuallyimplementedtodevelopcookbooksandrecipes:
Tofinishtheapplicationandstartwritingtherecipe:Theproblemwiththisapproachisthatduringthedevelopmentofanapplication,youinstallvariouspackagesonyourstagingmachine.Youeitheraddinsomedocumentationtotrackchangesormemorizethestep.IfyourapplicationisdependentonmanyOSpackages,itmeansthatyouhavespentagoodamountoftimefinalizingtherecipe.Todeveloptherecipesstepbystep:Theidealapproachtoovercometheproblemistodevelopyourrecipeasyourapplicationevolves.Forinstance,wehavealreadydecidedthatourapplicationneedsatleastnginxwiththeMySQLdatabase.
Here,wewilldiscussanothertool,TestKitchen.Ithasasimpleworkflowthatstressesonspeedbutoptimizesforthefreshnessofyourcodethatexecutesontheremotesystemsbetweentests.Ithasastatic,declarativeconfigurationinakitchen.ymlfileattherootofyourproject.
DetailedinformationofTestKitchencanbefoundathttp://kitchen.ci/.
HereisanotherblogpostthatshowsushowtouseTestKitchenwithDocker:
http://www.timusg.com/blog/2013/10/15/testing-cookbook-with-docker-and-test-kitchen/
Wecanstartdevelopingourapplicationsinafolder.CreateanewboxwithaVagrantfolderandsynctheprojectcodefoldertoaVagrantbox.
InstallthenginxrecipeonaVagrantboxandforwardtheporttoanewbox.Oneachcommit,ourcodeautomaticallymovestoanewboxandNginxdisplaysanewbox.Toinstallanynewpackage,extendtherecipeandprovisiontheboxagain.Whileusingthisapproach,wecandevelopourrecipewithnoextratime,andonceourapplicationisready,wecanimmediatelytestitonourvirtualbox.
Donotrepeatit.Ifanyrecipecanbeusedfurther,itisalwaysrecommendedthatyoucreateanewrecipeandincludeit.
Thebenefitofthisapproachistokeeptherecipesisolated,anditcanalsobeusedinfuture.
ChefserverChefserverfacilitateswithaquickerwaytodeployacompleteenvironmentinsteadofanysinglemachine.WehavealreadydiscussedthatwithChef-Solo,wecanconfigureanysinglemachine.Asourinfrastructuregrows,itbecomesdifficulttohandleoperations.Configurationmanagementtoolsaredesignedtomanagealargeinfrastructurewithseveralmachines.
Chefserverisahubofconfigurations,cookbooks,nodeinformation,andpolicies.Metadatadescribeseachregisterednodethatismanagedbychef-client.Nodesaskchef-clientforconfigurationdetailsfromtheChefserver.Recipes,templates,andfiledistributionsaresavedonthecentralChefserver.Moreover,ChefserverprovidesanAPItosendandreceiveconfigurationdetailsonthefly.
TherearemainlyfourcomponentsofChefservershowninthefollowingdiagram:
Bookshelf
Bookshelfisusedtostorecookbooksandresolvethecookbook’sdependencies.Ifany
cookbookorafileisdeclaredtwice,Bookshelfkeepstrackofthefileandsavestheitemonlyonce.Allcookbooksarestoredinflatfiles,anditiscompletelyisolatedfromChefserverandsearchindexrepositories.
Allitemsarestoredinacentralizedrepository.
WebUIWebUIisbuiltinRubyonRails3.0,andithasthewebinterfaceforChefserver.Itcontainsalistofalltheclients,workstations,andsoon.WecancreateclientsfromWebUIusingdifferentsettings.
ErchefErchefisanothernameoftheChefserverAPIofVersion11.AsChef11isrewritteninErlang,thepurposeofErchefistomakeitmorefastandscalable.TheAPIiscompatiblewithRuby,andallthepreviouscookbookswrittenforlesserversionsofChef11willcontinuetowork.
NoteChef-clientisstillwritteninRuby.
MessagequeuesRabbitMQ(https://www.rabbitmq.com/)isusedasamessagequeuesystemforChefserver.Toupdateanyitemonthemaincookbooks,Chefisaddedintothequeuefirstbeforethesearchrepository.Amessagequeueisusedforasynchronoustasks;ithasapublisher-subscribermethodtohandletasks.
Chef-expanderisusedtopullthemessagesfromRabbit-MQ;thesemessagesareprocessedandthenpostedtoApacheSolr.
ApacheSolrisusedtoindexandexposetheRESTAPIforChefserver.
NginxisusedasanHTTPserverandfrontendloadbalancer.
PostgreSQLisusedasadatastoragefortheChefrepository.
Inourexamples,wehaveusedknifetocreatecookbooks.InChefInfrastructure,knifeoffersalotmorethanbasiccookbookcreation.Wecancreateserversanddeleteandsendcustomcommandstoindividualnodes.
WhileusingChef-Solo,weneedsomecronjobs(scheduledtasks)toupdatetheserver,orwecanusesomeothertoolsuchasFabricfororchestration.
AnothermajorbenefitofusingChefserveristheabilitytosearchnodesinthewholeinfrastructure.Forexample,theloadbalancercanupdatethenewserversautomaticallybysearchingforserversintheinfrastructure.Chef-Soloismeanttomanageonemachineatatime,butwithChefserver,wecansendqueriessuchasallnodeswithlessthan8GBRAM.
IfyouwanttotryChefserverwithoutinstallingit,youcansignupforafreeaccountonChefInc.Thefirstfivenodesarefreetouse.
AdetaileddocumentationofChefservercanbefoundathttp://docs.opscode.com/.
SummaryInthischapter,welookedatamodernoperatingsystemimagingtool,Docker.WealsodiscussedsomeoftheusecasesofDockerandhowitcanhelpusmanagedifferentversions.
Afterthis,webuiltDockerwiththehelpofDockerfile.Onceweachievedthis,weusedanNginxrecipetobuildtheDockercontainerandbindtheport80ofthemainmachinetoaDockerimage.
WealsoglancedatsomerecommendationsofusingChef-Solo;theserecommendationsexplaincertainadvantagesanddisadvantagesofusingChef-Soloindifferentmethods.
Then,wediscussedChefserverbylookingatitsbasiccomponentsandbenefits.
ThereisstillmuchmoretolearnaboutChefserver,andyoucancontinueonthetopicwithanyChefserverreadingmaterial.
IndexA
Apache2dependencies/CreatingaHelloWorldrecipeApacheSolr/Messagequeuesattributes
about/Attributes,Attributesorder/Attributes
attributesdirectory/AttributesAuFS
about/DockerAuthentication/UnderstandingChef-Solo
BB-TreeFilesystem(BTRFS)/DockerBerksfile
creating/ThecreationofaBerksfileBerkshelf
features/Berkshelfinstalling/TheinstallationofBerkshelf
Bookshelf/Chefserverboot2docker/InstallingDocker
Ccache_path
benefit/ExploringtemplatesCentralizedAPIforintegrationwithotherinfrastructurecomponents/UnderstandingChef-SoloCentralizeddistributionofcookbooks/UnderstandingChef-SoloChef
about/GettingstartedwithChefcomponents/GettingstartedwithChefversions,PrivateChef/GettingstartedwithChefversions,HostedChef/GettingstartedwithChefversions,OpensourceChef/GettingstartedwithChefserver/GettingstartedwithChef-Client/GettingstartedwithChefKnife/GettingstartedwithChefterminologies/Terminologiesoverview/AnoverviewofChefinstalling,asRubygem/InstallingChefasaRubygeminstalling,aspackagemanager/InstallingChefasapackagemanager
Chef,installingaspackagemanageradvantages/InstallingChefasapackagemanagerdisadvantages/InstallingChefasapackagemanager
Chef,installingasRubygemadvanatages/InstallingChefasaRubygemdisadvanatages/InstallingChefasaRubygem
Chef-Client/GettingstartedwithChefchef-dk/ExploringKnifeChef-Solo
about/UnderstandingChef-Solocomparing,withChef-Client/UnderstandingChef-Soloprerequisite/PrerequisitesofChef-Soloconfiguring/Chef-Soloconfigurationrecipes,executing/Executionofrecipesusing,ways/RecommendedwaystouseChef-Solo
ChefDevelopmentKit(chef-dk)/DatabagsCheffile/BerkshelfChefserver/GettingstartedwithChef
about/Chefservercomponents/ChefserverWebUI/WebUIErchef/ErchefMessageQueues/Messagequeuesbenefit/Messagequeues
documentation/Messagequeuescloudnode/Nodecookbooks
about/Cookbooks,Cookbooks,Developingrecipesandcookbooksused,foradditionalconfigurationsetup/Cookbooksfolderstructure/Thefolderstructureattributes/Attributesmetadata/Metadata
Ddatabag
about/Databags,DatabagsDEBfile
download,URL/ProcessvirtualmachinesDebianpackagemanagement(dpkg)/UsingtheOmnibusinstallerDocker
about/Dockerusing/Dockerinstalling/InstallingDockerinstalling,boot2dockerused/InstallingDockerworking/TheworkingofDocker
Dockerfilesabout/Dockerfilescreating/Dockerfiles
EEmbeddedRuby(ERB)/ExploringtemplatesErchef/Erchefezbake/Dockerfiles
Ffiles
using/UsingfilesFilesfolder/Filesfolderstructure,cookbooks
about/Thefolderstructureattributes/Attributesfiles/Filesrecipes/Recipestemplates/Templates
Hhelloworldrecipe
creating/CreatingaHelloWorldrecipeHostedChefversion,Chef/GettingstartedwithChef
Iinstallation
Librarian-Chef/Berkshelf
KKnife/GettingstartedwithChef,Databags,Messagequeues
about/ExploringKnife
LLibrarian-Chef
about/Berkshelfinstallation/TheinstallationofBerkshelf
LinuxContainers(LXC)/Docker
Mmetadata
about/Metadata
Nnetworknode/Nodenginxrecipe
dependencies/ProvisionNodedatastorage/UnderstandingChef-Solonodes
cloudnode/Nodephysicalnode/Nodevirtualnode/Nodenetworknode/Node
OOhai/RestartingservicesandserverhandlingOmnibusinstaller
aout/UsingtheOmnibusinstalleradvantages/UsingtheOmnibusinstallerdisadvantages/UsingtheOmnibusinstaller
OpensourceChefversion,Chef/GettingstartedwithChefOpscode/InstallingChefasapackagemanager
PParallels
about/ProcessvirtualmachinesURL/Processvirtualmachines
Persistentattributes/UnderstandingChef-SoloPHPWordPress
settingup,prerequisite/PHPWordPressphysicalnode/NodePlatformasaService(PAAS)/DockerPrivateChefversion,Chef/GettingstartedwithChefprocessvirtualmachine
about/Processvirtualmachinesprovisioningprocess,inVagrant
commands,using/Provisionabout/Provision
Python/DjangoapplicationwithMySQL/Python/Djangoapplication
QQEMU-KVM/Processvirtualmachines
RRabbitMQ
URL/Messagequeuesrecipe
about/Recipeswriting,rules/Recipesexecuting,Vagrantused/ExecutingrecipeswithVagrant
recipesdownloading/Downloadingrecipesdeveloping/Developingrecipesandcookbooksabout/Understandingrecipes
Recipesfolder/Recipesregistry/TheworkingofDockerresource
about/ResourcesGitresourceexample/Resourcestypes/Resourcescodingconvention/Resourcesdirectoryresource/Resources
resourcesabout/Resources
rolesabout/Roles,Rolesnameattribute/Rolesdescriptionattribute/Rolesrun_listattribute/Rolesdeclaring/Rolesreal-worldexamples/Roles
/RecommendedwaystouseChef-SoloRPM(Red-HatPackageManager)/InstallationonLinuxandUbuntuRubygem
Chef,installingas/InstallingChefasaRubygeminstalling,command/TheinstallationofBerkshelf
RVM(RubyVersionManager)/InstallingChefasaRubygem
SSearchindexes/UnderstandingChef-Soloserver
handling/Restartingservicesandserverhandlingservice
restarting/Restartingservicesandserverhandlingsolo.rbfile/Chef-Soloconfigurationsystemvirtualmachines
about/SystemvirtualmachinesVirtualBox/ProcessvirtualmachinesParallels/ProcessvirtualmachinesVMware/ProcessvirtualmachinesQEMU-KVM/ProcessvirtualmachinesWindowsVirtualPC/Processvirtualmachines
Ttemplate
about/Templatestemplates/Templates
using/Exploringtemplatescomponents/Exploringtemplatesfolderstructure/Exploringtemplatesexploring/Exploringtemplates
terminologies,Chefnode/Nodeworkstation/Workstationcookbooks/Cookbooksrecipes/Recipesresources/Resourcesroles/Rolesattributes/Attributestemplates/Templatesdatabags/Databags
TestKitchen/ExploringKnifeURL/RecommendedwaystouseChef-Solo
TinyCoreLinux(TCL)/InstallingDocker
V$vagrantboxcommand/Processvirtualmachines$vagrantdestroycommand/Processvirtualmachines$vagranthaltcommand/Processvirtualmachines$vagrantinitcommand/Processvirtualmachines$vagrantpackagecommand/Processvirtualmachines$vagrantprovisioncommand/Processvirtualmachines$vagrantreloadcommand/Processvirtualmachines$vagrantresumecommand/Processvirtualmachines$vagrantsshcommand/Processvirtualmachines$vagrantstatuscommand/Processvirtualmachines$vagrantsuspendcommand/Processvirtualmachines$vagrantupcommand/ProcessvirtualmachinesVagrant
advantages/Processvirtualmachinesabout/Processvirtualmachinesinstallation/Processvirtualmachines$vagrantinitcommand/Processvirtualmachines$vagrantupcommand/Processvirtualmachines$vagrantsuspendcommand/Processvirtualmachines$vagranthaltcommand/Processvirtualmachines$vagrantresumecommand/Processvirtualmachines$vagrantreloadcommand/Processvirtualmachines$vagrantstatuscommand/Processvirtualmachines$vagrantprovisioncommand/Processvirtualmachines$vagrantdestroycommand/Processvirtualmachines$vagrantboxcommand/Processvirtualmachines$vagrantpackagecommand/Processvirtualmachines$vagrantsshcommand/Processvirtualmachinesfile/Processvirtualmachinesvirtualmachine,settingup/Processvirtualmachinesused,forrecipeexecution/ExecutingrecipeswithVagrantprovisioningprocess/Provisionsite/Provision
Vagrantbox/DevelopingrecipesandcookbooksVirtualBox
about/ProcessvirtualmachinesURL/Processvirtualmachines
virtualmachine(VM)/InstallingChefasapackagemanagerabout/Introducingvirtualmachinesystemvirtualmachines/Systemvirtualmachinesprocessvirtualmachine/Processvirtualmachines
virtualnode/Node
VMPlayer/ProcessvirtualmachinesVMware/ProcessvirtualmachinesVMWorkstation/Processvirtualmachines
WWebUI/WebUIWindowsVirtualPC/Processvirtualmachinesworkstation/Workstation
Top Related