+ All Categories
Home > Documents > Configuration Management with Chef-Solo - Lagout Management... · provides step-by-step...

Configuration Management with Chef-Solo - Lagout Management... · provides step-by-step...

Date post: 29-Jul-2018
Category:
Upload: dodung
View: 215 times
Download: 0 times
Share this document with a friend
204
Transcript

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


Recommended