 This is an interactive workshop. So hopefully you all brought your laptops. If not, you can pair up with somebody else that did. But I'm going to be giving you some instructions on here. And then you'll actually be following them in yourselves so you can see AutodevOps in action. Just a quick rundown on the agenda, we're going to actually jump right into having you clone a project to actually kick off AutodevOps. And then while that's building, because it takes five or 10 minutes to run AutodevOps, then I'll take some time to explain what it is and go into some backstory and things like that. And then at some point, we'll check in on how your pipeline's doing. So just to run through some prerequisites, you do need a laptop, but you can pair up with somebody else if you don't have a laptop. So maybe raise your hand if you need a partner. And anybody who wants to volunteer to work with you, all right, great. Anybody still need a partner? Cool. And then obviously with the laptop, you need internet access. You'll need a gitlab.com login. And you'll need maintainer access, which I think Daniel has already set up for everybody. But there will come a point where if you run into something and it complains about permissions, because maybe you registered at the last minute or you didn't register ahead of time, we might not have given you permission. So just raise your hand. Or actually, there's a Slack channel, WS-autodevOps-101. You could ping Daniel. Don't ping me, because I won't get the ping. Ping Daniel or Joel. And then they can help you. Actually, can you stand at Daniel? Joel, stand up for a moment, just so everybody knows. They're going to be helping you out. If you have any technical problems, whatever, just raise your hand and somebody will come help you. But specifically, we ran into this earlier where we thought developer access was enough, but it turns out you need maintainer access. And then just to let you know ahead of time, we already have created a Kubernetes cluster. And so in this group specifically, so when you create the project, you'll want to create it in the group we've told you to create it in. Otherwise, you won't really get full access to everything. So this is it. Really, this is actually the one slide you need to do. And I think we've pasted the links to this in the Slack channel. That might be easier for you to find, rather than having to type out this URL. But basically, go to the group, which is undergitlab.org. And it's called Contribute Workshops. And then you're going to go create a project under that group. So just follow the instructions there. You'll want to copy and paste that URL for the minimal Ruby app. And so what you're going to do basically is create a project cloning from that other project so that you get, well, it's a really, really trivial Ruby app. You really could start with anything. Use the project templates to create it. But this is just a smaller app that actually will just build faster and deploy a little faster. And then just some reminders. When you do create the project, you're going to need to set the project slug to something unique. And there is a little bit of a gotcha. If you set the project name, but you forget to set the project slug, you might run into a problem, because you're going to try to create a project that somebody else already did. So make sure the slug is unique, not just the name. And then also set your project to public. It doesn't really matter, but it just helps us debug things if you need to. And that's really it. But after you create that project, AutodevOps is enabled, again, for the group. So every project under there will just automatically start building. That's the magic of AutodevOps. But it won't run the first time. So you actually have to do this one step at the bottom, which is to run the pipeline. So just follow the steps there. Go to CICD Pipelines and hit Run Pipeline. Anybody got their project created so far? Well, people good? Is the pipeline kicked off? Good. Good. Just something unique, but yeah, your name would be not first. You can't use spaces in the slug. It shouldn't let you. It should fail on that one. So not just the project name. Project name, you can have spaces. Project slug, you can't. That's the difference. So you can make it look pretty if you want. You can give it a name, but here. And just really quickly, you can make it public. You don't need a description. So you just go New Project. Oh, I didn't actually copy the URL before I did that. It's actually right in the things. You can just copy paste from there. It's in the description of the group. So go to Import Project, Repo by URL, Paste in the URL for the minimal Ruby app. And then go down here to the Project Slug and click on Public. Again, that's not necessary, but you can leave the project name blank. The slug is the one that's important to change. Yeah, so this Git repository URL, that's where you paste it in this minimal Ruby app. So slug is the unique string that will show up in the URL. And it's kind of like you can't have spaces or things like that because it's got to be a URL. Whereas the name, you can make it prettier. You can put capitals and spaces and apostrophes and other kinds of things in there. You don't need it. Obviously, like in this case, I just gave it a slug. I didn't give it a name, and that's totally fine. But if I really wanted to, if I wanted to add a space between Workshop N2, I could do that. But you need to have the slug. And the slug has to be the thing that's unique as well. So you could technically, I guess, have the project name could be nonunique, I think. But the slug has to be unique. So you don't need to configure it. It's already configured. But it doesn't start running right away. So if you made a change, if you pushed up a change or something like that, then it would kick in. But in order to get it to kick off the first time, just go to CI, CD, and Pipelines, and then hit Run Pipeline. And if everything works, this should actually kick off. But if your permissions are wrong, that may actually fail. So quick show of hands. Who's got the first Pipeline running? Cool. That's pretty good. So all right, well, while that's running, so just wanted to talk about what is AutodevOps. As you saw, it fundamentally comes down to, it's a Pipeline. It is a CI, CD Pipeline that we have defined for you. And you notice in the project, there's no GitLab CI YAML file there. The project knows nothing about CI, CD. It's just a little Ruby app. But we know how to build that Ruby app. And we know how to test it and do security analysis, all this other kind of stuff. We know how to do that. And so AutodevOps is basically all these best practices that we want to encourage everybody to have. But we believe is a good baseline for software development. And we put all those best practices into one Pipeline that then is available so that anybody who deploys an app just gets that Pipeline. Now, literally it is still a GitLab CI YAML file, but it's not in your repo. It's in one master place on the server, in this case GitLab.com. And so what we're really doing is just saying we know that that's the YAML file that we're going to run by default. And we'll just automatically run it. So what you get then is if you weren't doing this as a project clone, you would have seen like, oh, I pushed up my first code. And as soon as I pushed it up, it would have just kicked off the Pipeline right away. If you make any edits to the files, it will just kick off a new Pipeline right away. Again, it's CI CD, but with a bunch of best practices built in. So actually, before I jump into a little bit, I want to talk about why we built AutodevOps. And the thing here is we want to make it really, really easy for everybody to do CI CD, but also not to just do sort of the bare minimum CI CD. Like most people, when they create a project, they start with, OK, well, we'll run tests. That's the natural thing for CI. And then that may be they'll even get into CD, but they're not going to do things like code quality analysis and security analysis. And we really believe in the shift left movement. If you look at everything as a Pipeline, we want to take security and things like that were stuck at the end. And we want to move them as far left as possible. And we believe even on your first deploy, you should be checking for the security. So we said, OK, let's put all that in there and make a script that says, this is everything that you should be doing, so let's just do it for you. The history is that, actually, AutodevOps really started as Autodeploy. Our first version of this just did deploys. And in fact, the first version was a deployment onto OpenShift, because it was just a convenient platform at the time. And so it started off with just doing deployments to production and staging on OpenShift. And then as the company evolved to have more and more capabilities around the DevOps lifecycle, we put all those capabilities into AutodevOps. The first versions of AutodevOps only had a couple of jobs. And now there's, I don't know, 12 jobs or something defined. It's a really complicated script, frankly. There's a lot in AutodevOps. I'll just run through them really quickly, and then I'll actually show you in the Pipeline what they look like. But the first thing is building. If you have a Dockerfile in your project, like the example you just cloned, then we'll actually just build the Dockerfile. Yeah, that's a good question. We have thought about it about a year ago or so when we came up with this strategy to go to DevOps. DevSecOps was starting to get popular, but we didn't want to start going. We have this slide, actually, where it was like, DevSecBizDesignOps, because it's like, well, we do all this stuff, and so we just said, look, we're just going to call it DevOps, because DevOps really isn't just dev and ops anyway. It's really everything around software development and operations and delivery and securing and whatever. It's everything that's involved, and so we just like, let's just call it DevOps. The reality is, though, that since then DevSecOps has become much more popular, and security really is kind of a third pillar in our product. It's of equal size, probably, to the dev and the ops portion. So I think some of our marketing campaigns will start talking about DevSecOps more, but I think we're still just keeping the product, the auto DevOps name there. It's just about DevOps, because, again, it is far more than just even DevSec and ops. So anyway, so going back to the builds, if you don't have a Docker file, we will actually detect what language you've got, and we will try to build that, and we'll actually use Heroku build packs to build it, so we can detect, if it's Ruby, we'll try to build it a certain way, if it's Java, we'll build it a different way, and so we'll actually build that up, and then create a Docker image in the end, and then that will be the build part. Then we'll try and test it, and we'll, again, use the Heroku build packs for that. Not all languages are supported for that, but if we do detect it and we can support it, then we'll try to test it automatically. Code quality analysis, we'll just run that again. It'll be based on the open source version of Code Climate, and then we'll display those code quality results right in the merge request, or in the merge request, if you make a change. And then there's a whole bunch of security testing, so static analysis, static application security testing, dependency scanning, license management, container scanning, all those things kick off, again, right from your first deploy, so really taking shift left there, and then auto review apps, which is really awesome stuff, so when you make a new branch, and you push up a change, and you're about to make a merge request or something like that, we'll actually go and automatically deploy your change into another environment, specifically for you to be able to review what that change looks like live. And then once we've got that review app, we can actually run dynamic application security testing on it. So we actually have, I'm not sure which tool it is, but there's an open source tool that will then try to detect problems in your security vulnerabilities in your running application, which is really cool. Then auto deploy, when you merge it back into master, we will automatically deploy that to production, or staging, if that's how you've got it configured, but which I'll get to later how to do that, but by default it deploys to production. And so really you've got, from first push, it just automatically does all this stuff all the way to deployment to production, which is pretty great. Once it's in production, we'll actually then run browser performance testing on it too, which really is just kind of, it simulates a browser hitting your website, hits slash on your application, and then starts recording how long that whole process takes. And then we've got that benchmark, and then if you make another merge request that slows things down a lot, we can actually note how much that slowed things down, or so that you know before you actually deploy, whether you've slowed something down, yep. I don't think so, I think right now we just tell you what the delta is, whether it's faster or slower. We don't have a threshold, there's no alerts by default, I think on performance testing. We don't fail the pipeline, so we'll tell you that it's slower, but we'll still let you go ahead and deploy. Yep. And then auto monitoring is again, whether it's after it's in production, or in review out frankly, we know how it's configured, we know it's on Kubernetes, we know how to instrument that, and we can automatically get things like response times, and error rates, and even like pod CPU usage, and all this kind of great stuff. And so again, all this happens without any configuration whatsoever, and that's really, that's why we put auto in front of all these. It's really almost all the capabilities of our DevOps lifecycle thrown in by default. Yeah, go ahead. I don't think we have that now, but we've definitely talked about having the ability to create an issue from any kind of alert, but like oh, if there's a performance issue, great, let's create an issue and then track that and somebody can triage it or whatever. I don't know when that kind of thing is gonna be coming, but we don't today. Cool. All right, so at this point, it's a good time to check in, how are your applications actually doing? I know I kicked off one a little while ago, and I think my thing finished. So I'm just gonna run through a little bit just to show you what the pipeline looks like. I mean, I talked about all these tasks that auto DevOps does and includes, and this is how it's actually manifest. Again, it's a pipeline. Testing is all done in parallel, because you don't really wanna wait for all the tests to happen sequentially. So the code quality analysis, license management, all these kind of tests happen in parallel, and then all the way through production, deployment, and then, excuse me, testing the performance of it. So hopefully your pipelines look like that, anybody not have a pipeline that looked like that? Uh-oh. Oh, code quality, it's still running. Well, that's one of the reasons we kicked this off a little while ago. Sometimes it can take a while. Not yet. Still code quality, yeah, that can be a little slower. All right, well, so one of the things is, now that we've got this, I can do a couple of things. I can look at the environments. In my case, I jumped ahead and actually created another environment, but just pretend that's not there for a moment. I've got this production environment and you can see that, I actually did this two hours ago when I did the previous workshop, but I can now open this and I can see my running app and it's obviously a pretty trivial app, just says hello world. But we've given it this URL up there, based on zip.io, just to make it easier. But we've all got this, I've got some unique name based on my app in the group that it's in. And so all of our apps who are living on the same servers, they're all just running in their own pods when they're running and you'll all be able to see the hello world running on there. Exactly, so what'll happen is if you use autodevops and you don't have a cluster, you'll get the first half of it, basically. You'll get code quality analysis, you'll get the static analysis testing, you'll get a bunch of those things, but then as soon as you try to deploy, there's nothing, you can't deploy to anything so it won't try to deploy. You'll still get value out of it, it's still pretty cool, right? But obviously in order to get the real value of being able to deploy, you need to have a good, which is why we basically, we all had, we pre-configured the group so that it has a group cluster and so you all have access to that cluster and it just made it a lot easier. You can attach clusters at the project level and so you could have just done that, but I didn't wanna be configuring 30 clusters or whatever it was. Cool. There are a couple of differences though because we chose to do a group cluster, we actually don't get as much capabilities so some of the things are still being forwarded over, the group clusters are a relatively new thing. If this was an individual cluster, then actually I would have been able to see the deploy board here and so now I'm jumping into this has nothing to do with auto DevOps anymore but it really is part of just the whole DevOps lifecycle that when you're deploying to production, let's say, you can actually see boxes showing like, oh, it's deployed halfway and there's still the rest to go and right now there's only one pod so it wouldn't show me very much but you could see it, you could scale that out and there's also monitoring which won't work at the moment so the little graph to see the environments and all the data isn't there but if you configure the cluster at a project level and then install Prometheus on that cluster you'd be able to see that data a little bit more but I skipped through that for the purposes of this workshop. Cool, so to see a little bit more of what auto DevOps looks like so right now this, again, in my case I've already kicked off another merge request if you want to go and make a change to server.ibb it's really the only thing and here you can go in and I'll just actually edit it here that's funny somebody already edited it so here you know whatever I'll just say, so I'll just change the hello world message to something else and put it in target branch which will then also trigger creating a new merge request and you all can do this yourselves if you want to what that does is it'll kick off another pipeline and this one looks a little bit different which is why I wanted to do this whole process it starts off the same it still has to build it and run all the tests but now it's gonna create a review app instead and then it'll do that dynamic security analysis on that review app which is pretty cool and it'll still do performance testing on that review app and then it won't actually run this it'll wait for that to happen later but when the branch is deleted it'll automatically then delete the review app as well which is pretty cool because you don't want to leave the pods lying around so that actually can take quite a while as well so I have, okay so so now in this case I've kicked off another build it's gonna take a little while so right now there's no deployments yet it's gonna, it will take a while so I'm gonna go actually just look at see if I actually did this okay so I ran this one earlier and I had a different merge request which you can see isn't, you know it was a similar trivia little change changed hello world it ran a pipeline and then from here I don't even have to go through to that environments page I can actually just see it right here view app and I can see the app running with the my little change hello workshop so that's, you know it's great because you can look at the code and you can see what the code was and you can review the code but sometimes you don't really know what it's actually gonna look like and so it's really important to be able to see the review app and again you get all this for free I didn't have to configure anything from an app perspective I could have pushed up some Java app and it still would have done this it would have created review apps and you know it would have done automatically best practices built in has everybody been able to see their live app yours finally finished and so can you see your app so if you go into again operations environments probably the best place for you to see it and then from there you should be able to just see the thing running or see the app that is running yeah I think somebody must have changed master after I did this two hours ago so I don't know somebody merged it it's one of the challenges of giving everybody owner credentials cool so that's the basics of it really you know in how long did that take 30 minutes basically in our case took a little longer probably normally it wouldn't take that long frankly to go through but in 30 minutes you pushed up an app or pushed up code rather and we turned it into an app and it deployed to production and you did nothing nothing to configure it at least but there's there are some more things you can do to configure stuff so here's a just link to the documentation for all the different kind of environment variables you can set I'm just highlighting a few of them you can set the number of replicas which is you know could we need to speak for you know the number of instances and so if you set an environment variable called replicas and you set it to three or something like that you'll be able to scale up your instance from just one pod up to three pods you can set that replicas a variable at different levels so I could set it for production and have it be different than for my review apps for example and so you can just use environment specific or yeah environment specific variables to specify that oh for production I want it for three for staging I want it to be two and for everything else it's one that kind of stuff you can also set additional hosts right now like you saw the URL was a pretty ugly URL but if I have DNS configured and I want to have a pretty domain for my production which is probably makes sense you can set up additional hosts and that I think should allow you to have you can access it from either one you can have it from the the ugly URL or the prettier URL by default Postgres has turned on but that can be a waste for an app that doesn't use Postgres so you can disable Postgres maybe you've got a project where the Heroku build packs don't know how to test your project and so that just fails and rather than having to make them a custom pipeline you could just set a variable to test disabled and that'll actually disable the test job in fact almost all the jobs you can disable if for whatever reason you don't want to run any kind of static analysis you don't need to do that or the license check you want to turn that off you can set variables to turn that off there's a bunch of ways you can configure autodevops just by setting environment variables and then that means you don't have to you know you can customize it a little bit really easily but there is another way to customize it which gets a little bit more interesting as we have what we call composable autodevops which is just the template itself can actually be modified pretty easily so I think what I'm going to do is demo this let's see what the best way to do it is from here I think if I go to add a file and I pick the type is Gilem CIML and then I pick autodevops it actually puts in literally this is the autodevops script so it's 93 lines but most of the content is actually hidden behind these includes so it's really easy to be like okay well we've included build we've included test we've included code quality like these are all the jobs and they're defined somewhere else so if you want to turn one of them off you can just delete it if tests well I don't suggest you turn off tests unless it's really failing but you could delete the template for tests and then go and add another job to do tests differently you want to override it you want to run our spec in parallel with 70 pods running simultaneously or something like that you can do that but then you can keep the rest of autodevops all be the same so it's a really great way to start from the autodevops template and then augment it with whatever you need whatever your customizations are you could also go the other way and let's say I've got an existing Gilem CIML and everything's great but I just really want to add security testing well then you could just include the parts that you need you could just take any part all of those if you want and then add them to your other existing Gilem CIML and it's probably worth explaining what this really does these templates this include template you can include other things you can include files that are relative within your repo you can include files that are on other projects you can include lots of things which is a really great way to build up sort of a centralized repository of all your CI CD tools and then different projects can include the things they want but templates are a special case again going back to this list these are all templates and you can basically just include any of these by just using this one line include and so if you I'll just pick one here so for container scanning this is the 62 lines of container scanning that you can just include with one line of Gilem CIML and there's a few other things like code quality like if you just wanted to add code quality to a project and nothing else you could copy this literally or you could just reference the include and we really recommend using the includes because then if we ever change things if we improve how the static analysis job functions then if you just include it you'll always get the latest version whereas if you copied it in then you'd always have it be stale that question so it literally looks for them in the same place that looks for populating this list there's a the GitLab server ships with these templates and it looks in that spot for the templates but then also if you like let's say at a group level you add custom templates then you could refer to them there as well so it's in the place where the templates are which frankly I don't remember offhand where that actually is they used to be different they were rendered differently but they live somewhere else now any other questions? you can there's a couple ways you can do that let's see I'll pull up the documentation here so one of the ways you can do that is by setting the build pack and so there's a couple of days so there's a build pack URL you can specify there's also you can set a file like dot build packs anyway there's documentation on it there you can set this if you need to override the build pack so if the detection is wrong first off you could do that but also just there are thousands of build packs out there and we only use maybe seven by default and so if you've got a custom build pack for some framework that's not really normal or standard or other I should say then you can just point to that build pack instead and then we'll build that way I'll also add though you don't have to use build packs again you can just provide a docker file which is really easy these days to create a docker file and again if we detect a docker file we'll skip the whole language detection thing we'll just run the docker file without a YAML file so basically what we do is the whole thing about autodevops is that if there is no YAML file we will just use the one special YAML file that we've identified which is the autodevops template and so that's the auto part of it basically any other questions? I do depend on external docker images usually especially like the code quality one goes and pulls in a bunch of different images that was one of the things we were talking about in the last workshop where some ways you can cache some of these things but they're all going to be pulled from the jobs well you don't need autodevops to do review apps autodevops just give it to you without you having to configure anything but you could set up any kind of custom pipeline and still just create review apps there's documentation about how to do it technically but however you build and deploy because again autodevops only works with Kubernetes but lots of people deploy elsewhere so yeah you just need to construct your YAML with the review stage with the review stage exactly and basically just define two jobs one that creates the review app and one that destroys the review app and you know you create them in a certain way and all the magic happens Is there a question back there somewhere? Thought it's a hand up All right Sorry? Well autodevops has been around for Yeah well it was in beta in 10 point something and then I think maybe called GA in 11.0 but it was around for several months before then and really quite functional but there were a few things that stopped it from being GA so anyway so it's been around for quite a while but we've also continued to evolve it I don't know when we added browser testing but I don't think that was 11.0 for example and then all the security stuff has been added so it's obviously like everything we iterate it continues to evolve Composable part is very new that's only a couple months old so it used to be that when you included autodevops it was 300 lines of YAML and which was fine but it also meant then that like when the security tests the script itself changed which did happen quite often it meant that anybody who had vended in the template would potentially not get to take advantage of those things so using the includes really really helped and I think it was only maybe within the last six months that includes even came down to core and so it was originally I think a starter feature maybe it was premium but it meant that we couldn't make use of it for something that might be used by core and so but once that was done it took a couple of months and then yeah we made autodevops composable and I think it personally really makes a lot easier to get started and you can see what it looks like and then just make some small changes to override a few things I believe they are the template ones might not be but like if you're pointing to another project I think you can put a ref in there and point to a specific branch or version or something like that I don't remember the specifics like how like if it works everywhere like sometimes you can just put it in a URL and so then you can potentially put the version in the URL but I don't think for templates you can I could be wrong though I don't know if Daniel remembers alright any other questions? alright cool let me see I think where was I back then I don't know that there's anything else yeah that's it really yeah I don't think there's anything else to show except for maybe you know actually making some changes to the autodevops to the template but I think we've covered about how to do it so I think it's enough to get you started if you wanted to start playing with it if you remove them then yeah they just disappear exactly and actually one of the questions somebody had before is like well what if you're not on ultimate then these security tests don't work and I think if I recall correct actually I'll check it right now that like the container scanning actually has this only clause and it will only run if you are licensed to run container scanning which would mean you've got an ultimate license and so if you're on anything other than that then the job just disappears the whole job just doesn't even get instantiated so you would just see a smaller pipeline or well it's a parallel pipeline so you'd see a smaller list which is pretty nice because it doesn't waste your time because what would happen when we first launched autodevops we didn't have that capability and it would mean we'd run the job we'd do the analysis and then we'd generate a file that represents all the results and then there's just nothing you could do with it because the rendering is actually licensed not the running of the job and so it's the display in the merge request of the security analysis that actually shows up like if I go back actually I think I need to look at the merge quest if I look at this merge request you'll see these things there so no changes in code quality performance metrics improved on three points which is kind of interesting that sounds random because that didn't change much security scanning detected no additional vulnerabilities and license management no new licenses like all that stuff it's the display of it that is actually licensed and so there's nothing wrong with running them on core just that you can't see the results yeah like I don't know it just looks like it's not particularly meaningful so that would be like having an actual threshold there would make a lot like three points is probably just not worth that's just variance yeah that is a great question we do not currently have any plans to do so well to be clear so OpenShift we have plans for that but that's Kubernetes underneath so it's not a different platform but it is different enough that we actually have to solve problems differently one of the advantages of doing the composable auto DevOps and we haven't quite hit there yet but is I'd like to be able to sort of decouple the deployment mechanism from the rest of the structure and so if you wanted to override and say I'm going to deploy differently you could potentially just change some different file or even better just include a different version like so instead of including the Kubernetes deployer you include the AWS VM deployer or even the FTP deployer or whatever and you just include a different one and then everything just works we're not there yet and it's not honestly a priority like Kubernetes is the top priority for us and so making that work well is really important but I do expect that it's both possible and that there's some demand for being able to do auto DevOps to other platforms that is a great question I think we need to do some exploratory work to see if it's possible first but if it's possible then yes of course we should be able to document how to do that I'm really curious now that you say that if I look at the auto DevOps script whether it's whether I can just override one thing it wasn't when we made a composable the goal was to still within Kubernetes be able to select different things but maybe another iteration would be then to make that part composable as well and again start with just the default one the auto DevOps script only does Kubernetes but at least hey if you know here's how you would modify it to do something else and I know that my exploration work I did you know geez a year and a half ago or something like that did explore that kind of stuff so I know it's it's conceptually possible but maybe not with the current current limitations yeah right well the if you're using the build packs the pulling the build packs well I think actually we have a Docker image that has already pulled the build packs I don't think that's a problem if you specify a build tag URL then we would obviously be able to well unless you pointed it to an internal representation of it or something like that the code quality wouldn't work that pulls a bunch of Docker images even by default I think we still point to Docker images that might be on gitlab.com so you might still have to mess with that I don't know it's worth looking at because right now there isn't a lot specified but within the jobs there might be you know URLs that are pointing to specific places and I know the security ones obviously are a challenge but I don't know about the rest that's a great question I think I don't know if I can pull up metrics right now that will actually say but Autodev is one of those things where people love the idea and it actually really helps people get sold on the idea behind gitlab and everything else but that doesn't mean that they're actually running the like unmodified autodevopscript but they're still inspired by that and they'll you know use the structure and again it's even easier now with the composability thing I don't know if we have any data of how much people are using the composable version but it's even easier to start with that and then just modify the parts that you need to again including potentially changing how to deploy like in worst case like I said the composable it'd be nice to be able to just change one line but worst case you could still do all the rest and say the part that does the deploy rip that out and then write your own and then there's more writing you have to do but it'd be easy enough to do and then be like okay this is how I do review apps this is how I do production etc anyway so I think you've got a lot of adoption of the principles of autodevops and some parts of it but of just actually using autodevops as the thing without any modifications so that's probably fairly low I think that it's a great way to get started but a lot of people have customizations after that any other questions cool thank you everyone