Overview

About this video

What You'll Learn

  1. Deploy Spin apps as OCI artifacts through Fermyon Wasm Functions registry.
  2. Use the built-in key value store for globally distributed application state.
  3. Manage apps from the extended Spin CLI, including deploy and inspection.

Thorsten Hans walks through Fermyon Wasm Functions, the new fully managed service that runs Spin apps on Akamai's globally distributed network. Covers the aka plugin, deploying via OCI registry, and the built-in key value store.

Transcript

Full transcript

Generated from the English captions. Timestamps jump the player to that moment.

Read the full transcript

0:10 Clouds amaze A tangle thread, servers spin inside your head. But a new dawn breaks, Thorsten ons will show the key to build and run effortlessly. to Going Innovate. Spin it up. The future's bright. Microservices taking flight. Thorsed and hunts, I'll show the key to build and run Hello, and welcome back to the Rawkode Academy. This is Rawkode Live, the show where we take a look at cool open source projects in the cloud native space. Today, we're gonna take a look at Fermion Spin but through a slightly different lens based on some of the announcements they made just last

2:57 week at KubeCon. Guiding us today is Thurston Hands. Welcome back. How are you? Hi, David. Thanks again for having me, and hello, everybody on the stream. Yeah. Always an absolute pleasure. For anyone who hasn't caught us, you know, streaming together before, could you just tell people who you are and what you're up to? Yep. As David already mentioned, my name is Thorsten. I work as a senior cloud advocate with, Fermion, where I mainly, you know, am on streams, write technical docs, blogs, or, help developers taking our products and services and our open source projects to build software,

3:42 for the upcoming future, right, for the next decade, maybe. Yeah. Awesome. Thank you. And, you were at KubeCon last week on the Vermeion booth talking about all the wonderful things that the team have been up to. So I know there's a number of announcements. Do you wanna give us the the quick rundown of what Fermion has been doing in the last couple of months? Yeah. Sure. So, yeah, the both of us, were in, in in London for KubeCon EU. And, yeah, as David mentioned, we we, had a booth there and we introduced, Fermion Wasm functions,

4:23 which is basically a fully managed hosted service that we provide on top of Akamai's global connected network. So we took like over the last couple of months, we we took the way how we run SpinApps in dense and available fashion and put that together with Akamai's globally distributed network and locations that they have around the globe to, you know, basically provide a service where we as developers can just take our spin apps, deploy them there, and we don't have to care about nitty gritty details like selecting a region. Right? So apps are always available and requests

5:15 are routed to the closest data center depending on from where the request is hitting the app, which is basically in a nutshell, what Fermion Wasm functions is and what we were, working on, the last couple of months. Yeah. I think that the understated thing about this, right, is like, you know, anyone who has watched more than one video on this channel knows I love WebAssembly and building applications with this pattern. And I always talk about the performance characteristics of shipping WebAssembly. Right? When we start a container, we're measuring it in hundreds of milliseconds, typically. However, when we're measuring WebAssembly,

5:58 we're measuring in nanoseconds before that thing is actually returning some data back to the user. And, you know, the not the problem with Fairmair Cloud, I don't wanna frame it in that way, but Fairmair on Cloud, I believe was like single region for the entirety of this kind of, you know, cloud life, which means you have to fight the latency. If that user is in Australia, if they're in Asia, if they're in Europe, you don't really know where that server is and you could be measuring it in fifty milliseconds or we could be measuring it in three hundred

6:28 milliseconds, which is not the end of the world, especially when WebAssembly is fast. However, when you partner with Akamai, who probably have one of the biggest networks in the world, we're now getting this double whammy of, well, we're gonna get that first bay or that we're gonna get that latency down to an absolute minimum and then the runtime and the execution of that WebAssembly binary is then equally fast. And then it's like, who doesn't want that? Like, that is just the absolute ideal scenario for anyone that wants to ship and have their users be happy on a

7:00 performance level at least. You know, you still gotta write good code. Right? You know, we can't teach people everything. But when you remove that infrastructure component and that networking component, I mean, that's a win. I I mean, hands down, that is absolute win. I was so thrilled to see this announcement. So Yeah. Yeah. So basically how we phrased it, we, you know, we married the fastest fastest serverless compute with the fastest network available to to provide, like, lowest latency for execution. Right? Of of serverless of serverless workloads here. Yeah. And the cool thing is, for us as developers,

7:39 nothing changes. Right? We can still use Spin to for creating WebAssembly workloads, or you can create them using different tool chains as long as they align with Wazi incoming HTTP handler, for example, right, to build apps and deploy them there. However, as always, we are super keen to deliver a great developer experience and, you know, extended the spin CLI to make it aware of that new Fermian functions service, where you can deploy your apps. You can, you know, inspect all the apps running on your account and, you know, different, like, inner loop concerns are obviously addressed,

8:26 by default. Yeah. Awesome. So do you wanna give us a bit of a rundown on what is you're gonna be walking us through today? I mean, I think we've all got a pretty good idea based on what we're talking about. But, yeah, what are you gonna be showing us how to achieve today? Sure. So can You want me to jump over to the screen share? Yeah. That will be great. Alright. You are now live. Take it away, Thorsten. Okay. Cool. Thank you. So what we're looking at right now is basically the announcement post. I think we can put that link in

9:02 in the show notes later on, which is, you know, giving you an, you know, an overview of what Fermion Wasm function is, what it offers in more detail. Obviously, as always, we try to provide best in class documentation. And if you're familiar with what we do, with Spin and SpinCube, c or the CNCF projects we, contributed. We have obviously reworked our website to make it a little bit, like, clearer where to start. Right? So as a developer, you obviously start with building apps. But at some point in time, you wanna deploy and run them. And there is right now a new section

