KubeCon + CloudNativeCon Europe

Leveling up with Radius: Custom Resources and Headlamp Integration for R... Nuno Guedes & Will Tsai

30:40 · 23 Mar 2026 – 26 Mar 2026 · YouTube

About this talk

This talk introduces Radius, an application platform developed by the Microsoft Azure open source incubations team. The speaker explains how Radius enables developers to define portable applications that can be deployed seamlessly across various cloud providers while maintaining a clear separation between development and operations. The platform incorporates a Universal Control Plane that abstracts infrastructure details, simplifying the deployment process for developers. A demonstration showcases the deployment of a to-do list and chatbot application across local and cloud environments, highlighting the flexibility of Radius in handling different resource types. Nuno, representing Millennium BCP, discusses how their team customized Radius for compliance and legacy system support, emphasizing the importance of clear interfaces and stable contracts in managing application life cycles. Overall, the session illustrates Radius's capabilities in fostering collaboration between developers and operators through a structured approach to application management.

Full transcript

Thanks everyone for being here. My name is Nuno. I'm head of full cloud at Millennium BCP, which is a bank in Portugal. And will My name is Will. I'm a principal product manager on the Microsoft Azure open source incubations team and really happy to be here and talking to you guys. So we'll jump in then. Before we get started, I'll kind of go through Radius and give

you an overview of Radius and then hand it over to Nuno who will talk about the more exciting stuff that they're doing with Radius at Millennium BCP. But before I jump in, I'll give you a little bit of background on where I'm from and the the team I work in at Azure. Our open source incubations team, we sit in the Azure office of the CTO. Our charter

is to work across the company and the open source community to solve problems that benefit the industry at large, not just Microsoft or Azure customers, but the industry all up. And to do this, shipping open source code is our main priority. As a part of that, we partner closely with the CNCF to provide open governance for our projects and to help us build these vibrant innovative communities

around each project. So of course today I'm talking about Radius specifically, but I hope you have a chance to check out the other projects that come out of our group as well. So what is Radius? You can think about it as kind of like an application platform that allows you to to define portable applications that can be deployed across different platforms and cloud providers. And the way

it works is sort of we think about it in these four pillars of functionality for Radius. You can think of the Radius resource types as the abstract interfaces that the developers work with when they are putting together their applications. They shouldn't be worried about infrastructure concerns and infrastructure decisions during the development phase when they're building On the other hand, the operators think about infrastructure, right? And infrastructure

recipes in Radius are akin to the concrete implementations of the respective resource types where the operators would encapsulate all of the infrastructure requirements, such as security and cost best practices, uh into the uh infrastructure uh give these over to um the developers to use, right? But uh the main thing is that this kind of setup enables a clear separation of concerns between the developers and the operators.

So, you can think about Radius enabling you to build your own APIs in front of your infrastructure, in front of your developer platform. Uh developers deploy their Radius-defined applications into these target Radius environments. And in these environments, you have all the necessary recipes and settings preconfigured, which means that infrastructure decisions can be made when the developer targets a particular environment for uh deployment. And because there's this

structured approach to building and deploying applications, what you end up with is a very rich application graph that shows exactly what's been deployed and how the application is pieced together with all the interdependencies and connections between the resources. And then, of course, this platform and API approach to managing applications and their corresponding infrastructure allows for a much more effective deployment and management of applications across platforms and

clouds and enables this very efficient workflow or collaboration model between your developers, your operators, and your SREs, as well. And at the heart of everything is the Radius Universal Control Plane. The Control Plane model that we have built into Radius enables you to build out your infrastructure in a platform-in-API-driven manner. And it is this Radius Universal Control Plane that enables the level of abstraction that you're able

to achieve and really allows you to future-proof your applications against any infrastructure changes in the future that are undoubtedly going to come up. And this this visual I really like because it shows the need for an abstraction between applications and infrastructures the platform teams can use Radius to front their infrastructure with a set of stable and developer-friendly APIs. But under the hood, the platform engineers and operators

