Transcript
and friend, Gister Beke. Hey, how's everyone doing? In episode two, we're going to focus on setting up an ingress of Load Balancer in front of the compute resources that we deployed in episode one to be able to expose the Nomad UI. We're going to walk you through setting up the Load Balancer, setting up IdentityWare Proxy, some DNS, and the Load Balancer in general we're going to cover. So Chris, did I miss anything? No, I think that's about it. I think we have a very healthy, nice Nomad cluster running now, but of course, it's not very helpful if you can't access it. So yeah, let's today roll out all the stuff we need to get some traffic into the cluster and I think it would be a nice goal if at the end we can actually see the Nomad UI and see all the servers and clients and what they're doing. Yeah. And do I see you wearing the Nomad T-shirt as well today? Yeah, of course. I have it on. Nice. Awesome. That's amazing. Cool. So I just mentioned DNS, IdentityWare Proxy, Load Balancer. I think these are the three things that are going to be fundamental to this episode, but would you briefly like to explain to the audience why these three components are required for setting up Ingress for the Nomad UI? Yeah. So as you saw in the last episode, we're working with a VPC, Virtual Private Cloud Network, with private virtual machines running our Nomad servers and clients. That means that there's no traffic allowed to go in. And of course, it's not very helpful if you want to run, for example, a web service and serve a website on the internet. So in order to make that work, we need a way into our cluster. And in Google, to do this safely, you need a load balancer that is exposed to the internet. And then you need to attach this load balancer to this group of servers we created as a backend. And of course, because we want to expose our Nomad administrative UI, we should also add some security to that. So we're using Identity-Aware Proxy, which is an authentication gateway, basically, that we can enable on the load balancer that forces me to sign in with an authorized Google account in order to see this admin UI. Right on. Do you think we can draw it out in ExceliDraw or something to make it a bit more tangible for the audience? Yeah. Do you by any chance have that open? We can open it up right here. So here's a new- Nice. All right. So as a short reminder from previous time, we have our sort of managed instance group. And in here, we have a couple of servers. Let's do three for now, because we actually deployed three. And this is all private. So it's like a completely pulled off environment. Nothing goes in and very restricted access outwards as possible. We saw last time we configured our firewalls to do this. But now in order for the user to access this, let's put the user right here, all we want to do is we want to put a global load balancer in front. And then we want to point the backend of this load balancer to these three servers. But if you would draw a line right now from the user to the load balancer to the servers and expose our admin interface, everyone in the world would be able to access it, right? Even if we put a password on it, it wouldn't be very secure. We don't want that. So for a public web service, that's fine. We'll cover that in a future episode as well. But for this admin UI, we want some extra security. So we're putting an extra layer in front here, which is called Identity Aware Proxy. And that is a service from Google to sort of protect your load balancer backends with another layer of Google managed identity. So Google forces an open ID connect login exchange before traffic is evaluated and if approved, routed to your actual load balancer. So this is what I'm going to set up today, these components. Awesome. Nice. So maybe we should go back to our code base and start writing out a load balancer. Yeah, I think the first thing we need though is an IP address, right? Otherwise, nothing is able to access our server. Exactly. Let me pull up my editor on my side as well. Give me a brief moment. Oops. Alrighty. Fix my mic real quick. Okay, so I think we're going to create a load balancer. Yeah, I'll call it load balancer UI or admin. I think the actual path that we're exposing is slash UI. I'll just call it load balancer. Actually, I'll just call it GLB for now, GLB.tf. And if we ever get another load balancer, we can always split things up. Yeah, so why do we need an address? Right, so we're going to set up DNS in a little bit as well. And in there, we want to make an A record to a single IP address that is always the entry point of our admin UI. And from there on, it is distributed to our different servers that we have running. If you have three servers, you don't want three different IPs because you would get a different thing every time. So our load balancer takes care of the load balancing, but it's not that you need a single static ingress IP address that you can sort of claim and point your DNS to. Yeah, and we're going to set up several different resources. So in Google, when you're creating a load balancer, it consists of multiple components, a backend service, a URL map, forwarding rule, and an HTTPS proxy. So those are resources we're going to set up right now. And I'm, I think, Chris, if you could, I'm going to write out some resources, but maybe you could give like a voiceover of what I'm doing. I'm terrible at talking and coding at the same time. Yes, I'm good. So yeah, like Bruno said, a load balancer is a pretty broad, we have three layers. You have a front end that sort of determines your domains, your paths, your methods, everything that is sort of reachable. Then you have your backends, which are targeting for instance, in our case, our managed instance groups. And between those, you need sort of a map to route traffic to the correct backend, and that is called the URL map. And so we're going to define Terraform resources for all three of these layers, and together they will act as the load balancer. So we're starting with the backend here. We're going to use a load balancing schema called external manage, and that is Google's sort of next generation global load balancer, which has a lot of options for advanced traffic routing that we might want to use in the future. So I think if you're setting up a new load balancer in Google, you should always go for this new version. So yeah, as our backend, we're targeting a managed instance group, and in Terraform, you target this using a group attribute, and we're targeting our previously created instance group. Yeah, I think balancing mode utilization is a standard mode. I think that's pretty good. It should be fine for any default kind of behavior. And like we discussed, we want identity where proxy, so we are also going to configure that. We probably need some values for this ID in secret. So that's something we need to create in Google's console, and now we need to put them in our Terraform code. And what's the reason we have to do it through the console? So in order to provision an open ID or OAuth2 client for identity where proxy, Google generates your client ID in secret, which is a fairly normal pattern for any OAuth-based system. And once you receive those from Google, you can put them in your configuration for your backend. Yeah. SSL certificate. Yeah, so the URL map is fairly simple. We're just targeting our backend service as a default service because we're not having multiple types of backends here. We want to be secure, of course, so I very much like that you're setting up a managed SSL certificate already. I need that. And yeah, indeed, we need a name, a domain name, actually, a little bit as well. So we put it in a local. Yeah. So I'm thinking out loud. We're going to... I reserved a domain name for us. Maybe you could show the viewers which domain name we got. So we should have it in a Google Cloud project. Right. We registered something. Have a quick look in Google Cloud. Yeah. Google domains. Yep. All right. There's one active here. That would be nomad-on-google.cloud. That's the perfect domain name. Nice. Nomad-on-google.cloud. Yes. I love it. Nomad on Google Cloud. That is awesome. Okay. I'm quickly looking up something, a little function. I guess what I would love to do is this. To be fair, I think I can just call it this as well. Okay. So name project is local app project. And then we have the managed block for domains. We're going to put in this. No, that's not correct. That should be domain. Damn. Damn Copilot. Nomad underscore domain. Right. Yeah. So this would be nomad. Yeah. What should we do? Should we use a subdomain? All right. I think maybe just this. What do you think? So I think we'll have multiple entry points in the future. One for admin stuff, but also stuff for like public. So I think it would be a good idea to reserve a separate subdomain for purely the administrative stuff. Okay. So we could do like admin.nomad on google.cloud. Maybe. Sure. Yeah. It also works. Alrighty. So that's done. Then we're going to set up the HTTPS proxy. Yeah. That's just a simple proxy usually known as a front end. And I think here we're going to target our URL map, which points purely to our backend that we already created. And we also load our SSL certificates so that we can do the TLS termination in our proxy. I'm not getting any certificate issues towards our manager. So I've been naming everything. Nomad underscore UI. But you've been calling it Nomad admin related stuff. Would you like me to rename the Nomad UI things to Nomad admin? Yeah, I think it's nice to keep the naming consistent. Sure. I think it's always a good strategy. Yeah. Nice. And this should be almost done. Yeah. Thank you for helping out. So that's all Nomad admin, Nomad admin, Nomad admin. Cool. Then just a forwarding rule that is referring the address that we reserved and the target. Do you want to quickly explain what the forwarding rule does? Yeah. The forwarding rule is basically like the name already implies. Forwarding the traffic, the proxy you've set up. So this is a place where we sort of route the traffic from our IP address to our target HTTPS proxy. And here we also indicate, for example, which protocol and ports we want to accept. In our case, we're only accepting HTTPS traffic. So we're going to use TCP on the range 443. Yeah. I always get confused by this port range argument, by the way. Target is Google Compute. I got fat fingers. I'm sorry. And a lot of people are watching. Nomad admin.id. And then it's the IP address, which is the Google Compute global address. Nomad admin. Alrighty. Okay. So all the null values are still to do. So there's a I was filling in a health check, but we haven't specified a health check yet. So let me work on that. Google. You can already set that up probably because we next to having health checks already on our managed interest groups. We also want to check the health of our actual services that are going to be used by our users. In this case, ourselves for the admin purposes. So let's set up a separate compute health check targeting our load balancer, basically. Yeah. Yes. I import 4646. Indeed. And I think the path is slash UI slash. Okay. So we also have, I think at some point we're also or we already have correct me if I'm wrong, but there's also an agent health. Oh, we did that. So for this load balancer, we're targeting a UI. But for our servers and agents, we're, we are, we are specifying the request path as V1 agent health, which is a dedicated health endpoint for, for Nomad. We're for a load balancer. We're specifying the UI. Okay. So if you want agent health is really an internal thing for cluster health, which is not to expose publicly. So for the purpose of our app, we're just checking whether our app is actually running. Yeah, indeed. And we kind of set up the IEP credentials. Chris. Yeah. That's something we Google cloud. Right. Okay. Yeah. Yeah. I think so. So we can navigate here to the aware proxy. Actually, let me check out one thing. I'm curious because I know that there is a little, I know that there's a resource for IEP, but I think there's a little note that it's only allowed for organizations or something or internal stuff. Let me check. Only internal organization clients can be created through Terraform. External clients must manually create, must be manually created by the GSP console. I think that's why we have to create it manually. Yep. Yeah. We're not building like an internal company app or something. So. Oh, the API is not enabled yet. So that's why we have to create it manually. Yep. That would be in our services, right? Yes. I just added it. Cool. Assuming that it's IEP.googleapis.com. Let me quickly check. Yep. It is. All right. So if I apply this now, I would also apply the same thing. I would also apply the same thing. Yeah. I would also apply the same thing. Yep. It is. All right. So if I apply this now, I would also apply our load balancer, right? Yes, that's correct. Which one, I think? I think we should first get the IEP credentials in there. Okay. Then what would be the correct order of things now? Should we comment all this out? It depends. So do you want to create the IEP credentials first and then substitute them in here? I need this API to be enabled first. Oh, okay. I'm sorry. I thought you just enabled it to the UI, but you wanted it to be there first. Okay. Yeah. Let's comment out this thing. Feel free to comment out the GOV. Yep. Okay. Yep. So for now, we're only going to apply this new service. Yes. So that we can create those credentials in the UI. Yeah. I think it's a good practice to, if you can use Terraform to do something, you should not use user interface when absolutely needed. There we go. Yay. Let me refresh this page. All right. It's enabled now. Let's go to that service. Yeah. So that was what confused me, because when you create the credentials, you do it through a different service. So it's not IEP. Yeah. On the top, if you type an OAuth client credentials. It's a different, it falls under like the consent screen stuff. So I think we have to create a consent screen first. Yeah. Quick note, we, we have a consent screen for this. We have a consent screen for this. We have a consent screen for this. We don't have a consent screen for this. So we don't have a consent screen for this. Quick note, we, we cut out a small portion of the video because we were setting up the consent screen, which you will see on screen right now. Our email, I'm just sort of blurred because we're going to want to share it with you. No hard feelings. Let's, let's head over to credentials and then start setting up our credentials. Sounds good. So here we can create some new credentials, I think. The OpenID Connect is based on OAuth, right? So we need an OAuth client ID, I think. Yeah. We're going to set up the web credentials. I think it's a web credential. Yes. And then, yeah. Name can be data. And then for the authorized, actually authorized JavaScript origins is going to be the URI. So it's going to be like https://admin.nomad-ongoogle.cloud. Right on. And for the authorized redirect URI. If you copy paste. URL from what? Yeah. If you copy paste the first URI that we configured in JavaScript origins, that one needs to be a redirect URI as well. And we're going to set up an IAP redirect URI, but we can only do that once we have the client ID. All right. So if you go ahead and what does it say there? Okay. So if you create this, You're going to get these. These values are going to be blurred, of course. But if you copy the client ID as well as the secret, just persist them somewhere so you don't lose them. And the secret. All right. Yes. Awesome. There we go. Yeah. And if you then go back to the web credential that you just configured, Nomad, then there's an IEP URL that I share with you. And you're going to have to substitute the client ID in there. All right. Because this is actually the URL that Google sort of injects in front of your load balancer for identity or proxy, right? Yeah, that's correct. So I didn't do our proxy. Once you authorize your proxy is going to redirect us to our load balancer. Of course, we've blurred that client ID there as well. Sorry for that. But we don't want to share our secrets with you. Okay. So that is done. That means we can now start setting up and deploy the load balancer and we can inject those, the client ID and credential. There's two things we can do. We can set up variables for our secrets. We can also create secret entries and secret manager and then fetch the values from there. What would you like to do, Chris? Well, I think in a really production environment, I would put in a secret manager, but maybe for the sake of time and easiness here, we should just put them here. Sure. Feel free to go ahead. You should have the values. Yeah. So I just configured two variables, an OAuth to client ID and an OAuth to client secret. Yep. All right. Nice. Cool. Feel free to just run through from file. I think we now need to target our- No, no. That should be. So Terraform also automatically loads a number of variable definition files if they're present next to like auto.tfrs and auto.tfrs.json. There's also terraform.tfrs and terraform.tfrs.json from the top of my head. So this should load it in. Oh, yeah. You already ran up on it. Nice. Any other file that you specify for tfrs, you would have to pass the far flag file. No? Sure. Far file flag. Sorry. What is it complaining about? Oh, the ID. Yeah. Have any resources. That looks pretty good. We have the URL map, the proxy, the certificate, the health check for our service, the forwarding rule, our IP address, and our backend. That looks good. Yay. Ship it. There we go. So I think most of this will go relatively quickly, but our SSL certificate might need a little bit of time to be validated. I think we forgot one thing. We have to configure the address of the load balancer in our DNS zone. Otherwise the certificate will never be validated. Yeah. So let's do that. Would you briefly like to explain to the audience what I just said? Yeah. So for a managed HTTPS certificate, Google uses DNS verification, and that means you have to prove via a DNS entry, in this case, an actual A record pointing to our IP address, that this domain name that you're trying to register an SSL certificate for actually belongs to you. So, yeah, for this DNS verification process, we need to create that A record entry. Yeah. And we registered our domain using Google Cloud Domains, which is automatically creating a DNS managed zone for you. So that's why I'm using a data source right now on the bottom of this file, to be able to check whether that managed zone actually exists. And if so, I'll get the ID. I'm going to insert an A record in there, the record of the load balancer address that we reserved, which is the resource all the way on the top that I'm highlighting right now, this Google compute global address. So let me quickly look up what the name of the zone is. I believe that's just Nomad on Google Cloud. Then I'm going to create an A record. Give me a brief moment. So in the meantime, we actually got an error on our Terraform apply. Managing schemes don't match up. External manage. Thank you. All right, so this DNS zone, we don't have to create it. It's automatically there because we use Cloud Domains. Now you're setting up our A record. Yep. Point our admin. Nomad on Google Cloud subdomain to the IP address that we reserved earlier, right? Yes, that's correct. So that's what I'm doing here. Project is local app project. I don't know if the DNS record set takes a project. I just assumed that. Let me quickly look that up. Registry. Yeah, it does take a project. Okay, great. Actually, TTR can make 300 because I don't expect this to change at all. So what we did here, we're creating that record set. We're pointing to admin. And then the Nomad domain, which is Nomad on Google Cloud. That actually needs a trailing dot. I just remembered. That's how DNS works with a trailing dot to indicate that the FQDN is finished there. Then it's an A record with a TTL of 300 seconds. The managed zone is the Google DNS managed zone that we automatically got from Google when we registered the domain with Google. And then the value of the record is going to be the Nomad admin address, which is all the way on the top. It's a reserved compute global address. Okay. Can we apply this? Yeah, let me verify one thing. I just assumed from the top of my head that this was the address. I quickly want to validate on the registry that that is correct. I think the output looks good. Okay. So we have our record set. And, yeah, we're going to be deploying all the other services. Very cool. Maybe let's take a look in the Google Cloud UI what the status is of our SSL script. Yeah, let's do that. Maybe let's take a look in the Google Cloud UI what the status is of our SSL script. Yeah, let's go to the load balancing page. We should be able to see our new load balancer. It's being checked. But it already defined our backend service, which is our managed instance group, and it's marked as healthy. So I think the entire chain of resources we just created works. Very cool. So for the certificate, we can actually dive a little bit in here and have a look at the certificate details. It's currently provisioning. It says here it can take 24 hours. In my experience, it's usually 15 to 20 minutes. Yeah. So we have to wait a little bit for that to finish provisioning. At that point, I think we should be able to go to the address that we registered and see our dashboard, right? Yeah, that's correct. So we're going to quickly teleport. Nice. There we go. Active certificate. It only took 10 minutes. Yeah, everything looks okay. It seems like the certificate was properly verified using DNS. So I think that's actually it for what we need to deploy. So let's try and visit this URL and see if we can actually reach the NOMAD UI. So I'll type it in. It says in NOMAD on Google Cloud. Sounds good. Our page. Let me switch a little bit to English here. It's not the NOMAD UI. No, no. So for those familiar with Identity Web Proxy, if you're not signed in, Google will immediately redirect you to a Google sign-in page. Then you sign in, and then you are redirected back to whatever application you're serving behind Identity Web Proxy. So this is a screen I would expect at this point, so it looks still pretty good to me. I can select my account, sign in, and then we should see the NOMAD admin UI. Yeah. Right. I know why that is. Still a good moment for us to explain what's going on. Yes, I'm fairly sure that you need an IAM binding called IAP General Resource Accessor. Right. So maybe we should set that up, right? Yeah, we should. I think we still have an IAM.tf where we can set that up. Let me go ahead, head over to here. I'm going to do something like IAP General Resource Accessor, because we're going to do multiple. Let's create a little focus. Can you double-check on the role binding name for me, please? Yeah, sure. I could actually have a look in the Google documentation. Actually, I'm going to do this differently. So that's IAP HTTPS Resource Accessor. And it's IAP.HTTPSResourceAccessor. Oh, it's HTTPSResourceAccessor. Almost correct. Like this? Yeah. Okay, great. I need to make it far, because there's going to be multiple NOMAD admins, and we're going to hard-code them in a file, of course. I believe this should be like a Google group. Maybe you can briefly explain how that would work, Chris. Yeah, so in Google, with IAM, you can target users or groups or service accounts or any other kind of sort of principal account. Normally, I would make a Google group, and I would put all the people in there that should have access, and then we give this group, the IAM member, role binding. But for the sake of this video, I think it's easier to just target a couple of individual users, which would only be the two of us. It's easy to manage still. Yeah. One brief moment. So around the schemes, you're setting up the values for these NOMAD admins, right? Yes, that's correct. If you could go ahead and run a Terraform plan. We'll just quickly see if that works. Getting an error. Oh, yeah, I flagged it as sensitive value. I guess it's not allowed to put in there. I wasn't aware of that. I never tried that, actually, to iterate over sensitive values. I just didn't want to expose the... Yeah, you can give it a try again. We can always blur out our email addresses. That sounds good. Yeah, there we go. Some blurring needed indeed, but it looks good. So let's apply this. Now we're getting an error. What's the error about? Oh, sorry for that. It has to be prefixed with a role slash. I should have known that. It's fixed. I missed this prefix of role slash. No problem. Live coding, people watching. It's stressed out. I forget things. All right, there we go. Shall we reload this page and see if it works? Yeah, I'm curious to see. Maybe there's some caching at hand as well. Yeah, it could also be that you have a cached response, Chris. Yeah. You can try and reload without caching. I'm not sure what that option is. Ah, there we go. Just took some time to propagate. Cool. This looks like Nomad. Nice. We did it. Very cool. So we don't have any jobs yet, of course. And that's probably something we'll do in the next episode. But today we're going to talk about how to create a job. But today we can still have a look at the servers and clients which we provisioned. So we can actually see the three servers we have in our managed instance group and their IP addresses and the leader election. So, yeah, this is exactly what I would expect at this point in time. So I'm really happy with that. And I would also expect three clients to be there. And they are indeed all here and they're all reachable and they're all on the correct version. So I think we have a fully working Nomad cluster. Still very basic. We're going to add a lot of stuff in the future to really make it production ready. Add a ton of metrics, add applications, add storage, network for Docker and whatnot. But I think this is a very good starting point for a healthy cluster. Nice. This is amazing, Chris. After deploying our compute resources and our load balancer and setting up our proxy, we get to see the Nomad UI. That's great. And indeed, in future episodes, we're going to actually do something and run something on Nomad. We're going to deploy. Yeah, would you like to spoil a little bit how our future episodes are going to look like so people can look forward to it? Yeah, we're going to have a couple of episodes from here on. I think the first one coming up is actually deploying a workload. After that, we're going to make sure that this workload can actually be accessed by people via the internet as well. So we're going to set up a load balancer, but this time for more public use. We're going to do some stuff with storage interfaces so we can store files and retrieve them again. Do something with Docker bridge networking. Some service discovery with traffic. Yeah, if we're going to run multiple services, we're going to do some internal ingress and routing, probably using traffic, which I like very much. And we're also going to do something with autoscaling based on not only active CPU usage, but also allocations. Because you want to scale up before you run into problems with your resource limits. So very much looking forward to exploring those capabilities. Super exciting. We're going to wrap things up for today. Chris, thank you so much for doing this together with me. It's an absolute pleasure. And viewers, thank you very much for watching. You've all been wonderful. We're going to see you in the next episode, which is going to be episode three. Focus on deploying a workload and making that accessible to you. Chris, thank you. Viewers, thank you. And we'll see you soon. Bye-bye.