9:53 over here, fermion WASN functions, which, you know, gives you all like details about how to do x, y, and z within fermion wasn't functions. But also there is the request access button because right now it's in preview and we have to or we let people in once you, you know, request access to the service. So that's a great resource where you can find samples, tutorials, you know, guiding the you as a developer, through the process of building your apps and getting them deployed to Fermion Wasm functions and also some like, let's say, more details about how this works. And I

10:41 think that's a good starting point to to become a little bit more technical. Right? So our service comes with, with its own registry. Right? So as for like more than a year or more than a year, yes. I think we, we stick to OCI artifacts as distributable units for spin ups. So if you build a spin up and you wanna distribute that, you always end up with an OCI artifact that is pushed to some sort of OCI registry. So basically a registry that implements the Docker registry two dot 0 standard. And, yeah, we provide one as part of

11:25 Fermion Wasm functions, which basically receives your workload and ensures that it is deployed across the globe. And as soon as all the regions report back that the app is up and running, We register a sub domain name for you with an HTTPS certificate so that you can immediately invoke or send requests to your workload. Or you can if you use or if you are already using Akamai products, you can integrate them with existing Akamai products. Right? That's possible. So to route through a property, how it is called in Akamai to your fermion wasn't functions. On the back end side,

12:15 nothing changed. Right? So you can still interact with databases, with key value stores. And again, we provide as part of our service offering a globally distributed key value store that you can just use as you're used to use it with, Firming Cloud, for example. Right? So it's really like an an incarnation at the next evolution step on how to run, spin apps on a fully managed platform. Alright. So, what do you need to get started? I think that's always, the most important information for us as developers. So I have installed spin on my oops. Yep. Spin

13:07 dash dash version on my machine in the latest stable release. That's version three dot two dot o. And I have also installed a new plugin that's called AKA. That's basically the plugin, you know, for interacting with Fermian Wasm functions. You you see already like familiar sub commands like apps, manage applications, or to deploy an app, to log in, and so on and so forth. So we will go through that entire workflow, once we have implemented an app that we can deploy to the service. The most important question at this point might be how can I get that ECA plugin?

14:00 And again, the documentation provides a quick start where you can, you know, find information on how to install Spin and how to install the plugin, the ECA plugin that I have already installed on my machine. This is especially handy if you have already spin installed on your machine or if you installed it before we release that plugin. Right. As always, language specific tooling is required. So if you want to write your apps in JavaScript, TypeScript, you need node installed in your machine. If you want to write your apps in Rust, you need Rust installed with the Wasm 32

14:43 WasiP one target. And if you wanna write your apps in Go, then you need TinyGo installed in a recent version. I think I've installed let me check TinyGo version o 36. I think 37 is already out. So that will also work. But keep in mind to also upgrade your templates because there was a rename of the entire Wasm 32 Wasi platforms at the beginning of the year. So for Rust, for example, it's now called Wasi 32 Wasi P one. And for TinyGo there was a change as well. Right. So if you encounter some errors following the guide,

15:32 building the app, it chances are pretty high that there is that you hit exactly that, you know, change from the underlying platform name. But that's all we need. Right? We need on, the spin, installed on on the machine. We need language specific tooling and that Akamai or the Akka plugin. So the service is a multi tenant service, which means we have to authenticate in in some way. Right? And, you know, we use a lot of GitHub, so we have we use GitHub as an authentication provider. So once you have requested access, you know, and the onboarding is completed,

16:18 you can do a spin aka login over here. And that is a regular device code flow over here where I can say, I wanna authenticate with my individual GitHub account and then I have to grant the CLI the permissions to interact with fermion wasn't functions on my behalf. Right? So I can, can I can close that tab right now. And as you can already see, it welcomes me. And now I have access to, you know, my account where I can do things like obviously deploy apps or I can simply say apps list to explore what's already there. And as you

17:07 can see, I played around a bit with Fermin Wasserman's Yeah, you've got a couple. Yeah, and I cleaned up a couple of them already before the stream. So, yeah, you get like, you know, the list of apps deployed to your account. And as as you mentioned, David, the both of us were at KubeCon. So let's take this one for example. You can do a spin archive apps info. I think it was without a dash. Yeah. It was without a dash. And you can see that I deployed. However, never invoke the app. No. I did not invoke it in the

17:46 last seven days. So I deployed an app there that is available at this URL and it basically prints hello world, you know, a quick verification demo. Yeah. So I think the key point is it's a super intuitive, sub command to the SPIN CLI addressing like day to day, concerns. And we will obviously, right now, start building something. And, for those of you were on or joined the last stream where I, ran into some issues with the ET router in in in TypeScript, there are also great news, in regards to the HTTP TypeScript and JavaScript templates.

18:40 Let's say, hello, fermion wasm functions, and let's edit two to be safe. I think I have one already. So we updated JavaScript and TypeScript templates since, David and I were on stream, last time. And the new templates allow you to choose, from different routers because I think, I like Hono pretty, a lot and, I think it's API is super memorable for at least to me. And but maybe you wanna roll without an HTTP router. Right? That's now also possible. So let's I like Hono as well. It's a great little mini framework. And, you're right. The developer experience, the API surface of it