can manage their own IAC templates, binding the relevant Terraform or Bicep modules to their respective environments and in effect provide these really nice deployment landing zones for developers and their applications. So, we'll see more of these in in action from Nuno when he shares some of the stuff they're doing at Millennium BCP later. But before we get to that we can take a look at a quick

demo that I'll show. If you're familiar with Radius and you've, you know, watched some Radius talks in the past, you might be have seen a variation of this demo before. But today we'll kind of deploy the whole shebang, right? We'll deploy the to-do list and chatbot application across a a plethora of environments and see it running in these environments. So, here's the demo. And you'll see that

here we have a sample demo application, which consists of a front-end a Redis cache, and an AI model to power the chatbot. Now, let's take a look at the Radius dashboard as well to see what resource types we have available for us to use. The resource types that are relevant for our application are the Redis cache and this AI model resource type. So, let me click into

the AI model resource type and show you the details and developer documentation that the platform team has provided for this type for me as a developer. We see there's a model name property that I have rights to adjust. Um but you'll notice that I can't really adjust anything else. The only thing I can provide as input to this resource type is the model name. Now, we can

take a look at piecing together the application definition, right? So, I have a front-end container that I've defined that depends on our two resources, the and then also the AI model. And these are both connected to the front-end container. And then notice I'll pass the model name as input parameter. So, now we can go ahead and deploy the application. So, what I'll do is use the rad

run command to deploy and run the application. We'll use a tiny llama model target it at our local dev environment. So, Radius will deploy a locally hosted AI model and a locally hosted Redis cache resource um on my local machine. So, once the deployment completes, we can go interact with the app on port 3000. This is all hosted locally on my I type in, you know, a

prompt. So, I ask for it some feedback on when to do laundry, and I click the chat button, the feedback button. And as you can see, the uh AI feedback is, you know, not so useful. It's a small model within our environment, so, you know, it's not too sophisticated. What would be more interesting is if we deploy this to the cloud and leverage the more sophisticated models.

So, in this case, I know I have a an AKS environment in Azure where I can make use of a GPT-5 nano model. So, I point it to my AKS environment and hit deploy. And now it's finished deploying. We can refresh the uh port, and this now is hosted on my Azure environment in the cloud, and as expected, you get much richer feedback from the AI bot,

right? This is actually useful, not just a list of times I can do laundry. So, you know, that's not it. We can actually take this exact same point it to our AWS environment, and deploy it to our AWS environment, and Radius will provision AWS specific So, you'll see here in the deployment that uh I fed it the AWS environment name, and then also specified a different model

for uh the AWS environment. I hit deploy, deployment completes. Now I can use a rad app graph command to see what was actually deployed to my AWS environment for this application. And we'll see zoom in here, and we'll see that as expected, it provisioned AWS specific resources, a memory DB cluster, as well as uh AWS bedrock instance to serve the AI model. So, yeah. Now, there we

have it. We've taken the exact same application definition and deployed it across three uh different infrastructure provision in all three environments, all without me having to modify my application, my application definition, or source code. So, now I'll hand it over to uh Nuno. Thank you very much. what if you want to deploy something that's not available out of the box? What if you want to customize it?

What you need to support legacy stuff? Compliance requirements. Most of you will have to need to do some customization to improve support for resource types. And in Radius, we can think of that as different names for things we've been doing for a long, long time. If you look at this as a coding business as usual work, you typically would think about interfaces, implementations, dependency injection, and all

of those typical programming concepts. You can do the same in Radius. If you think that interfaces are called resource types. Implementations are called recipes. You do dependency injection patterns with environments and so on. This is something we all know how to do. For instance, imagine you were going to implement Go code to spit out Postgres databases. I mean, that's the possible interface for it, right? A struct

an input struct an output struct uh something to receive the con- context and give you that instance. If you write the same thing in Open API schema spec, it's the same thing. I'm sure any of us, for for better or worse, understands Open API schema. And it's the same thing, just a different language. Implementations, sure, you'd write some code to generate a username, a password, actually create

