Building a WorldWeb App with Ruby, App Engine, Serverless Container, and Spanner (Cloud Next '19)

[MUSIC PLAYING] MATTHEW SOLDO: First, just a little bit about myself I’ve been working in the cloud industry for a while now I started my career at PayPal, moved on to Amazon, got to see the differences in how they built apps, which was really interesting But I really wanted the startup experience that everybody comes to Silicon Valley for And I stumbled upon this crazy little company called Heroku that was doing what at the time was called platform as a service for Ruby apps And I had built a Rails app for a failed startup And so I was this weird person who could make spreadsheets, code in Ruby, and maybe think about what products people should build So I became a product manager in the first dozen or so people at Heroku Had a great run there It was a ton of fun Managed and started the Heroku Postgres product, which maybe some of you have used, and for a while PMed the main Heroku product Then I left there, did a couple of things, spent a couple of years at Docker And then I found my way over to Google Cloud And so I’m PMing the App Engine product, which is actually Google Cloud’s oldest product It predates Google Cloud And it had been the janky old product in the portfolio But in the last couple of years, we’ve been reinvesting in it And now, it’s the really cool vintage product in the Google portfolio So I hope you folks will be excited about it and give it a try So you can post your questions on Dory, and I’ll take a look at them at the end I think you can link to it from the NEXT app I don’t know If not, you can use this ugly URL here So what we’re going to cover today First, I’m going to talk about just what are your options for Ruby on Google Cloud Then I’m going to show you a basic app Basically, this is an app Heroku circa 2013 or so Rails, Postgres, and Redis running on in a single location Then we’re going to do something that, frankly, I’ve always wanted to do, which is build an app that spans multiple continents and georoutes to them based on where you are and is resilient to an entire continent going down It’s ICBM-proof, as I like to say OK, so first of all, if you take one thing away from this, it’s this Ruby is now on App Engine in a really big way We announced that yesterday in the big mega blog post about serverless We’ve got a whole paragraph of mention It is an alpha I can say it has a couple of rough edges, but it’s actually pretty good for an alpha product I’ve been really banging on it hard And it works, which is great So I will show a URL at the end for how you folks can use it It is a private alpha But all you have to do is join a Google Group, and it’ll magically work for you OK, so let’s talk about your Ruby options on Google Cloud Before, there was basically only one option, which was App Engine Flex And for those of you who might not be too familiar with App Engine, there’s basically two flavors to environments There’s Flex and Standard And it’s kind of– environment’s a bit of a misnomer They’re basically completely different products Completely different code bases, different user interfaces App Engine Flex used to be called managed virtual machines And that’s what it is It’s basically like a serverless-like experience on virtual machines So scaling it out takes 10 minutes because you’ve got to wait for the virtual machine to load Deploys take a while It abstracts some things away, but it’s not really serverless because there are servers there So the choices were kind of barren But now, oh my gosh, we still have App Engine Flex But now we’ve got App Engine Standard, a second-generation runtime We’ve got Cloud Run, which is just announced You can just create a container It can have Ruby in it Cloud Run doesn’t care what’s in the container And it works Or you can do Cloud Run on GKE, where you take that container and run it on your own private GKE cluster So lots of choices They all work pretty well It’s a lot of fun Now I want to go– oh– OK, here we go So again, take a quick picture of this if you want to try it This is a super-ugly URL, appengine-standard-ruby25-alpha Google Group You’ll go to the Google Groups, log in with your Google account– the same one you use on Google Cloud– join the group It’s set to just auto accept anybody who joins And that puts you into the alpha And there will be a link there to docs on how you use it But we’ll be showing you that today It’s pretty straightforward Here’s that Dory link again if anybody has questions

You can also ask questions live But if you’re shy and don’t want to get up and talk, you can just put it on your app and do a question there All right So I want to show you a simple Ruby app But actually, let’s take a detour and talk about why Ruby I’m actually curious Most people here are Rubyists If you just want to shout, why do you program in Ruby? Anybody AUDIENCE: It’s easy MATTHEW SOLDO: It’s easy I think it’s super easy I pride myself on being a really bad programmer And Ruby is a language that makes a lot of sense to me Anyone else? Why Ruby? AUDIENCE: Rails MATTHEW SOLDO: What’s that? AUDIENCE: Rails Using Rails MATTHEW SOLDO: Rails Yes, Rails is awesome It’s not cool It is super not cool right now But I think it is awesome If you want to build a web app that’s backed by a database, it’s such a no-brainer You can create a Rails app in a second You could fire up a scaffold Basically with a couple of commands, you could have a working app And I’m actually giving a talk in about an hour, talking about productivity with serverless And to me, Rails and serverless go hand-in-hand You can build an app in under an hour And you can deploy it in a couple of minutes And you can actually test out to see if it’s something useful, which is great I also think Ruby is great, and Rails too, for expressing business logic, like having a model You can have an invoice model Invoice.create creates a new invoice Invoice.send You can create this code that is very easy to read, very business-friendly And I think it’s one of the best ways to model business logic out there And it turns out most apps have that sort of logic in it All right So let’s talk about a simple Ruby app We’re going to use these things– App Engine, Cloud SQL, Cloud Memorystore, and VPC Connector So let me tell you about what’s changed in the Google Cloud world on why this is relevant The janky old App Engine of a couple of years ago, it was this all-in-one product It came with Datastore It came with a special flavor of memcache It was memcacheg, for Google It was different from regular memcache And those services worked really well They worked perfectly out of the box But if you wanted to use something else, tough luck You couldn’t You couldn’t even get direct network access You had to use a special API called URL Fetch You wanted a different library? You couldn’t use it You could only get the libraries that were on there And the language runtimes themselves weren’t even the open source ones They were these special forks of the languages that Google maintained So in other words, it was super proprietary But last year, we released something called second generation runtimes, which is what people expect these days It’s a fully open source language runtime Has direct network access, obviously And so that was a big step forward But the Ruby second generation runtimes run on an entirely different cluster from the rest of Google Cloud And they weren’t able to talk to a lot of the Google Cloud services So also yesterday, we released something called VPC connectors And this completes the picture for using App Engine second gen runtimes and Ruby They let you connect to any VM or any service built on VMs, which is like Cloud SQL or Redis, that’s running in Google Cloud So now you can use all the parts of Google Cloud along with your App Engine app And that’s another big takeaway that you should get, is that Google Cloud has all these fun toys– AI, Artificial Intelligence APIs, Redis, memcache, Spanner, all these cool things And now with App Engine you can actually use them, which is great All right So it’s pretty easy This is the bare bones setup In your gemfile or wherever you’re specifying your Ruby gem, you want to do 2.5.3 or greater It’s currently running Ruby 2.5.3, and it’s going to be 2.5.5 shortly Maybe we’ll go to 2.6 We’ll see App Engine has something called an app.yaml That’s where you configure it and tell it what it is you’re doing You need to tell it you’re using the Ruby runtime You tell it an instance class There’s F1, F2, and F4 The F1 is 128 megabytes of RAM And it turns out that it’s not enough RAM to run even most basic Ruby apps So you need to do an F2 But I’ve got really good news And you guys are going to be some of the first to hear it Later this quarter, we’re going to be doubling the memory on all of the second gen instances So you’ll be able to use an F1 for the same price as the F2 That F1 will be 256 megs, which is enough for a basic Ruby app And finally, you set something called an entry point And this is just the command that gets run

It could be a Rails server command Or it can be a Puma command directly, or whatever you want And then on the CLI, you just type in gcloud app deploy That’s assuming you’ve got the gcloud client If you don’t, just install it And boom, it should work All right So that would get you just like a Hello World app But Hello World doesn’t really get you very far So you’ll probably– almost all apps– we talked about Rails Rails is great Rails usually wants a relational database And it really likes Postgres That’s my favorite So to set this up, just click into the Cloud SQL part of the Google console And you’re going to fill out this form here You give it some name Generate a password I have all those– whoa Oh, yeah, OK I didn’t step through this OK So yeah, you’ll give it a– you just click that Generate Password button and copy that Pick a region You can choose to run it in the US, west, central, or east Europe We’ve got lots and lots of regions It’s one of the really cool things about Google Cloud And really important– and this is actually a little caveat I ran into– enable a public IP Otherwise, it doesn’t seem to work In theory, you should be able to have a private IP and connect via the VPC Connect But once we get that working, we’ll document that properly This is still alpha OK, then, one of the cool things you can do in that app.yaml– this is an App Engine-specific thing– is you can set environment variables So just set your– that password you generated, just stick it in there Tell it what your user is And tell it what the host is That host, after this screen, after you actually click the Create, it’ll give you this host You just put out the cloudsql dash There’s this special unix socket that gets created on App Engine to connect to your Cloud SQL instances And so that’s actually what it’s doing And then in your Rails app and in your database.yml, you just reference those environment variables for setting up your database All right, now What I talked about before, creating a VPC connector So by default, when you create a project in Google Cloud, you get a virtual private cloud that has all the [INAUDIBLE] stick VMs that are shielded from the big, bad, dangerous internet So it’s real easy You just click into here You’re going to have to enable VPC access For some reason I don’t get, most of the products on Google Cloud don’t work by default. You have to first enable the API Then you can use them I don’t know why that is I’m sure there’s a good reason for it But it makes for awkwardness in getting started OK, then you’re going to click into a serverless VPC access and just click Create a Connector Boom You tell it which network You get this default one by default You’re going to need to type in an IP range with a dash 28 CIDR range Just use the default one that’s in that little help text there And there you go Now you’re going to create a Redis instance So again, you just click onto Memorystore Create it Give it a name Pick the region You probably want the region to be the same one that you picked for App Engine, because you want it to be in nice, fast internet access And that is basically all you want You could choose, there’s basic and standard tiers The standard tiers have failover But we don’t need that for our demo And then we’re going to configure the app to use Redis That’s all You stick that in your production config Tell it use that And you see we’re using that Redis URL, which I had back here in– so back in that app.yaml, we also see that VPC access connector You have to put that in to make the VPC work And then you stick in that Redis URL at the very bottom there And that’s the address of the Redis instance you just created And then it will all work All right So I’m not going to actually go through all of that live, because it takes 15 minutes But we can just pull up a working app, prove that it’s working OK Can I get the– there we go Cool So I created this app I’ll pull it up here Let’s make this not terribly small So here’s this app It’s just a simple app with two models And let’s– so here’s that app.yaml that I was showing you

before This is all the live stuff I guess it has my credentials in it I’ll have to destroy this database now Otherwise, heaven forbid, you could put data in there So that’s the basic app And boom, it is running right here You can see you get this little appspot.com domain This is an app It tracks watches because I’ve been collecting watches lately And it’s a fun thing to put in a database And you can put in a URL, and it works And that is a Rails app running on App Engine For some reason, it’s been super slow in the– you can see it’s loading up right now I have no idea why that is But again, it’s alpha, so it’s slow And man, that is really painful Really painful All right Well, it’s not supposed to work that way But the demo gods are not looking favorably on us All right So let’s switch back into the presentation OK Again, put some questions in Dory All right Now let’s get to the fun part So let’s look at a world-spanning Ruby app Now, I think when, at least for me, when I first got introduced to cloud computing, this is what I wanted I wanted a cloud that spanned the world And I’ve talked to lots of customers of Heroku and Google Cloud and Docker And there’s, I’d say 1 out of 5, maybe 1 out of 2 times, they were like, they say, well, can you run it in different places? Yes Can I run it in all those places at once? No It’s something that’s really hard to do But it’s something that people want It’s the cloud It’s not located anywhere It’s just kind of ephemeral So you want a cloud that covers the world But really, you end up getting this It’s like, yeah You can put it wherever you want Central, east, west– we’ve got all of them Pick one So, yeah, it’s great It’s still super awesome to not have to manage all these things, not have to go down to the data center But it’s not that cloud of our dreams But it’s actually possible to build So let’s build it So this is what we’re going to use for this Going to use the new Cloud Run on GKE product that got launched yesterday It is super cool If you are running Kubernetes in your organization but want to have a serverless experience, it is a smoking hot product You should probably have, there’s probably someone in your company that’s the Kubernetes operator, maybe two people But then you put Cloud Run on top of it, and you don’t need to worry about the Kubernetes stuff We’ll also use Spanner So one of the hardest parts about creating an app in multiple locations is the data It’s really easy to just run something that returns Hello World, and that’s it You can run that in multiple places, but who cares? Almost all apps need data, and data is heavy And so it doesn’t like to move around a lot But we’ve got this really cool technology called Spanner And we’ll back it with that You can use Cloud Memory, Redis, the same way that we did in the other app And again, that VPC connector And then to wrap it all together, we’ll use Cloudflare to do the georouting Well, there was a really cool map of the world there But that’s not loading for some reason So imagine there’s a map here We’re going to run this in US Central 1, which is Iowa, in EU West, which is in Belgium, and in Asia It’s going to be one app, three continents, load balanced So it’ll go to whichever continent you are closest to And it’ll have automatic failover Here’s the architecture So on the front, like I said, the hard parts about this are the load balancing and the data Doing the app is actually pretty easy So we’ll use Cloudflare for a geoload balancer Currently, the Google Cloud load balancer does not work well with Cloud Run Hopefully, by the end of the year, that will not be the case So you could just keep it all in the Google Cloud But frankly, it doesn’t matter Cloudflare is a great product It worked It was super– it was actually one of the easier parts of this whole demo to set up I had never done– I’d never used this part of Cloudflare before But it took me under an hour from learning on how to set it up It’ll geobalance to the code running in any one of these three regions When I made this slide, I was going to try to use App Engine But it turns out Cloud Run worked a little bit better The reason for that, by the way, is you can only have one App Engine app per Google Cloud project So that makes it hard to have an app running in three places

You can create multiple projects But then those apps can’t all connect to the same Spanner instance, because the apps connect to the Spanner instance in their project Projects are these fenced bounds in Google Cloud Then I’ll have a cache layer, and then the Spanner database and back So here’s some caveats There is no Active Record support for Spanner If you google it, you will find a gem It hasn’t had an update in two years So it’s not based on the latest Ruby version It’s not based on the latest Rails version It does actually work on the versions that it talks about But it was a proof of concept It was built by somebody who used to work at Google And it did work as a proof of concept The Ruby team at Google is hoping to build an Active Record adapter for Spanner later this year That means that hopefully next year, it will exist I would love it If that does exist, doing this will become exceedingly simple, because without Active Record, Rails isn’t very friendly to use Caveat number two is you’re going to need to use the Google Cloud client library, and it does not support process forking Maybe you’ve delved into this But most modern servers, they’ll fork the process and get better concurrency That will just break the GRPC library, which the cloud client’s based on And so you just need to set your app to not fork If you’re using Puma, there’s a simple flag to do that And third caveat is, oh my god, it is expensive This is not for the faint of heart It is really cool And it’s almost kind of cool how expensive it is How expensive is it? It’s about a Tesla Model 3 per month And that’s if you use the barest-bone configuration So the barest-bone Spanner configuration that runs on three continents is about $27,000 per month Yeah, it’s silly It’s silly expensive The good news is, if you’re a really big company, that’s a Spanner instance You can have up to 100 databases on an instance So each database is actually going to cost you about $270 a month, which is super reasonable So if you work for a big company and they decide to use Spanner for a bunch of things, it starts to become pretty cost-effective Or if you’re at really big scale I mean, if you’re running the next super-hot startup, $27,000 a month to have global reach is pretty reasonable There’s also a whole GKE cluster Each cluster in each continent has 45 gigs of RAM and three nodes and costs another several thousand dollars a month So it’s pretty pricey But it’s cool You can do it OK, so how do you do it? First, you have to create a Spanner client I just created that little initializer And this is straight out of the Spanner docs And you can see at the very end there, the little dollar sign That makes it a global and to just access this from anywhere in your Rails app Then you need to populate it The cool thing about Spanner is it’s plain vanilla SQL So this is just some plain SQL I just created it and pasted it in on the Spanner console and created my table The app we’re going to create is just a very simple posts app that has messages And like I said before, there’s no Active Record support Fortunately, there’s this thing in Rails now called Active Model, which is a lot of Active Record without the database But you just need to re-create some of the methods that Active Record would otherwise give you So what’s going on here? When I was more ambitious, there was an image uploaded on this app It didn’t quite work We have the Active Model in this post class We also have a few other things, like these URLs helpers, that just make things work Unlike an Active Record app, you need to create this attribute accessor These are just the various attributes that’s in the database that lets you access them And you can do validation And that’s the basics of creating a model Then we just need to re-create some of the methods Active Record gives you Here’s a simple finder You pass in an ID Then it just executes this SQL, where you find a post and return the first one There should only be one, but better safe than sorry So that would be post.find Then once you have one, if you want to save it, boom You just do a transaction and insert the stuff into the database I’m just passing in whatever got set on that model

And you could do a Find All, where you just do a select* and limit it to– if you have a lot of stuff, you don’t want too many of them So this is re-creating the methods that Active Record would give you by default Again, if we make an Active Record Spanner adapter, you won’t need to do this It’ll be really easy All right Then setting up Cloudflare So Cloudflare, you just add a site You create these things called pods Pods are nominally collections of servers But since with serverless you are getting a collection of servers, you basically just map each of these to one of your deployed instances And then you create a load balancer And the load balancer is just saying, load balance between these pods And you can see at the very top there, you give the URL In order for Cloudflare to work, you need to be doing your DNS And it will automatically create all the DNS magic You could also create some health checks here to just make sure it’s working OK So let’s switch into demo mode again Wake up my computer Now, the demo gods were not friendly to me And for some reason, the– so here’s the app And maybe my internet’s not even working Oh, wait I see Wrong URL Boom All right So it says this app is being served from the EU So the demo gods were not friendly to me, but it actually helped demonstrate some of the power of this For some reason, I could not get the US version of this app working Something got borked in the configuration But guess what? The Cloudflare georouting also does failover So it’s routing us to the EU version of the app And that’s basically just pulling out a config var that lets you know where it’s being served from, that little message at the top So what this looks like in Google Cloud– whoa, too big So you go into Google Cloud’s console, and you tap on Cloud Run And basically, you could just create a service Actually, let’s deploy Let’s show a full deploy here I’m going to go to my command line And here is the directory So here’s this Hi World app I need to switch to the project So again, we talked about those projects This app has its own project All right So now I’m going to use that project And now I’m going to do a build Let’s just see I’ll just pull it out of my command history here All right So gcloud builds submit And you give the tag So we have this other product called Cloud Build And it takes a Docker file and builds it for you So I just told it to build that and tag it with this– gcr.io is our container registry And it’s going to fetch this thing and pull it all up into the cloud You can also do the build locally with Docker and then just push it up there It actually will work faster if you build locally, because right now, Cloud Build does not cache your layers in Docker It just goes through all the regular build stuff This is just plain vanilla Docker Nothing special about this That’s the power of Cloud Run Once it’s built, I can create a service And I just go into Cloud Run Here, let’s start from the beginning I just go into Cloud Run, click Create Service, pick my container image There we go Give it a name Now, when you pick a region, this is Cloud Run not on GKE Right now, it’s only available in US central But then these are my GKE clusters that I set up before I just pick which one I want Can deploy it to Asia And we allow it to connect to the internet Optional settings You can pick how much memory each instance of this app gets

You can add any config variables you want here So on this app, I’ve got a region Click Create And it’s going to deploy And that’s all it takes to deploy something to Cloud Run And then over here, just to show you what’s happening in Cloudflare, we’ve got this load balancer Is that visible? So in Cloudflare, there’s this little traffic tab here And you set up a load balancer I’ve got this one It’s hosting the demo subdomain And you can see it’s got two pools active Here’s that US pool that wasn’t working I just turned it off because it was having problems But now, it just routes to my European pool and my Asia pool If we take a look at one of those, this is just the default IP address that I get on Cloud Run on GKE I just stuck that in there straight out of the console I’ll show you that Here’s that European version of the app There’s that And I basically just copied and pasted that into here And here we have the working Hello World app Super small Wrong way Hello Cloud Next 2019 Boom And there it is Hello Cloud Next Second time I’ve made that message OK, it works Cool Being served from the EU because the US is down right now And that’s a world-spanning Ruby app Can we go back to the my slides? Thank you World-spanning Ruby app You saw it here first There’s nothing special about Ruby You could do this with, really, any Docker container– Node, Bash, whatever you want Just need to list it on port 80 All right Wrapping up So I think one of the points of this talk is Google Cloud has a lot of cool building blocks There’s Spanner There’s machine learning APIs There’s all these cool things And what’s really fun is in just a couple of days or a couple of hours, depending on how good you are– took me a couple of days because I’m a really bad programmer– you can snap them together and create something really powerful Second takeaway, Ruby is on the cloud in a big way It’s on all those services So if you’ve been waiting to use Google Cloud but were deterred by the lack of Ruby support, it is there now And again, to try it right now, there is the URL Just join that Google Group, and you can use it today I would love feedback Just email me directly, S-O-L-D-O at Google [MUSIC PLAYING]