19:33 is is slick. Yeah. It it is it is super great, especially, like, it's middleware APIs. I like them, a lot. And, yeah, stumbled upon it couple of a while ago and yeah. So we updated our templates. So that's, also new. So let's jump right into Hello Fermion Wasm Functions two. Let's open up code and let's increase the font size a bit. Again, nothing, new over here. Right? We have package JSON like a idiomatic an idiomatic JavaScript or TypeScript in that case project. However, right now the dependency added to the project is Hono instead of Ity. But you can choose whatever,

20:24 know, which router you want. So before diving into code, let me do one thing. Let's do a quick spin build because spin build also runs an NPM install if that hasn't been executed in that project to pull down the dependencies and which, you know, is basically, turning on the lights to get IntelliSense and auto completion and stuff like that in in Versus Code. Alright. So the the skeleton that we create when using Hono is giving like, you know, simple guidelines on how you can use capabilities provided by Hono such as the built in logger, a middleware that adds a response header

21:13 and to get routes. Right? So pretty pretty default hello world experience. Let's let's save that as it is and we will, you know, change that and enhance that during the stream. But let's let's let's give it a try. Right? Let's say it's been built. So we updated couple of yeah. I removed couple of comments. So let's build that again. And now that is built, I can do the usual spin up to test it on my local machine. I can curl local host 3,000. I get back Hello Spin and I think if I say Hello no, not greeting me.

21:58 Let's greet David. There you go. You get Hello David. This time that is if we look at the headers, we get JSON back. In contrast, the root route was a plain text response. Okay. So it works on it works on my machine. That's great. We see that we get logs provided by the Hono Logger middleware. Let's take that app and let's deploy to Firmin Wasm functions, which is as easy as doing a spin echo deploy. And right now it's taking, you know, the Wasm file, the spin manifest, creates an OCI artifact, push that to the wasm func fermion wasm

22:42 functions registry. And now it's deploying the application across the globe into all the regions that are part of the service. So we had a question on the chat about that. Sure. Actually, I'm gonna bring it in now. But Paul was asking how many pops are there on this network? How many regions are we deploying to? So there's a difference between, points of presence POPs and, regions. I I'm not hundred percent confident how many regions. Let me quickly look up. Let me quickly look up. So list of countries is pretty damn long. Try to come up with Oh, we have

23:32 over 4,200 edge points of presence on the Akamai connected network. And the service is right now we operate it not in all regions provided by Akamai. So if I remember correctly, we're currently running in six regions as part of the preview. However, we are super happy to stamp out new regions and, you know, grow during the preview period as well. So I think yesterday and the day before we, extended and or we we added two more regions before that we were running on four regions. So that's growing but obviously once we move out or graduate out of

24:21 the current preview phase, we will distribute it across all the date, all the regions that we could deploy to. Awesome. Thank you. Yeah. Great question, Paul. Sorry for not remembering the number from top of my head. But, yeah, it's, more than 4,200 POPs. Okay. So in the meantime, deployment it roughly takes a minute or so to deploy or to ensure that the app is deployed across all the regions. It happens in parallel so we expect like the same you know time frame no matter how many regions participate, or are part of the service offering. And we end up with a

25:10 generated, sub domain under echar.fermion.tech, which you can obviously, you know, put behind your first, or your first line of of defense or your DNS configuration, right, to expose it under your, domain name. So let's curl it. And we get a hello spin. And I think it was hello raw code, let's do that. And there we go. And we get back, the expected result. If we take a look at the headers right now, oops, dash I, we can see that the closest one, for me is the European Central region in, in the Akamai cloud. This is due to the fact that I'm

26:07 based close like 150 kilometers away from Frankfurt. So, yeah. If I would live like couple of kilometers further south, chances would be better to end up in a France region because there I'm so close to, to the France border. But that's like an indicator that you can see, hey, which which region handled that particular request. Can you drop that URL in the the chat for me? I'm I'm just curious. I wanna I wanna see if I'm gonna get EU Central or something else. Sure. Let me copy that. And, there we go. Thank you very much. Did you get it?

26:54 I I got it. Yeah. Okay. Cool. I got Paris. There you go. Paris. Interesting. Well, yeah, I guess that's a good I'm in Scotland. So Oh, okay. That's pretty good. Yeah. I'll take that. There's there's another interesting header added over here. We have that x Envoy upstream service time, which is basically telling you, after entering the network, the Akamai network, how long in milliseconds did it take to process that entire request. And we see four which is that's I executed the request couple of times. It's higher as I expected it and that's due to the fact that the app writes

27:45 to standard out. Right? Which is always an expensive, action. Right? So if you strive for best perf, obviously, Rust is faster or Rust code compiled to WebAssembly. That's the alright. The the the correct explanation is faster than taking JavaScript or TypeScript and compile it onto WebAssembly because the binary does not have to, you know, doesn't have to contain a run time like a JavaScript run time. So there are ways to get even lower like to one millisecond or less. Okay. Now we have that hello world deployed and we can do spin echo logs over here

28:35 to get like the logs that this particular app produces. And the, plugin is smart enough to recognize, hey, you're still in that folder where you created that application. So it can determine the actual name of the application by investigating the local, the current folder. Right? So if I step out of this folder and if I do a spin oops spin echo logs it says hey there is no spin TOML. Right? I can't find I don't know which logs I should present. So I can say, there's Hello KubeCon. Okay. I don't know if that one create logs.

29:16 Fermion wasn't functions two, then I provide the name of the app. Right. And I can, you know, obviously also inspect how an app behaves at run time. If I don't have access to the source code or if I am in a different like corner on my on my hard disk. Cool. So this is like super sample a super simple hello world. But what are like typical use cases. Right. So we we thought about, besides, let's call it line of business applications. So I don't know, crud over a database or, you know, interacting with the key value or loading data from