the database, now build out a connection string, push it out. Guess what? Do it in Terraform. Same thing. Input variables, outputs, put your code into it. Same principles. And for us at Millennium BCP, we had to do a whole lot of this because guess what? Compliance. Now, it's a bank. We have a lot of requirements around compliance. We need to support the rest of the of the

IT ecosystem and things as worrying CMDB for instance. And well, we already have processes for approvals for the whole ITSM workflows. We needed to be at least compatible with those. So, guess what? Custom implementations, custom types. But just by bringing those existing things into this approach, we gain the very simple thing, but also a very important one. And that's clear separation of concerns. For some of those

systems, it wasn't what the responsibility matrix was. So, by putting it into this pattern where you have an interface, you have multiple implementations and so on, it helps us get this clear separation of concerns. What the devs need to care about, what ops needs to care about, and And also, clear visibility on these different life cycles. The interface has a long life cycle, the interface is stable,

implementations change a lot. And maybe in some of these, every week there's a new version being pushed out and all of that. Do developers care about that? No, developers want an interface where they can specify what the application needs, not if the Terraform behind it is uh pushing out a new tag to the resource or not. So, we end up in this pattern where contracts are stable,

implementations have very short life cycles. And honestly, nobody cares cuz different concerns are equally serviced, if you want. And all of that because we start with intent. Now, we define that contract. We put everyone in the same discussion. Devs, SREs, ops, all of that. And we decide, yeah, these three fields are actually what matters in the resource. Or something like that. with this approach, we ended up

implementing multiple things. As I was saying, CMDB FinOps stuff cuz we kind of need to decide if we're going to spin up resources or not. And a lot of different resource types. Some of the database engines we run. For instance, observability. I think that's that's a good example because if you put observability into a context where it can see the application, you're also automating a universal baseline

for observability. You have the an initial set of alerts, for instance, that you can figure. You know what metrics you're going to pull. And that's just a custom resource type going into the application dependency graph. So, with this, we augmented the initial resource types that were available. And not only that, because it's Terraform, we're now targeting additional landscapes to run this. Things like GCP, on-prem, private cloud.

And so, the universal control plane is always doing the same thing, ensuring resource types and running implementations. But, it's our business. It's not the out-of-the-box pattern. Let's go with Let me show you, or try to, very simple example that sometimes people do not think about. Cool. This is a schema for a resource type that gives you no resources. It's just an interface that says, "Give me your

application ID, and I'll what the systems around you know about you." We call it allowed capabilities. Like that application can have databases or It can do messaging or not. It's allowed to have caching or not. But, someone decided that because that application needs to follow a certain Or things like resource tags. Where some external system says, "You need to put a tag with the cost center, and

here's the value." And all of that. This is a very simple schema Well, it's just this, you know. Couple of objects in the outputs. Couple of inputs. And the value of this, at least for us, it's almost essential because, well, when you spin up a resource, you kind of like to know what cost center you're going to put it on it, for instance. no matter what implementation

is, on multiple environments, this calls different things, naturally, and not just a matter of endpoints, sometimes it's really different systems. Publishing this it's as simple as and I'm going to show you the script we use for this. It's calling red resource type create to generate. bump this up. To register that type and just like I did here it's registered. Now, the fields are there, the description, all

of the typical schema stuff. And also, what this script does pulling this one down is to do publish extension, which means that as I'm local this zip file gets a definition, but this in real life is getting pushed to a container registry. It's an OCI artifact. So, your platform users just register an OCI artifact on their machines and they have the type available. They can start coding

against this type. And again, doesn't matter what it's just an interface. But cool people get interfaces, build implementations, now publish V1 of the app, the thing crashes. Now, out of memory stuff, all of the issues we learn and and fight against every day. The next challenge that we had to solve don't care too much about looking at the YAML and all of that, especially because that's time-consuming.

We also did not want to and and Will's demo you saw the Radius dashboard. We also did not want to put another new tool with any of those roles the operators of the app have and such. So, what we did, now these guys here, publish a new plugin for Headlamp. I'm sure everyone knows about Headlamp. So, in the plugin catalog, now there's a saying Radius. And with

