Serving raster layers on Google Cloud Platform

download Serving raster layers on Google Cloud Platform

of 35

description

Serving raster layers on Google Cloud Platform

Transcript of Serving raster layers on Google Cloud Platform

  • Serving raster layers on Google Cloud Platform Lastupdated:22December2014

    Contents

    Introduction1.ConfigureaCloudPlatformprojectforservingrasters2.UploadtilestoGoogleCloudStorage

    AccesscontroldecisionsMaptilesUploadingtilesinbulkforpublicaccessUploadingtilesinbulkforprivateaccess

    3.UsetilesfromGoogleCloudStoragewiththeGoogleMapsAPIMapsAPIPublictilesexampleMapsAPIGoogleCloudStoragecookieauthexampleMapsAPIGoogleCloudStorageOAuth2.0Example

    Howthisdemoworks4.WrapOGCendpointsaroundtilesfromGoogleCloudStoragewithGoogleComputeEngine

    CreatingaGoogleComputeEngineVMInstallingandconfiguringMapProxyLoadbalancing

    CreateasnapshotofyourworkingMapProxyVMCreateadiskfromthesnapshotCreateanimagefromthediskCreateaninstancetemplateCreateanInstanceGroupCreateanHTTPloadbalancer

    Thirdpartyproducts:ThisdocumentdescribeshowGoogleproductsworkwiththirdpartyproductsandtheconfigurationsthatGooglerecommends.Googledoesnotprovidetechnicalsupportforconfiguringthirdpartyproducts.GOOGLEACCEPTSNORESPONSIBILITYFORTHIRDPARTYPRODUCTS.Pleaseconsulttheproduct'swebsiteforthelatestconfigurationandsupportinformation.YoucanalsocontactGooglePartnersforconsultingservices.

    GoogleMapsforWork1/35

  • Introduction ThisdocumentshowsyouhowtoservecustomrasterlayersusingGoogleCloudStorage,GoogleComputeEngine,andtheGoogleMapsAPI.ThisapproachisusefulifyouhavealargequantityofsatelliteoraerialimagerythatyouneedtoserveatscaleontoaGooglemaporotherGIStool.Usingthisdocument,youllcompletethefollowingsteps:

    1. ConfigureaGoogleCloudPlatformproject.2. UploadimagerytilestoGoogleCloudStorage.3. DisplaytilesusingtheGoogleMapsAPI.4. ServemaptilesusingOGCstandards.5. Loadbalanceyourapplication.

    Note:ThisdocumentdoesnotdescribehowtocreaterastertilesandassumesyoualreadyhaverastertilestouploadandhostinGoogleCloudStorage.Youcanuseoneofmanythirdpartytoolstocreaterastertiles.Beforeyoubegin,makesureyouhaveaGoogleAccount.ConsiderusingasharedGoogleAccountforyourorganization,ratherthanapersonalGoogleAccount.

    1. Configure a Cloud Platform project for serving rasters

    1. SignintotheGoogleDevelopersConsoleandclickCreateProject.

    GoogleMapsforWork2/35

  • 2. Enablebilling.

    FordetailsaboutbillinginGoogleCloudPlatform,seetheGoogleAPIsConsoleHelp.

    3. Addacreditcardorbankaccounttotheprojectforhosting(storage)anddownloading

    (egress)thesourceimageryforthecontractterm.GoogleCloudPlatformprovidesacalculatorforestimatingmonthlybillingchargesbasedonusage.

    4. CreateaGoogleCloudstoragebucket.

    Note:Cloudstoragebucketsareglobal,soifthenameyouchooseisalreadyinuse,chooseadifferentname.

    5. InstallandauthenticatetheGoogleCloudSDKtoeasilyconductbulkdownloads.

    Followtheinstallationinstructionsforyouroperatingsystem.OnceyouinstalltheSDK,youllhavenewsystemcommandslikegcloudandgsutil.

    GoogleMapsforWork3/35

  • 6. UsethefollowingcommandtoauthorizetheCloudSDKtoyourGoogleAccount.UsethesameGoogleAccountyouusedfortheowneroftheCloudPlatformProjectandtheImageryBucket.

    $gcloudauthloginprojectyourprojectname

    Detailsaboutthiscommand

    AnOAuth2authorizationscreenwillopenabrowserwindow,givingtheCloudSDKaccesstoyourproject.

    GoogleMapsforWork4/35

  • 2. Upload tiles to Google Cloud Storage

    Access control decisions YoucanfindadetaileddescriptionofhowGoogleCloudStoragehandlesAuthenticationandAccessControlintheGoogleCloudStoragedocumentation.Thisdocumentfocusesontheuseofaccesscontrollists(orACLs)forpublicorprivateaccess.Withpublicaccess,thetilesyouplaceonGoogleCloudStorageareaccessibletoanyoneontheInternet.Withprivateaccess,onlythosetowhomyouexplicitlygrantaccesscanviewthetiles.PrivateaccessiscontrolledusingOAuth2.0,andrequiresviewerstopresentcredentialsbasedoneofthefollowing:

    AGoogleAccount(suchasGmailorGoogleApps) AGoogleAccountthatisamemberofanapprovedGoogleGroup Accessviaathirdpartyserviceorproxythathandlesauthenticationviaserverside

    authentication(awebservicethatacceptsausernameandpasswordandproxiesdatawithaserversideaccesstoken).

    Map tiles Maptilescanhavevariousnamingstandardsandcanvarybasedonmapprojection.Thisdocumentfocusesonmaptilesinaz/x/y.pngnamingstandard,where

    Zisthecurrentzoomlevel,and XistheXcoordinateandYistheYcoordinate,measuredfromthetopleftofthemap

    foreachzoomlevelGoogleMaps,ESRI,Bing,OpenStreetMap,andothersusethistopleftstandard.However,theOGCstandard,calledTMS,startsfromthebottomleft.Youcanseethedifferencesinthetwoexamplesbelow,whichshowatypicaltilesfilestructure(Z/X/Y.png),where,inthe4thXcolumnofzoomlevel4,therearetwoimagesfortheYcoordinates.Notethattheirnamesaredifferentbasedonwhethercountingbeganatthetopleftofbottomleft.

    GoogleMapsforWork5/35

  • Thefilestructureinwhichyoursoftwareexportedthetileswilldeterminethelogicyouneedtouseinyourapplicationwhenyouwanttoloadaspecifictile.However,thefilestructuredoesntimpacttheactualuploadprocess.Forexamplepurposes,thisdocumentusestheUSGSNationalLandCoverDatabase.

    Uploading tiles in bulk for public access TomakethetilespubliclyaccessibletoanyoneontheInternet,setthedefaultACLforthemaspublicread.Inthedirectorywhereyouhaveyourtilesinasubfoldercalledzxy,run:$gsutilmcpapublicreadRzxy/gs://usgslandcoverdemo/

    Detailsaboutthiscommand

    Themparameterwillmakethecpprocessruninparallelthreads,whichwillgreatlyspeedupyourupload.

    Uploading tiles in bulk for private access Tomanageaccesstoprivatetiles,youcanuseGoogleGroups.WithGroups,itseasytograntreadpermissiontoaGoogleCloudStoragebuckettomembersofagroup,andthenmanagewriteaccessforindividualusersusingthestandardGoogleGroupsadministrationtools.Forthisexample,welluseagroupnamedCloudStorageTilesPrivate.Tojointhisgroup,clickJoinonthispage:

    GoogleMapsforWork6/35

  • https://groups.google.com/forum/#!forum/cloudstoragetilesprivate$gsutilmbpcloudstoragetilesdemogs://usgslandcoverdemoprivate/[email protected]:Rgs://usgslandcoverdemoprivate/

    3. Use tiles from Google Cloud Storage with the Google Maps API Maps API Public tiles example

    SeethedemoThefollowingcodesnippetshowstheGoogleMapsAPIJavaScriptyouneedtocallthetilesasaGoogleMapsAPIImageMapType.Thesefilesresideinthe/z/x/y.pngstructureinthesamebucketinwhichtheHTMLthatloadstheMapsAPIresides.

    GoogleMapsforWork7/35

  • varimageMapType=newgoogle.maps.ImageMapType({getTileUrl:function(coord,zoom){varproj=map.getProjection()varz2=Math.pow(2,zoom)vartileXSize=256/z2vartileYSize=256/z2vartileBounds=newgoogle.maps.LatLngBounds(proj.fromPointToLatLng(newgoogle.maps.Point(coord.x*tileXSize,(coord.y+1)*tileYSize)),proj.fromPointToLatLng(newgoogle.maps.Point((coord.x+1)*tileXSize,coord.y*tileYSize)))return"{z}/{x}/{y}.png".replace('{z}',zoom).replace('{x}',coord.x).replace('{y}',coord.y)},tileSize:newgoogle.maps.Size(256,256),minZoom:mapMinZoom,maxZoom:mapMaxZoom,name:'Tiles'})

    YoucanalsohosttheHTMLpageonGoogleAppEngine,GoogleComputeEngine,oryourownwebserverandstillpointtotilesinaGoogleCloudstoragebucket.Todothis,justmodifytheURLfromalocalreferencetoaremotereference,asfollows:return"{z}/{x}/{y}.png".replace('{z}',zoom).replace('{x}',coord.x).replace('{y}',coord.y)toreturn"http://storage.googleapis.com/usgslandcoverdemo/zxy/{z}/{x}/{y}.png".replace('{z}',zoom).replace('{x}',coord.x).replace('{y}',coord.y)ForTMStiles,youneedtofliptheYcoordinate,asshowninthefollowingcodesample:varimageMapType=newgoogle.maps.ImageMapType({getTileUrl:function(coord,zoom){varproj=map.getProjection()varz2=Math.pow(2,zoom)vartileXSize=256/z2vartileYSize=256/z2vartileBounds=newgoogle.maps.LatLngBounds(proj.fromPointToLatLng(newgoogle.maps.Point(coord.x*tileXSize,(coord.y+1)*tileYSize)),proj.fromPointToLatLng(newgoogle.maps.Point((coord.x+1)*tileXSize,coord.y*tileYSize)))//FliptheYvaluevarymax=1

  • },tileSize:newgoogle.maps.Size(256,256),minZoom:mapMinZoom,maxZoom:mapMaxZoom,name:'Tiles'})Seeademo

    Maps API Google Cloud Storage cookie auth example Forthisexample,wellusetheGooglegroupnamedCloudStorageTilesPrivate.Tojointhisgroup,clickJoinonthispage:https://groups.google.com/forum/#!forum/cloudstoragetilesprivateYoumustbeamemberofthisgrouptoviewthetilesinthefollowingdemo:https://storage.cloud.google.com/usgslandcoverdemo/zxy/cookiezxy.htmlFromtheGoogleCloudStorageDocumentation:

    GoogleCloudStorageletsyouprovidebrowserbasedauthenticateddownloadstouserswhodonothaveGoogleCloudStorageaccounts.Todothis,applyGoogleAccountbasedACLstotheobjectandthenprovideuserswithaURLthatisscopedtotheobject.TheURLforbrowserbasedauthenticateddownloadsis:https://storage.cloud.google.com/bucket/objectNote:ThisURLbaseisslightlydifferentthanthehttp://storage.googleapis.com/basethisdocumentusesforthepublicmapexamples.

    OnceyouveuploadedyourHTMLfile,youcanaddormodifythepermissions.MakesureyouveappliedthegroupyoureusingforthebucketsdefaultreaderACL.

    GoogleMapsforWork9/35

  • WhenauservisitstheprivatewebpageURLintheirbrowser,theuserisautomaticallypromptedtosignintotheirGoogleAccount(ifnotalreadysignedin).Aftertheuserisauthenticatedandthebrowserhasacquiredacookiewithanencapsulatedidentitytoken,theuserisredirectedtothepageintheGoogleCloudStoragerepository.GoogleCloudStoragethenverifiesthattheuserisallowedtoreadthepage,andthenloadsthepageintothebrowser.Inthecodesamplebelow,notethatitisarequirementthattheabsolute,andnotlocalizedURLpattern,begivenforthetiles:varimageMapType=newgoogle.maps.ImageMapType({getTileUrl:function(coord,zoom){varproj=map.getProjection()varz2=Math.pow(2,zoom)vartileXSize=256/z2vartileYSize=256/z2vartileBounds=newgoogle.maps.LatLngBounds(proj.fromPointToLatLng(newgoogle.maps.Point(coord.x*tileXSize,(coord.y+1)*tileYSize)),proj.fromPointToLatLng(newgoogle.maps.Point((coord.x+1)*tileXSize,coord.y*tileYSize)))return"https://storage.cloud.google.com/usgslandcoverdemo/zxy/{z}/{x}/{y}.png".replace('{z}',zoom).replace('{x}',coord.x).replace('{y}',coord.y)},tileSize:newgoogle.maps.Size(256,256),minZoom:mapMinZoom,maxZoom:mapMaxZoom,name:'Tiles'})

    Maps API Google Cloud Storage OAuth 2.0 Example OAuth2.0isanopenauthenticationprotocolusedfrequentlyinGoogleprojects.Itoffersauthenticationforbothclientandserverbasedapplications.ItsusefulformanagingquotausageforAPIsthathavedailylimitsorcostsassociatedwiththem,andforrestrictingquotausageanddataconsumptiontospecificdomains.Forthisexample,wellagainusetheGooglegroupnamedCloudStorageTilesPrivate.Tojointhisgroup,clickJoinonthispage:https://groups.google.com/forum/#!forum/cloudstoragetilesprivateYoumustbeamemberofthisgrouptoviewthetilesinthefollowingdemo:

    GoogleMapsforWork10/35

  • http://storage.googleapis.com/usgslandcoverdemoprivate/zxy/privatezxy.htmlAsamemberofthegroup,youllfirstseeapagethatasksyoutoauthorize.ClicktheAuthorizebuttontoprovidetherequiredclientsideOAuth2.0credentialstoaccessthetiles.Next,youllseeascreenthatasksyoutogranttheapplicationpermissiontoaccessfilesinGoogleCloudStorageonyourbehalf.

    ClickAccept.AmapwillappearandloadtheprivatelyACLdtiles.

    GoogleMapsforWork11/35

  • How this demo works ThetopofthesourcecodeforthedemoaboveisablockofJavaScript: //TheClientIDforyourapplication,asconfiguredontheGoogleAPIsconsole.varclientId='237898814327hacml4d6ii16ekeopho52vepp5cq6e5o.apps.googleusercontent.com'//TheoauthscopefordisplayingGoogleCloudStoragedata.varscopes='https://www.googleapis.com/auth/devstorage.read_only'varaccess_token=''functioninitialize(){authorizationFlow(authorizationComplete,refreshComplete)}functionauthorizationComplete(authResult){access_token=authResult.access_tokeninitMap()}

    ThiscodeconfigurestheOAuth2.0Workflowparameters.ThefirstdefinedvariableisanOAuth2.0ClientID.TocreateaClientID:

    1. FromtheAPIs&AuthlistintheDevelopersConsoleproject,clickCredentials.

    GoogleMapsforWork12/35

  • 2. ClickCreatenewClientID:

    3. OntheCreateClientIDscreen,selectWebapplication(default)fortheApplication

    Type.(Thisapplicationisaccessedbyawebbrowseroveranetwork,andisnotaserversideorinstalledapplication.)

    4. ClickConfigureconsentscreen.

    GoogleMapsforWork13/35

  • Theuserseestheconsentscreenafterinvokingthefunctiontoauthorizetheapplication.Werecommendthatyouprovidelogosandlinksforyourapplication,toencourageuserstotrusttheapplicationtowhichtheyaregrantingpermissionstoaccesstheirdata.

    5. Ataminimum,enteryourcontactemailaddressandaprojectname.ThenclickSave.

    6. OntheCreateClientIDscreen,providetheAuthorizedJavaScriptOriginsandthe

    AuthorizedRedirectURIs.

    GoogleMapsforWork14/35

  • ThisinformationpreventssomeonefromcopyingyourHTML/JavaScriptandhostingitonaninsecureorthirdpartyserver,tointerceptuserdataoruseyourprojectsquotas.Inthisexample,wewanttohostaprivatemaponGoogleCloudStorage,soweneedtosettheAuthorizedJavaScriptOriginstohttp://storage.gooogleapis.com.WealsoneedtosettheAuthorizedRedirectURIstothefinalURLatwhichtheHTMLpagewillbehosted.Oncetheuserisauthorized,theOAuthworfklowredirectstheuserbacktotheoriginalpage,thistimewithaURLparameterthatistheiraccesstoken.Whentheapplicationseesthattheresanaccesstoken,itwillthenreplacetheblankpagewiththeAuthorizebuttonbyinitializingtheGoogleMapsAPI.

    Finally,auniqueClientIDentrywillbecreated.YoulladdthisClientIDtotheJavaScriptforthevariableclientIDintheexample.

    GoogleMapsforWork15/35

  • ThefollowinglinedefinestheOAuth2.0Scope,whichprovidesthedataaccessrightsthattheapplicationneedstheusertogranttotheapplication:

    varscopes='https://www.googleapis.com/auth/devstorage.read_only'AtGoogle,thesescopesaretiedtoindividualservices.Inthiscase,wearecallingthedevstoragescope(GoogleCloudStorage),andbecausetheuserjustneedstoaccess(notwrite)tiles,theapplicationonlyneedsread_onlyaccess.Itsbesttokeepscopesasnarrowandconservativeaspossible,bothforsecurityandusertrust.Forexample,youwouldntwanttograntawebpagethatissupposedtoshowyourmaptilestheabilitytoposttoyourGoogle+profileorreadyourGmailcontactslist.BecausewewanttoallowuserstoaccessthewebpagebeforetheusersprovidetheircredentialstoinitiatetheOAuth2.0workflow,weneedtomaketheactualwebpagepublicallyaccessible.Dontworry,userswillnotbeabletoaccesstheprivatelyACLdtilesinthebucket,becausewearenotgoingtomodifytheirACLshowever,wellmaketheHTMLpageinthebucketpublicallyaccessible.

    GoogleMapsforWork16/35

  • NotethatOAuth2.0credentialsexpireafteragivenamountoftime.AtGoogle,thedefaulttimeoutis60minutes.Thetimeoutisasecurityfeaturethatpreventssomeonewhomayhavenefariouslyinterceptedanaccesstokenfromusingthattokenforaprolongedperiodoftime.Thisapplicationrefresheseveryhourtoretrieveafreshaccesstoken:functionhandleAuthResult(authResult){varauthorizeButton=document.getElementById('authorize_button')//Hastheuserauthorizedthisapplication?if(authResult&&!authResult.error){//Theapplicationisauthorized.Hidethe'Authorization'button.authorizeButton.style.display='none'authorization_complete(authResult)//Wemustrefreshthetokenafteritexpires.window.setTimeout(refreshToken,authResult.expires_in*1000)Finally,unlikethepublicexamples,theprivateexamplesappendaqueryparametertothetileURL,?access_token={access_token}.WhenrequestingdatathatsprotectedbyprivateACLsfromGoogleCloudStorage,youmustpasstheaccess_tokenqueryparameterwithavalidandproperlyscopedaccesstoken.return"{z}/{x}/{y}.png?access_token={access_token}".replace('{z}',zoom).replace('{x}',coord.x).replace('{y}',coord.y).replace('{access_token}',access_token)

    GoogleMapsforWork17/35

  • 4. Wrap OGC endpoints around tiles from Google Cloud Storage with Google Compute Engine

    Creating a Google Compute Engine VM ToenableOGCcompliantendpoints,youcanhostaccesstotheimagerytilesfromtheopensourceapplicationMapProxy.Inthissection,youllcreateaLinuxvirtualmachinewithinGoogleComputeEnginetohostMapProxy,andalsocreateacustomfirewallconfigurationtopermitincomingtraffictoMapProxy. TheGoogleComputeEngineDevelopersCenterhasseveralresourcestohelpyougetstartedrunningvirtualmachines,andindepthinformationforconfiguringfirewallrules.

    1. FromtheComputeEnginelistintheDevelopersConsoleproject,clickNetworks.

    2. UnderAllnetworks,clickdefaulttoaddanewfirewallrule.Thisruleletsyoutestthedevelopmentserveronport8080.

    3. Createafirewallrule.

    GoogleMapsforWork18/35

  • 4. Enableport80byclickingonAllowHTTPtraffic.

    Installing and configuring MapProxy

    1. CreateanewUbuntu14.04ComputeEngineinstanceinyourproject:

    gcloudcomputeinstancescreatemapproxyimageubuntu1404trustyv20141031aimageprojectubuntuoscloudzoneuscentral1a

    2. ConnectviaSSH,usingaterminalortheDevelopersConsolebrowserterminal.

    $sudoaptgetupdate$sudoaptgetinstallpythonvirtualenv$sudomkdir/mapproxy$sudochmod777/mapproxy$cd/mapproxy$virtualenvsystemsitepackagesmapproxy$sudoaptgetinstallpythonimagingpythonyamllibproj0$sudoaptgetinstalllibgeosdevpythonlxmllibgdaldevpythonshapely

    GoogleMapsforWork19/35

  • $sudoaptgetinstallbuildessentialpythondevlibjpegdevzlib1gdevlibfreetype6dev$sourcemapproxy/bin/activate$pipinstallMapProxy$nanogcs.yaml

    3. CopyandpastethefollowingMapProxyconfigurationfileintothenanoeditor.Note

    thatyoullneedtochangetheURLparametertomatchyourGCSbucket.

    services:demo:tms:use_grid_names:true#originfor/tilesserviceorigin:'nw'kml:use_grid_names:truewmts:wms:md:title:MapProxyGoogleCloudStorageabstract:ThisisaminimalMapProxyexample.layers:name:gcstitle:GoogleCloudStoragesources:[gcs_cache]caches:gcs_cache:grids:[webmercator]sources:[gcs]sources:gcs:type:tilegrid:webmercatorurl:http://storage.googleapis.com/usgslandcoverdemo/zxy/%(z)s/%(x)s/%(y)s.pngcoverage:srs:'EPSG:4326'bbox:[125.850,24.530,66.800,50.289]grids:webmercator:base:GLOBAL_WEBMERCATOR

    4. Savethefile(Ctrl+O)andexit(Ctrl+X)Youcannowtesttheconfiguration.

    $mapproxyutilservedevelopb0.0.0.0:8080gcs.yaml

    GoogleMapsforWork20/35

  • 5. Visitthedevelopmentserverat:

    http://YourIP:8080/demo/

    Therewillbeseveraldifferentservices,basedontheconfigurationfilethatyouused.

    6. ClickanyofthePNGorJPEGlinkstotryouttheOGCservices.

    GoogleMapsforWork21/35

  • 7. Onceeverythingappearstobeworking,configureMapProxytoworkwithApacheviaWSGI.

    $Ctrl+Ctokillthedevelopmentserver$rmrfcache_data$mapproxyutilcreatetwsgiappfgcs.yamlconfig.py$deactivate$sudoaptgetinstallapache2apache2mpmpreforkapache2utilslibexpat1sslcert$sudoaptitudeinstalllibapache2modwsgi$sudonano/etc/apache2/apache2.conf

    8. Scrolldowntotheendofthefileandaddthefollowingcodeblock.Thensave

    thefileandexit.

    WSGIScriptAlias/mapproxy/mapproxy/config.pyWSGIDaemonProcessmapproxywsgidaemonprocesses=4threads=8WSGIProcessGroupmapproxywsgidaemonWSGIPythonHome/mapproxy/mapproxyWSGIApplicationGroup%{GLOBAL}OptionsAllAllowOverrideAll

    GoogleMapsforWork22/35

  • Requireallgranted

    $sudoserviceapache2restart

    9. AccessMapProxyviatheApachewebserverlisteningonport80:

    http://YourIP/mapproxy/demo

    Load balancing WrappingservicessuchasWMSandWMTStotilesstoredonGoogleCloudstorageintroducesoverhead.WhenaWMSrequestcomesin,MapProxyhastodownloadthetilesfromCloudStoragethatintersectwiththerequestedboundingbox,compositethem,andthencutthemintoasinglenewimage.UnlikeCloudStorage,MapProxyrunningonaComputeEngineVMis,bydefault,notdesignedtohandleveryhighQPSorsupportnumeroususerssimultaneously.Forthisreason,werecommendthatyouincorporateloadbalancing.

    GoogleMapsforWork23/35

  • ForafewuserswhooccasionallyuseyourOGCservices,youmightbeabletohavejustoneVMrunninghowever,youllneedtheabilitytoscaletohandlehigherdemand.ComputeEngineoffersmanywaystoconfigureloadbalancingthisdocumentshowsanetworkloadbalancedapproachwithautoscaling.

    Create a snapshot of your working MapProxy VM

    1. FromtheComputeEnginelistintheDevelopersConsoleproject,clickSnapshots.

    2. ClickNewsnapshot.

    3. Givethesnapshotaname,andchoseyourworkingVMasthesourcedisk.Thenclick

    Create.

    Create a disk from the snapshot

    1. FromtheComputeEnginelistintheDevelopersConsoleproject,clickDisks.

    2. ClickNewdisk.

    GoogleMapsforWork24/35

  • 3. Givethenewdiskaname,andchosethezoneinwhichyoudlikethedisktoreside.ThisshouldbethesameasthezonewhereyoudliketorunyourVMs.FortheSourceType,choseSnapshot,andthenchosethesnapshotyoucreatedinthepreviousstepasthesource.ThenclickCreate.

    Create an image from the disk

    1. FromtheComputeEnginelistintheDevelopersConsoleproject,clickImages.

    2. ClickNewimage.

    GoogleMapsforWork25/35

  • 3. Givetheimageaname,andchoseDiskastheSourceType.Selectthediskyoucreatedinthepreviousstepasthesourcedisk.ThenclickCreate.

    Create an instance template

    1. FromtheComputeEnginelistintheDevelopersConsoleproject,clickInstancetemplates.

    2. ClickCreateaninstancetemplate.

    GoogleMapsforWork26/35

  • 3. Givetheinstancetemplateaname,andsetthefirewalltoallowHTTPtraffic.

    4. Chosethemachinetype.A2CPUmachineisagoodbalancebetweenpriceandperformance.ItshouldallowyourloadbalancedVMstohandleseveralsimultaneousconnectionspermachine,whilealsobeinglessexpensivethanahighCPUmachine.

    5. ForImageforthetemplate,choosetheimageyoucreatedinthepreviousstep.For

    theDisktype,choseastandardpersistentdisk.

    GoogleMapsforWork27/35

  • Create an Instance Group

    1. FromtheComputeEnginelistintheDevelopersConsole,clickInstancegroups.

    2. ClickCreateanewinstancegroup.

    3. Givetheinstancegroupaname,andchosetheinstancegrouptemplateyoupreviouslyconfigured.

    4. TurnonAutoscaling,andchosetoautoscalebasedonHTTPloadbalancingusage.Acceptthedefaultvalueof80%.Later,wellconfiguretheRateofRequestspersecond(RPS/QPS),whichsays,Whenmyloadbalancerisreceiving80%oftheRPSthatthecurrentnumberofinstancescansupport,spinupanewinstance.

    5. Configureaminimumof1instance,andsetalimitforthemaximumamountofinstancesyourewillingtoallowtobecreated.Formostcases,10to20issufficient.

    GoogleMapsforWork28/35

  • GoogleMapsforWork29/35

  • Create an HTTP load balancer

    1. FromtheComputeEnginelistintheDevelopersConsoleproject,clickHTTPloadbalancing.

    2. ClickCreateanHTTPloadbalancer.

    3. Givetheloadbalanceraname.ThenclickCreate.

    4. Oncetheloadbalanceriscreated,clickthedefaultbackendservicetoeditit.

    GoogleMapsforWork30/35

  • 5. Forthebackendservice,chosetheinstancegroupyoupreviouslycreated.Forthebalancingmode,choseRate,andforMapProxy,5RPSisappropriateforeachofourn1standard2virtualmachines.Becauseyoupreviouslyselected80%asourHTTPLoadBalancingUtilizationthreshold,onceyourfirstinstancestartsreceivingasustained4RPS,anewinstancewillbecreated.Oncethetwoinstancesreach8RPS,athirdinstancewillbecreated,andsoon,untiltheupperlimitofthenumberofinstancesyouveconfigured.

    6. Oncethebackendserviceisconfigured,clickthedefaulthealthchecklink.

    GoogleMapsforWork31/35

  • TheHTTPLoadBalancerwillrunahealthchecktomakesurethatallyourinstancegroupsarehealthyandrespondingtorequests.Bydefault,itwilljustloadtherootofyourwebservers.

    7. TomakesurethatthehealthcheckisactuallyinvokingtheWSGIapplicationofMapProxy,changethePathto/mapproxy/demo/Also,changetheIntervalto20seconds.

    GoogleMapsforWork32/35

  • 8. ClickSaveandreturntotheHTTPLoadBalancerUI.ThenclickAddaglobalforwardingrule.

    GoogleMapsforWork33/35

  • 9. Givetheruleaname,andchoseeitheranEphemeralorStaticIP.Werecommend

    choosingStaticIP,becauseyoullsharethisIPaddresswithusersormapittoacustomURL.

    10. ClickCreate.YourHTTPloadbalancerandinstancegroupswillbepushedtoproduction.Astheserviceisbeingturnedon,youllseea404erroratyourephemeralorstaticIPaddress/mapproxy/demo/.

    Shortlyafter,youllstarttosee500errorsduringtheDNSpropagationphase.

    GoogleMapsforWork34/35

  • Afterabout5minutes,theserviceandDNSpropagationshouldbecomplete,andyoullseeyourliveGoogleComputeEngineMapProxyService.YourservicereadytoserveatGooglescale,withHTTPloadbalancing,autoscaling,andtheabilitytocreateOGCendpointsaroundtilesservedfromGoogleCloudStorage.

    Seethedemo

    GoogleMapsforWork35/35