30:03 a key value store. What are what are typical use cases? And what we created, this is a public repository. And again, I will post the link to or will send the link to you, David. This one where, everyone could explore couple of samples that we created as part of tutorials or just that we think are super valuable for you know doing computation close to the user instead of, you know, routing the request around the globe to a data center that is has been selected. So there are a couple of AB testing scenarios, traffic filtering, blocking

30:50 requests based on users country and and stuff like that. Right? Response header modification, gated gated access, so a limit access, that's that's also pretty interesting. So imagine you have like, you you are you have no embargo. Right? And you wanna do a a hard launch launch at at at a particular time, then you can easily because that execution is so fast, right, you can just say, hey, up until eleven, 11:59, fifty nine AM, return a 04:04 and starting at noon just open the gate and let people in. Right? So there are interesting scenarios that you could

31:41 could achieve with running closer to user when you could place computation, yeah, with low latency instead of, the the regular way to the data center. Yeah. And I thought it would be great to take one of the examples and implement it from scratch. So I would say like a simple AB testing scenario, to return different content, based on a key value store. So obviously, and I think this is super important for like enterprise scenarios or like, you know, extending existing, software products. You can provide your own key value store. Right? That could be in your cloud of

32:34 choice. That could be, I don't know, a hosted one that you expose through your private network. Whatever. Right? You can provide your own, but we also provide a globally distributed key value store as part of the service offering. And that's what I will use for demonstration purposes right now. Okay. We start again with, or let's let's check what we have over here. Good. So let's do a spin a new t http t s again and I think after that one we will do a simple rust to illustrate that every language works. But let's say this is the AB

33:16 key value, AB testing sample. Let's go that way. Okay. We wanna respond to everything and I like Hono, so let's stick with Hono. And let's do a spin build again to ensure all the dependencies are installed. Can I ask some questions just about Sure? The setup right now? So, you know, this is the second time we spun up a a TypeScript thing. And I think, you know, anyone following along at home that wants to do this too. What they're gonna see is one, NPM is you and node are used by default and webpack is used as a bundle. So

33:52 as someone who writes a lot of TypeScript myself, there's obviously a lot of momentum now to alternative run times. I'm talking about Dino and Bunn, as well as almost mass migration away from webpack to things like ES build. So my curiosity is like, okay, do I have the options to use BUN or Deno instead? Can I replace Webpack? And if I can, is this as simple as me creating a new template and submitting a PR? Like, how does this all work under the hood? That's a that's a pretty good question. So let's take that question and go to the Spin.

34:30 Js SDK. So, obviously, the JS SDK as all the all the spin repositories has been moved from the Fermion organization to the spin framework organization on GitHub as part of Spin being accepted as a CNCF sandbox project. So that's why there is a different URL. And there is the Spin, JS SDK. So there are templates that, you know, are provided that you can install on your machine. Obviously, you can roll your own templates. So if we sneak into pull requests, there is ad support for Yarn, which we postponed a bit because, we brought in Hono and we did some

35:23 major refactorings about modules modularization that I that I will explain in a second. But in regards to, the build tool chain and package managers, there is obviously a way to, you know, customize what happens. A spin template, let me let me zoom in a bit, always consists of two things. You have that metadata file that describes what this template is all about, That could have like parameters. Right? So HTTP router being the new one over here. And we have there are two ways how you can create a new component in Spin. One is that spin new that

36:13 I did like two times right now. I choose a template and then basically everything from the content folder over here will be dumped to your desired folder. Right? With some, you know, replacement happening in in template files and so and so on and so forth. However, there's a second way. You can always add an additional component to an existing spin app. And that's, you know, I think it's valuable to understand that that's why there is a dedicated component TXT, over here that will be merged into your existing spin.toml. And if we look into the package JSON,

36:54 you can see there's right now npm npx webpack being executed before j two wasm is basically responsible for taking the JavaScript source code that Webpack created with our templates and, you know, turning that into into WebAssembly. So obviously you could like submit a PR, replace Webpack with ES build. Definitely possible. Right? Regarding the runtime, so the JavaScript, SDK for Spin and the underlying tools, the build tools, so Spin framework build tools, they're responsible for turning your JavaScript source code into WebAssembly. And as part of that, a runtime must be shipped or must be compiled to WebAssembly as

37:50 well. And we are currently using Starling Monkey, which is a bytecode alliance project that is, you know, the runtime. I I think it roots from SpiderMonkey the runtime the from from Firefox. Right? It in addition to other runtimes, is it implements all the service worker specs and so on and so forth so that, you know, regular like fetch APIs work as you would expect them to work. Swapping out that one is also possible, right, as long as the desired runtime could be turned into Wazi or WASM Wazi P two compliant, component or in a WASM WebAssembly component.

38:48 Yeah. So I don't know if Deno or Bunn could be turned I I haven't looked into that, to be honest. Deno can certainly run and import Wasm? But I I I don't think moving away from Starland Monkey is a good idea. I think that that is the right move. I I think looking now that I understand how this is built under the hood, if you go back to your template one. Right? Yeah. Really, I just need to update the build steps in my package JSON. Like, webpack, I'm pretty sure I can remove. Even Dino has