this plugin sort of the same thing you can see in the Radius dashboard and the typical Headlamp interface. So, given that we run Headlamp in our clusters for our users, it's a typical experience that they have. Now, looking at pods and looking at resources in in Radius, it's the same thing in Headlamp. They just They just a different thing on the menu. So, you can you have

the the overview dashboards, you have the typical list of resources, resource that we were discussing. And it's basically And let me see if mine works locally cuz my cluster didn't feel like it today. So, here it is, standards headlamp experience. I have an application deployed. I drill down into it. Here's the typical detail. There's a container resource in this application. I can see the details. I mean,

again, standard headlamp stuff. So, this is the experience we want our internal users to have when going after radius day two operations. And summarizing, basically, these are two views on a statement which is everyone has a different view on the same source of truth. Either when we are in the beginning of this journey when we're talking about or when you're all the way into day two operations,

thing. It's the same contract. It's just different views on the same contract. the focus is to make the platform approachable because people see themselves in that but do not oversimplify. Complexity is there set to the level that each role wants to to see it. With that docs, codes, and discourse are there. Please, you know, drill into it. And if you have any questions, feel free. Questions? You

left them speechless. Oh, no, one. So, with this sort of model when you like I mean um you know, you don't have like a careful staging when you do something like that. or if that were to happen in there which is causing uh a uh rectification. Um imagine uh there's a incident and uh you have to go in and do the break glass thing. So, the actual

resource uh is now different from what was last deployed. How do you cope with that break? So, obviously the officer is then going to go have back from the development team, say, "How do you make this change so when it's next deployed, matches what we changed?" Is that how it works or how often does it work? Let me give you half an answer and I'll have Will

do the other half. For us, Radius' Radius' biggest value is the fact that it is a translation layer, meaning that for instance, if we're doing Kafka topics, what the implementation, what the recipe is doing is generating a claim for a specific operator, Kubernetes operator, that knows how to do Kafka topics. If we're spinning up a specific database, it's going into that product's operator. We're not doing big,

complex, um, implementations within Radius. We're translation and uh, adding business data like tagging, that sort of thing, you know? Because as you drill deeper and deeper into implementation, you get that pattern more and more. So, probably it's up to the data team to do most of those changes just in this scenario where it's a database, for instance, cuz it's it's closer to the resource and and the

resource manager. But the fact that we're putting these layers on top makes that resource usable for dev. Now, you're aligning life cycles more than anything. And for us, that's cool. But again, have to answer. So, so, uh, agree with everything you said. I'll add on to it that Radius, um, integrates with a lot of other open source projects that will do those things that you mentioned, uh,

much better than Radius ever could, right? So, we integrate with Flux to provide GitOps-style, um, CD kind of, uh, uh, functionality. And then, on the topic of drift detection and reconciliation, Radius doesn't have specific features to do that because Radius leverages other projects that has those features, right? We when you do a deployment using Terraform recipes, for example, we execute those deployments via the Terraform provider. And

the idea is then you can go through your Terraform provider to do things like drift detection and drift consolidation. Um and the uh reconciliation loop. Uh Radius is more of an orchestrator when it comes to uh the deployments. Does that sort of answer your question? Kind of. Imagine not using Terraform. Maybe using a provider as the thing that creates the resources. And for whatever reason, the ops

team changed the database. But then in the next time the development team goes to deploy, when they go to deploy it, yeah. What was previously Mhm. And it can then know or what the ops team did. deployment doesn't match what's now been Yeah, yeah. So, Radius does have a state store tracking kind of the deployments, but we don't actually Radius doesn't have the active kind of reconciliation

loop or drift detection. So, you would have to integrate, you know, another tool to to do that thing that you want to do that drift detection and reconciliation. But in the break glass scenario, though, you could the ops team could go and publish their YAML of those database recipes with the new schema and then all follow the deployment. All right. >> Thank you very much. Thank you.