39:18 a bundle command, which will give me a bundle dot j s. So Mhmm. Then I could just run the j to BASM and hopefully, would work. What is the responsibility then? Sorry. I know we're getting into the weeds of it now. What is the responsibility of the build tools package? What is that doing? So that's a good question. Top of my head, we have to look into that. Let me Yeah. Go take a look. Spin framework. Come on. So the build tools, I expect them to be good. No, maybe it's Maybe it's on the JS

39:59 SDK. Yeah, maybe it's a yeah, that was wrong. Maybe it's a package being packages. So the, yeah, there it is. Oh yeah, it's basically wrapping componentized JS and yeah. Oh, so wrapping up with them. Yeah, it was basically me catching up with like recent modifications right now, a talk. So over the past couple of months, there was a lot of there were a lot of improvements to the JavaScript SDK and the JavaScript, templates, that happened. Right? So our intention was to make spin projects with TypeScript and JavaScript more and more idiomatic. Right? Couple of weeks ago you ended up

40:55 with a folder, a nitwit configuration file that deploy that defines which which which as web assembly interface types words must be imported by your component and what's exported. Right? And although that is super useful at to some degree if you wanna you know become or implement more advanced capabilities or to to compose complex systems for multiple components. Things like that become super important and and and you know you wanna tailor that maybe at some point. But for the majority of workloads where you wanna, you know, create an API or interact with as we are going to

41:43 do with key value store, you we wanted to have the, project as clean and simple as possible. So we try we try to, you know, pack more and more into like dependencies that we add to the project instead of, having you to maintain or to track that in your source in your source control. Yep. Alright. So, once we are here, we also started modularizing the, Spin SDK for JavaScript so that you can now precisely pick and choose different capabilities when building Spin apps. And which is basically what we will do in a second. So we created an app right over here,

42:42 the AB testing sample app. We build it. So we downloaded and the dependencies and we turned it into a web assembly module. You know, that was just me to ensure my Versus Code is happy and I get, you know, IntelliSense and stuff like that. So the idea is to implement an AB, an AB testing and based on key value store. So what I have to do right now is I do a NPM install at spin framework forward slash spin dash k v, which, you know, adds that as a dependency to my application. And from now on,

43:27 I can use the spin, APIs as, you know, as I'm used to use them. So I can say, over here import k star as k v from add spin framework. There we go. And now I could start using them. So we'll do that in a second, but first let me do some housekeeping over here. Alright. So we still have the the logger. Yeah. Let's let's have logger. Let's stick with them and, we wanna basically expose a get endpoint at root route, which gets the context from Honu. And over here, we will do the following. So

44:25 let's say every even request should return something different from every odd request. That's the overall idea of that sample. Right? And to do that we track like every invocation of that of that application. So we can use whole new middleware middleware for that. So that's async. And again, we get the context and we get next. Alright. So this is basically allows us to run code before the actual handler handler and then we say await, next. And then we can run code after the actual handler. And that that's what I meant at the beginning of the stream with I really

45:26 like their, their middleware syntax and the way of how to structure your app. It it reminds me a little bit to, you know, like aspect oriented programming where you can take an existing application and enhance, your handlers or enhance your app before the actual handler or before the handlers and after the handlers. I like that approach, really much. And I mean, a great use case here is, like, making sure you respond to your users or customers as quickly as possible. And then anything that can happen after the fact, you know, I'm thinking analytics or event processing

46:04 and stuff, you just do that after. And then it doesn't affect that response latency. Right. Right. There's so there are numerous numerous use cases where this is super handy, right, where you can send a response and keep on computing to finalize or to, you know, whatever. Take your bucket of data that you collected throughout the request but then push it to whatever back end you you have to push it to but already present the answer to the user. And and we lose slightly, something something something similar to that. Right. So the idea the idea is to have a

46:42 counter. Right. So let's say interface counter, which has a count, that's obviously a number And we wanna store and retrieve that from the key. So I like to get rid of magic strings. So let's say hits is a constant, that's our key, that we will use. And let me push the code a little bit to the upper. So key value as always in in spin, we have the concept of a store. So k v, you can see you can open a named store or you can open the default store which is the store with the name

47:25 default. So let's open the default store over here and let's initialize the counter for now. Counter equals count is zero as count as counter. As as soon as the microphone is above my keyboard, it feels wrong. Right? It Yeah. Every time there's a camera in my face, my typing goes to absolute crap. It's just it's a rule. Right? That's it. That's how it works. That yeah. That is how it is. That's true. Okay. So we initialized that counter with zero because it could be the case that my app has never been invoked. Right? And I wanna use that value from

48:12 at that point. So let's say store, if a value at key exists, then we obviously wanna take that value instead. So we can say get JSON over here, at position key and cast that inch to into a counter again. So this is basically if, you know, no one execute or hit send a request to our app, we start with the count of zero. Otherwise, we just take it from the key value store and use whatever is stored in key value store. And now we can easily pass that, you know, count to, the handler before invoking it by saying, hey

49:05 context, please set a value called cup called count to counter dot count. Okay. Then we invoke our handler. So let's implement that and that's that's pretty straight forward. Right. We again have to load the count, so we can say count count equals number. So we parse whatever we get, to a number because this API returns an any, add position, count. Okay. Let's get rid of that one as well. Const context. Oh, that's rust. Context key equals, and let's say count, and let's use single quotes over there as well. So let's use that as the value and then we can grab that

50:08 from here and get rid of the magic string. Okay. So we have the count right now as a number and then we can easily say, let's roll with if count, if count, modulo two equals null, then we wanna return, let's say return c dot HTML, h one. Let's say even and otherwise let's return over here. Right. Just a simple example. So we have successfully read the value from key value store. We have implemented like the AB testing algorithm, super fancy, right now. So what's missing? Obviously, we somehow have to store the value. And this is what we wanna do after

51:05 the invocation. But we can't simply, you know, set it as it is. We have to increment it. So we say counter dot count plus, equals counter dot count plus one. Obviously we can also use the shortcut there. But ultimately we call store set JSON and we set at position key, we set counter. Okay. So that's basically the implementation of our app that we now wanna deploy to Fermi and Watson functions. However, there's one thing, one important thing missing. As always, WebAssembly has that deny by default security mechanisms. So we can't make use of, external resources

51:58 without specifying that and a key value store is no exception here. So that happens in the spin manifest where I can say, hey, my AB testing sample component should or requires a key value store. So you could request multiple and as I use that open default method, right, that's just syntactic sugar that executes open default. Right. So that's why I have to explicitly provide or ask to make use of a key value store called default. Okay. I think that's ready for testing or compiling first and then testing. Right. So it's been built. It recognized. Okay. There was some

52:59 code change. So there we go. App built successfully and spin up again. Now I can see, okay, you requested the default key value store. In the case of doing a simple spin up, spin will take care of creating a SQL like database for you that acts as a key value store on your local machine. So let's do our curl local host 3,000 and we get even and we get odd and we get even and we get odd and we get even and we get odd and so on and so forth. Right? So simple key value based AB testing.

53:46 So now let's take this one and throw it over the wall to fermin walls and functions. And that's again as you see us doing a spin aka deploy. And the same thing we saw earlier, right? Packaging the app, distributing it, and making it available across the globe. Are there questions that we can take in those 60 I mean, I have one. Sure. Go ahead. Now that, you know, we've got these WebAssembly functions on the Akamai network. Right? We've already discussed the matters of that and the fact that it is one of the biggest networks in the world and you're adding new regions.

54:29 Right? So as the Akamai CDN in front of this, and I'm asking that because I'm curious. If I return a cache control header on some of these functions, will the CDN cache that for subsequent requests? That's a pretty good question. And I think we were already at this one. Right? I shall brought that. Right? It's not there, right? Yeah, there we go. Right? So we can obviously integrate with the CDN which sits in front. Alright, so can we add a cache control header to the endpoint then? Sure. Let's try. I know this is gonna then add another

55:13 sixty seconds and I'll have to think of another question. But let's try it. Oops. Even. Yep. Odd. Even. Odd. Even. Odd. Even. Odd. So let's break that then with cache control. Let's break it by adding cache control header. Okay. Let me let me do one thing. Let's let me quickly curl no. Not curling that one. Let me curl this one, with dash I. So these are the default headers. Okay. Obviously, we have more latency because we right now talk to that this to add to that key value store right, but yeah let's go to, this one

56:00 and let's easily, we can do that over here See dot header, that is is that property. Okay. So we can nope. I think we can simply set that. Yep. And what do you want? Do you want it needs to be cache dash control. Cache control. Okay. You'd have to set max dash age equals ten for ten seconds. Ten equals get it. Oh, yeah. Sorry. Sure. Yeah. Makes sense. Yeah. So that should set. Remember that's response for twenty seconds. Okay. So let's do that. Oops. Like this. Okay. Cool. So let's do spin our card. Do you have to build it first? Spin

56:53 build. Good catch. But I think you can easily also use the DashBash build, the same experience as you have for spin up or spin deploy. Right? So Okay. That deploys. I've got more questions for you. Sure. So these examples are great. Right? They're really revealing how the Akamai integration works and the cool things we can do and the whole new stuff. The whole new stuff is great. Like, that is now my default for all typescript. I was never a big fan of it. I like clonal. Now what if I need some credentials and configuration passed into my application? What if

57:42 I want an endpoint for, like, an s three bucket and I also wanna pass in the access and secret key as secrets? What is the flow to do that? Good question. Good question. So as obviously there are sensitive and non sensitive configuration data that you want to use within your application. And you can specify them as part of, executing SpinAccordeploy. So there are flags where you can specify your configuration values and that's and the important thing is the, value or the configuration values are tied to that particular deployment. Right? Because right now I'm issuing the second

58:27 deployment of that app. Right? And it could be the case that I introduced variables with that update right now that haven't hasn't haven't been there before. So I think that's something if you start adding variables to your spin app and you wanna do spin aka deploy variable. You see, there are some, I hope not that sensitive. No, not non sensitive variables that I specified over here. On the service level, obviously, everything is encrypted. All the variables are encrypted and only exposed to that particular deployment or version of your app on your account. Does that mean every version or every deploy

59:23 gets its own unique URL? No. It does not. We are currently operating in latest is available at. It's always, you know, like, this one is always pointing to the latest version. Okay. Gotcha. Okay. So let's try if we broke our AP testing on purpose. So we get even. We get even. We get even. We get even. Can you add a dash I to that? We should be able to see the cache Sure. Off as well. Right? Yeah. There we go. Fine. The the funny thing is, you know, that I bet the first request after cache expiration

1:00:08 will also be even because the value is now even in in key value store. Well, it looks like the value should change. Yeah. There we go. Yeah. There we go. That's awesome. Yeah. I I didn't know if that was gonna work, but having the Akamai CDN sit in front of all, that's that's super cool. I love that. Yeah. Yeah. Okay. So we have that. We already explored logs. Right? So that was a spin, aka logs. Right? Sure. That should work. If the app write logs, and I Mhmm. Yep. Some logs. Yeah. Only two requests, which is exactly what I

1:00:43 would expect with the cache control. So, yeah. Lovely. Yeah. Okay. On top of that, we are obviously, you know, adding more and more capabilities to the Spin AKA or to to Firm and Wasm functions and to the AKA plugin that we provide. You can generate tokens in order to do CI CD workflows where it deploys straight from get up actions to gear account on Mhmm. Fermion WASM functions. I think that's, so let me quickly give, folks an overview of what you can expect there, right. You can create, delete list and regenerate personal access tokens. What do you expect from,

1:01:27 you know, to to basically do continuous deployment? Can I ask you another question? Is that okay? Sure. Alright. Don't mean to cut you off. All this stuff is what I would expect to work with the Spin cloud plugin. Right? Like, there's a lot of overlap here between the ACA and the cloud. So my curiosity is, one, if I log in if you log in to Fairmion Cloud, will you see your ACA functions next to your normal functions? And secondly, do we get all the same features we had with Fairmion Cloud? Can I do a custom domain on a Akamai deployment?

1:02:01 So both are great questions. So a, to answer the first one, if you log into cloud.fermion.com, you won't see, your workloads deployed to Fermion WASM functions. We're still in in preview. Maybe there maybe there will be a new UI. I don't know. I don't know yet, to be honest. I don't know yet. So know that you can't explore like the Fermin Wasm functions from within Fermin Cloud because those are two two separate like platforms. The way how the entire like, you know, building blocks of that service are different as they are on on on Fermion Cloud.

1:02:50 And, the other question was, if you, you know, what's the feature compare comparison or comparative to to Firming Cloud, especially regarding, custom domains. For example, our intention is as we run on top of Akamai to integrate with Akamai's services. And in Akamai there's a service called properties, which basically allows you to bring your own domain, maybe use Acme or let's encrypt to acquire an SSL certificate, bring your own SSL certificate, configure your either simple or really sophisticated routing rules, and then, you know, route to the fermion wasn't functions. So that's how it is today. That's how we designed that service to

1:03:50 integrate seamlessly with what's in front of in front of our service in Akamai. And yes, so slightly different as you may already know from or as the experience is with Fermi Cloud. Right. But as you said, this is in preview. There's still a lot of things to come down the road. So, yeah, it's very exciting to see where we are at the moment. Yeah. Yeah. And one part of that preview is, we have unstable cron jobs. So, this is under active, development. Right? Because, I mean, building real world application HTTP is could be like a great entry point

1:04:35 to trigger a function. But also, I mean, maybe you wanna run something on a schedule. Right? So And build my own status page, my own health checks. For example, yes. So we try to, you know, always iterate super fast and, you know, keep it simple yet maintain like the DX that we know. So creating creating a cron job is as easy as saying cron. Oh, there was one create and let's say root route cron, let's give it a name, root. So every second minute send a request to the root route at forward slash and cron dash root is just the name

1:05:22 for my cron job so that I can I can inspect or I can see it when I do a cron list? And right now the service will simply invoke that route every second minute. Right. So that's how it is today. We are obviously, you know, iterating over there and you know, adding more and more capabilities to to features like for example, Cron to make it like full fledged and, you know, bring more and more capabilities there. Awesome. Okay. So this is cron we have deployed. Oh, we can do a spin aker app apps info. Let's do that.

1:06:14 So we saw, yeah, fundamental metrics. Again, yeah, this is part of now trying to give the developers some insights about how the app behaves at runtime. That could be logs, that could be metrics. Right? So basically laying the foundation. Cool. There's one more thing. The nice part, one of the nice parts of WebAssembly is its portability, right? So, we, although we extended SpinCLI by adding that, ECA plug in and, you know, creating the service, so the the the cloud side of things, we did not change anything to the SpinApps. So SpinApps remain like a WebAssembly component

1:07:08 that exports a given capability, that imports given capabilities from the underlying run time, which means we still can do things like taking the same spin app and say spin registry push and call that AB testing for one hour. So TTLSH is like a femoral We can browse the website in the meantime while it's pushing. TTLSH is an anonymous and ephemeral docker image registry where you can store your OCI artifacts. And basically the TTL is defined by the tag that you provide when pushing your artifact. So everyone could right now, you know, take the AB testing app in the next,

1:07:58 fifty nine minutes and couple of seconds and run that on maybe it's all machine, using the dash dash from, Yeah. AB testing one h. Oh, think it no. It's not from. It's spin up dash dash from. There we go. Right. So that pulls the OCI artifact and you can do that on your machine right now and you will end up with the same app running on your machine. So we have the app running on for a minwasm functions. We can run it locally using spin up. But we can also go ahead and simply deploy to Kubernetes.

1:08:45 So I have a Kubernetes cluster over here. Let's say k get n s for example, that's thirty five days old. Which one is it? Yeah. It's an AKS cluster with SpinCube running on top of it. So that is SpinCube.def. Right? That's also it's a sub project of spin, which means this is also CNCF, also a part of the CNCF sandbox project, which allows you to run your serverless workloads on your Kubernetes cluster right besides your containerized workloads. So you can, right now, simply do a spin cube scaffold, scaffold from point to the however I called it AB testing for one hour.

1:09:41 Point to the OCI artifact. Right. And without further ado it's just printing it to standard out so we can tailor this. We can for example say replicas. I want to start with 10 replicas. I want to integrate HPA. I want to integrate KEDA. If you have KEDA deployed to your cluster to scale horizontally based on how I call it contextual load. Right? But we we could simply say, hey deploy this using kubectl apply and take STD in. So we pipe the manifest to standard in of the following command, which is kubectl apply. And basically in our Kubernetes cluster, we now

1:10:32 get a spin app AB testing. Let's do a wide. This is the new one which is pulling the image, so let's kill the old one. K delete spin app AB spin. So let's k get spin app. So there is an executor, there is an operator deployed to the Kubernetes cluster that watches exactly that CRD. I deployed one and then the operator goes, moves on and creates a deployment for you. Right. I specified replica or I removed the replica. No, I specified replica as one. Right. That's why we see desired one, ready one right now. So we see also a pod,

1:11:22 however, the pod does not consist of containers instead that's just a sub process or process on the underlying node. Right? So there's no container involved here. And also the operator creates a service for you allowing you to route requests to your spin apps. And if you scale out, you know, the Kubernetes service does it's thing to a router request to one of the replicas. So we can do kubectl or no, let's say k port forward forward to the service or we could immediately directly point to port as well. So AB testing, let's say localhost 8,080

1:12:10 to port 80 of that port. And now we can call curl 8,080. And we have the same app without recompilation, without anything running on an AKS cluster right now. And to be honest, I can't remember which architecture it was using. So let's check. Oh, I don't know if you see the architecture there. No. Let's do a KDescribe node. And I guess we can see AMD sixty four is it for here. However, it doesn't matter. It could be an ARM 64, right? If you wanna lower your cloud spendings, maybe it's smarter to roll with an ARM 64 instead of AMD sixty four.

1:13:05 And the fact that we use WebAssembly means we don't have to do multi arc builds, we don't have to cross compile things, we can just take the same workload and run it on different operating systems on different architectures. Alright. One more question for you then. Sure. That OCIR effect that you have pushed our registry, if I have configuration which may be sensitive, is it inside of that OCIR effect? Is that something people should be aware of not to push to public registries if there are sensitive information? That's a good that's a good question. So if we go into the source code of

1:13:48 our app, So what how how do you provide configuration data? It does not matter sensitive or not in the first place to your spin app is you specify a variables block over here where you can say for example, log level default equals debug something like that. Right? Then you so once you have defined a variable that allows the run time to pick up for example an environment variable to read that value. However you have to explicitly give your component access to that variable testing sample dot variables. Right? And then you can say, hey, take this from the application

1:14:46 variables. Right. So simple interpolation syntax over here. So now let's say you wanna have connection string over there. Obviously you could specify it over here but then it would be part of the OCR artifact. So there is and now I hope it is secure secure true and we can test if that's the right one. Okay. Let's say that. Right. And being able to use interpolation syntax over here allows you to do things like for example, Redis something like that. Right? If you want to combine multiple application variables into a single value. So I think it is either secure or sensitive.

1:15:49 Let's try spin up. I don't have to build. Okay, it's secret. Secret. There we go. Yeah. This is Okay. Then secret. Okay. So if you push your app to Kubernetes or if you push your app to as an OCR artifact somewhere. Right. Obviously, the default values specified or hard coded over here are part of that one layer in that OCR artifact. The other values are read when the application is bootstrap. Right? And that means we have to load them from somewhere. And from somewhere could be a Kubernetes config map, a Kubernetes secret. It could be

1:16:34 a HashiCorp Vault instance and so on and so forth. So there are different like configuration data providers supported by SPIN that you can integrate to load those values instead of hard coding them as I did with the lock level which I could overwrite obviously. Or you know to you know bring the connection string maybe from a HashiCorp Vault which is like a way more realistic data storage for sensitive data than an environment variable or a ConfigMap. Yeah. Nice. So that's the way how you could prevent yourself from leaking sensitive information in the first place. But still, I mean, even if your workload

1:17:27 does not require a sensitive configuration data, it's still it is still your IP. Right? So you obviously can use things like spin OCI login or spin registry isn't they're an alias, right, for registry. OCI is an alias for the registry command and there is an login command that you can use to authenticate against your protected OCR registry before pushing there. Awesome. Love it. Alright. Anything else you want to show us or can I move us back over to big face mode? Let's move back to the face mode. Alright. That was that was awesome. Such a

1:18:21 good demo. Thank you for, you know, taking almost ninety minutes out of your day to set and guide us through that. I love the trajectory of where Vermeion and Spin are going, being able to deploy this to the Akamai network. I think it's an absolute game changer for people that need to write performing applications for our customers and users around the world. And I'm very excited to ship some of my own stuff this way as well. I've got a lot on my to do list now. Awesome. Yeah. From my point of view, thanks again for

1:18:50 having me here at Rawkode. It was an absolute blast to present and, you know, talk about Fermin Walls and Functions. And, yeah, as I as I said at the beginning, it is public it is a preview and we if you wanna play explore it, you wanna run something there, just sign up to get access. We are happy to let people in and we are listening for feedback. So there is a feedback command in the CLI. Just let us know what you think about Alright. Well, thank you for your time. To everyone that watched, enjoy it, and thank you for

1:19:33 watching, and we'll see you all next time. Have a great day. Thank you. Bye bye. Rawkode Hit subscribe so you won't miss a beat. More livestream tutorials can't be beat. Keep coding, keep learning. It's the Rawkode way. We'll catch you next time.

Technologies featured

Meet the Cast

Weekly Cloud Native insights

Stay ahead in cloud native

Tutorials, deep dives, and curated events. No fluff.

Comments, transcript, and resources

More from Rawkode Live

View all 173 episodes
Spin

More about Spin

View all 20 videos

More about WebAssembly & WASI

View all 17 videos