Code Your Own Heroku Clone with Python – Provision Infrastructure Programmatically Tutorial
"WEBVTTKind: captionsLanguage: enHi, I'm Beau Carnes with Free Code Camp. In this course, I will teach you how to create a very simplified Heroku clone. This course is really all about how to provision infrastructure programmatically. Heroku is a platform as a service that allows developers to build, run and operate applications entirely in the cloud. Heroku makes it easy to do things such as deploy virtual machines, to host applications. And to deploy websites into the cloud. Some of the things that Heroku offers can actually be done pretty easily with other tools. In this course, I will teach you how to develop a simple web app that will allow users to provision virtual machines, and deploy static web apps, all at the click of a button, and hosted on Amazon Web Services. So this is what the Heroku clone is going to look like. Like I mentioned, it's very simplified, it just has two options to deploy your own static website, or set up a virtual machine for development and testing. So let me just show you what this looks like. So you go here, and it's going to show a list of the sites, these are ones that have already been created, we can also create a new site where you can put in the name, and then you can put in a URL where it will get that HTML code right from that URL, or you can type in your own HTML. And then when you click Create, it will create that site will deploy right to AWS. And then I'll tell you about what some of these like the viewing console. I'll tell you about that later in the actual course. But and then clicking the links here will actually open up the sites. Again, you'll see that more in the actual course, let me just show you what it looks like when you create the virtual machine. So here, we can create a virtual machine. And then you can choose the instance type. And with the virtual machine, you're always gonna have a public key. This is a way that it can be authenticated. After you after the virtual machine has deployed the AWS, we can SSH into that, but we need to authenticate it with our private key. So those are all the features you're going to be able to deploy and destroy, delete these things right from AWS. So right from this web interface, we'll be able to create the virtual machine on the site. And also we can delete the virtual machines and the websites, all from our web interface. We don't even have to log into AWS to do any of that stuff. And then also, I'll show you how to make a JavaScript version of one section of this. At the very end of the course. Provisioning infrastructure is related to platform engineering. A platform engineering team serves an organization by planning, designing and managing its cloud platforms. And often this can be done programmatically. The tools I teach in this course can be used for much more than just provisioning VMs and deploying websites, they can be used for platform engineering to make it simpler to manage cloud platforms. This course focuses on the automation API from plumie plumy provide a Free Code Camp grant that made this course possible. pulumi is open source infrastructure as code SDK allows you to create, deploy and manage infrastructure on any cloud using a variety of programming languages. Their automation API makes it possible to provision infrastructure programmatically using the plumie engine. Basically, it makes it simple to write a program that automatically creates VMs, databases, V PCs, static websites, and more on a variety of different cloud platforms. I'm going to show you how to create our Heroku clone a web app using flask and Python on the back end. However, you don't already have to know how to use flask and Python to follow along. Also, everything I show you could also be done with many other different frameworks and programming languages. And many of the steps are the same. No matter what web framework you use, our app will provision resources on AWS. But Paluma makes it simple to provision resources on most of the major cloud providers. And it wouldn't take that much updating to the code to use a different provider. Thanks to Kamal Ali who created the code that my code and this course is based off of. So let's start making the application. By the way at the end, I'll also show you how to use the automation API to provision infrastructure using JavaScript. So you can see how it's different between JavaScript and Python and also see how it's very similar. So let's start setting everything up. I've already created a directory on my computer called Heroku pool, which is where we're going to be creating the project. We first need to make sure that we have the plumie CLI installed. The way to install is different depending on your operating system. If you have Mac OS, you can just do brew install pulumi. And if you have Windows you can do Chaco install Pulu me. Both those assume that you either have homebrew or chocolaty installed, check the link in the description for other ways of installing pulumi. Now, this project also uses AWS, so you'll have to make sure you have an AWS account, and you have the CLI set up and authenticated, you can sign up for a free AWS account at the link in I have a link in the description that will show you how to sign up for a free AWS account. And then there's another link that shows you how to install the AWS CLI, it's going to be different depending on your operating system. Once you have the AWS CLI installed, you can configure it by just doing AWS Configure. And then the first thing you're going to have to do is put in your AWS access key. Again, I'm going to put a link in the description to how you do that, because Amazon has some very specific instructions on how to get an AWS access key. But once you have the access key, you can enter it, you can enter the secret access key. And then you can choose your default Region Name, I'm just going to keep it as the default here, which is AWS, the US reason to default output format, you may just want to keep all those the same. And after that's configured, it's time to set up the plumie project. A plumie project is just a directory with some files in it, it's possible for you to create a new one by hand, or you can use the plumie new command. So that's what we're going to do to pulumi. New, this is using the plumie CLI. Okay, it says please choose a template or mine does. If this is the first time you've used pulumi, you'll be directed to enter an access code or login. So it's gonna give you a URL to go to. And you may have to make a plumie account. But once you enter the access code, you'll see this where it says please choose a template. So we're going to choose AWS Python, we're going to be creating a Python app that hosts resources on AWS. And then we can choose things like the project name, we do Heroku cool. Okay, looks like it doesn't exist, because I've already it's associated with my plumy account. And I've already created a project with that name for a test. So I'm going to create a another route, I'm going to just call it something else, even though we know that it's supposed to be called Hero. Cool. So how about a row cool, too. Oh, okay. And then you can just pick the defaults for this stack, we're gonna keep the default, it's going to initialize into a new stack called Dev, which is an instance of our project, every plumie program is deployed to a stack, a stack is an isolated, independently configurable instance of a plumie. Program. Stacks are commonly used to denote different phases of development. In this case, we're using Dev, so I'm just going to use that. And then we can choose the AWS region to to deploy to now keep in mind, this is actually different than the default we set before. And this is the one that's actually going to be used US East one. And now you can see it's creating the virtual environment. Okay, install the bunch of libraries we're going to need into our virtual environment. But we're going to need a few more. So I'm going to do so first I'll just list here, you can see we created the plumie dot Yamo file that's used to configure everything, the main.py file, which is where our main Python code is going to go. The requirements dot txt, which tells us our dependencies, and then the V and V directory, this is our virtual environment. And we are going to run a program in the virtual environment. So normally, when you're installing Python dependencies, you use the program, Pip, but I'm going to make sure to run the program PIP from our virtual environment. So I'm gonna do V and V dot slash bin slash Pip. And then I'm going to install flask and requests. So these are to the dependencies. So we were making a flask app, and the requests library will allow us to make HTTP requests. So after we get everything installed in our terminal, I'm going to open up this folder in Visual Studio code. Okay, so here's everything in Visual Studio code, it has all the files I mentioned, such as our configuration file, plumie, that Yamo, the requirements, and then the main.py. This is where our main Python code is going to go. And you can see it installed some, putting some default code here are going to end up changing most of this. So we're gonna start off by actually changing the name of this file to app.pi, it's common for flask to be to be looking for a file called app.py, for the flask app. So like I said, we're gonna get rid of this code, we're gonna eventually use some code similar to this. But for now, I'm going to paste in some code here. And I'll even zoom in just a little bit more. So this is how to create the most basic flask app you can create. And so we're importing flask, the app is going to be flask with the name. And so this is how you create a route in flask you do that the app app, that's the app here. And then the route is just going to be the default route slash. And this is going to, it's going to basically just when you go to this route with just a slash at the end, it's going to run this function, it's going to return hello world. And so let's just test this out right now, I'm going to save this, and then I'm going to, and then create a new terminal window. And then I'm going to just do vnv slash bin slash flask run. Okay, it's giving me a URL to go to. So I will just Ctrl click here. Okay, and here it is, I'm going to zoom in here. So it just says, Hello, world. Okay, so we've created a flask app. And we've verified that flask is working correctly. Okay, back in VS code, I'm going to make my terminal get a little smaller here. So I'll just stop the app for now until we've made some more adjustments to our code. And I'm going to actually paste in some all new code here. Now, check, I'm going to be pasting in a lot of code in this tutorial, you probably don't want to wait around as they type in every single thing in here. So I'm going to be pasting in some code and then I'm going to be explaining what the different parts do. So if you check in the description, you can get a link to all the code that we are using in this tutorial. So you can see first we're importing OS, this is gonna allow us to get an environment variable later. And then where we are important we're getting, we're getting flask because this we're making a flask app, just like before. Now here is where we are importing the plumie automation framework. This is what I discussed earlier. So we're importing blueys automation framework as a variable called Auto. Then in the ensure plugins function, we get access to the local workspace, a N A, and this is something specific to pulumi. A workspace is the execution context containing a single plumie Project Workspaces are used to manage the execution environment. They provide various utilities such as plugin installation, environment, configuration, and creation, deletion and listing of stacks. Now here we have the WS dot installed plugins. Because we are deploying AWS resources in this tutorial, we must install the AWS provider plugin within the workspace so that the plumie program will have available during execution. And then we have the create app function. This is what flask will run when we start the flask app, we must first ensure plugins we run this function here, and then create the flask app. Now this is very similar to what we saw in our example flask app that we just tested before I put in this code app equals flask. Now this app dot config dot from mapping, this is also something specific to flask not plumy. This function is used by flask to set some default configurations that the app will use. This will not be a production Ready app. But if you ever deploy a flask app, make sure to change the secret key, I just have a secret, you can basically have this anything you want. The other variables are used by pulumi. So we have the project name of Heroku. Cool, too, I updated this. At first, it was Heroku. Cool, because that's what it was originally going to be called. But remember, we call it Heroku. Two. So this has been updated to Heroku. Two, you may want to use Heroku, depending on what you call it, if you're following along. And then we get the environment variable, the plumie organization, we get this, this environment variable. And that's why we import an OS above. Now the rest of this file is common to flask apps, we set the default route here. And just what this slash This is just like the example we already showed, but now we are also setting the HTTP method. This is for GET requests. Now, you probably already know about HTTP methods and request. But a get request is one of the most common requests when you're getting information to your web browser. So what we are getting the index html file, it's going to return this template that index that HTML template. This is an HTML file that we still have to create. And basically, it's going to render this file to the browser when someone goes to this route. And then we have this here, the file is going to import the sites and virtual machines files, which we still have to create. And it's registered them as a blueprint register blueprint. A Blueprint in flask is a way to organize a group of related views and other code. Rather than registering views and other code directly with an application. They're registered with a blueprint, then the blueprint is registered with the application when it is available in the factory function. Basically, we're using blueprints. So we can define additional routes for webapp. In other files, it's all just about being able to create some routes and these other files. So speaking of other files, let's create some. So I'm going to create a directory called templates. So let's click the new directory. And this is going to be called templates. And then I'm going to create a file called index dot HTML. And then I'll paste in some code here. Here's the index html. Again, you can get all this code at the link in the description. I won't go into too much detail about this code. It's basic HTML, but anything inside curly braces, like this block content, this is in curly braces here. This isn't curly braces. Basically, anything inside the curly braces is an expression that will be output to the final document. Flask uses the Jinja template library to render templates. So we can use the curly braces, the Jinja templates, to dynamically render things, like for instance, soon, we're going to use it to dynamically render a list of the sites and virtual machines that the user has created. And then we can also access variables that we create in the Python code, we can then put the variables in these curly braces to make them appear on in our in our website and the front end of our website. And you can see we can get specific URLs. So it's getting the URL for this site that lists sites. Now, this is something we're going to create in our Python file, we're going to create a list sites function. And this is going to be a specific route that we set up in our Python file. And this URL for function will be able to get that that URL basically. So next, let's create a new file, you can already see that this extends base dot HTML. So there should be a when it displays is going to display is the base dot HTML is going to come before the rest of this content. So I'll save this and I'm going to create this new file. And it's going to be called base dot HTML. Okay, I'm going to paste in this. Yeah, so this is going to have a header. And it's going to have another container that's going to have different flash messages. So our app is going to be able to flash up alerts and messages to to the user. And that's going to be all of this is going to be at the top of every page in our website. So I'll just say that. And now we're going to pretty quickly create the rest of our HTML templates. And then we'll Create the Python files that do the real heavy lifting in our app, and will go much slower through the Python files, the Python files are going to be what actually using plumie to create the different resources on AWS. So we're going to inside this Templates folder, I'm going to create two more directories, I'm going to create the site's directory. And I'm going to create the virtual machines. Directory, oh, these weren't supposed to be within each other. Silly. Move that, okay, so they're both in the same root level. And each of these are going to have the same three files, they're going to have an index that HTML file, a create that HTML file and an update that HTML file and the same for virtual machines. In will paste in stuff here. And I want to kind of point out some things here. So it's going to start with the base html, it's going to have this navigation here. But the real thing we want to look at is, it's going to, the real thing we want to look at is going to it's going to take information from our Python code that we still have to read, to have to write specifically, there's going to be a list called sites. If there's no sites, it's just going to say no websites are currently deployed, create one to get started. And then the URL for sites that create site, which will go to this create that HTML, and it's going to allow people to create a site. But then if if there are sites, it's going to loop this for site and sites. And it's going to add this free site. So you can see it's getting the URL for the site, and then the the name for the site. And it's getting a URL to delete the site, and to update the slides. And you can see the ID is the site name, the site name, so it's getting all this information from the site's list that we are going to create in Python in this site is actually going to this list of sites is going to come right from plumie, when you use plumie to get this list of sites that have been created on AWS, to show on this index page. And then then there's the console URL, you'll see what all this is in a minute. So I'm not going to talk too much about these other ones. It's pretty self explanatory. It's just basic HTML, all the functionality comes on the Python. And so that's what we're going to really focus on talking about. Now, the Create and Update are very similar. It's it's doing basically similar things except update will have some information already filled in. And then I'm just going to add this code for the virtual machines files, which is just like for the site's except it's going to be showing information about the virtual machines. So here, it's going to like if if there are if there's no VMs, no virtual machines are currently deployed. But if there are VMs. So it's going to be able to have a link to delete the VM, update the VM. And here, it's giving a command to SSH into the virtual machine. And we're going to actually try this out later after we create a virtual machine with this app. We're going to SSH into it. And it's always going to start with this same line. And then it's going to have the DNS name it's getting see what the curly braces so it's getting that directly from the from the Python side, where we've stored the DNS name for each virtual machine. Okay, now we'll do the Create. There's nothing too fancy in the Cray it's just a web form to insert certain information for our virtual machine. And then we have the update one. And this is to update information in the virtual machine. Now I'm just going to make sure all these files are saved and exiting the close some of these, I'm not really going to need to go back into these views. These templates, I mean, now it's time to create the functionality of our Heroku clone using Python. So the app.py file imports from these files that we still have to create. So in the same directory as app.py Let's create sites.py. So, new file sites.py. So now that we got the site's dot py, I'm going to paste in some code here. And these are all just the basic imports that we need for flask and plumy, including importing the automation framework right here. And then we import s3 from plumie, AB AWS, to interact with AWS and create an s3 bucket. And then there's BP equals a blueprint, we see the URL prefix is slash sites. So we are going to be defining what happens when people go to the URL slash sites. Now I'm going to paste in some more code and then describe what it does here. So here's a new function Create plumie program. And it's going to take a parameter, it which is going to be a string content. So on the front end of this web app that we're creating this Heroku pool, people can create a website, they can deploy a website by inputting the HTML that makes up the website, the HTML that the that the users put into the web form, becomes this content, and gets passed on to this create plumie program function. Later, we're going to be creating some routes and functions that call this create plumie program function and pass in the HTML text, that's going to become the content of the website that users are trying to create. So this function defines our plumy, s3 static website in terms of the content that the color passes in, it will allow us to dynamically deploy websites based on user defined values from the post body. So if we go in here, we can see that first we're creating a bucket and exposing a website index document. And then we're going to write the index dot HTML into the site bucket. So we have s. So again, the s3, this is this is part of pulumi is part of plumy to create an s3 bucket, and we're creating the bucket object. And the bucket, the ID is the site bucket that ID, which is going to be come from the bucket that we created up here, the content is the index content, which is what the user passed in as the HTML of the file, then we have the key in the content type. And then we are going to set the access policy for the bucket. So all objects are readable. Now, the way this gets set is specific to AWS. So that's where all of this is coming from, like this date is actually specific to AWS that we have to pass in for this. And you'll be able, so depending on what you're going to do, you just have to look up what information you need for AWS to create a bucket. And then finally, we are going to export the website URL. So the purpose of this Paluma dot export command that that you see here is to export a named stack output, exported values are attached to the program's stack resource. Later, we will see how we can access this data that's being exported. It's kind of like an environment variable. So this is the key, it's like a key value pair. The key is the website URL. The value is site bucket, that website endpoint, this is going to be the URL that we get directly from AWS, after deploying this site to the s3 bucket. And then the website content. This is just the the content of the the HTML of the website that we get here. So far, nothing is calling this function. So at this point, let's create URL endpoints that can be used to call that function we just created to create websites. So first, we will create a may persist, but this is a new route. So at slash new so first is going to be slash sites. And then after the end of slash site is slash new, and this will respond to both GET and POST requests. So you First, we're going to check if it's a post request. And let's just go down to see what happens if it's a get request. If it's a get request, it's going to return render the template sites slash create the create that HTML. But if it's a post request, that means the user has already went has already done the get request, they fill in the form. And now they're sending data to the same URL. And this is what we're going to do with that. Now you see this request that form that get? Well we got requests, that's as part of flask, and this is part of, oh, are the go. This is how we access the information that's sent with the form. And the information is different key value pairs. So the user will have put in the site ID into the form. And now we're getting that and we're setting it to be the stack name. And then the user will have put in a file URL, possibly, maybe not. So the way it works, the user can put in the file URL, which is the URL they want to upload to the s3 bucket, or they can type in the HTML. And that's going to be the site content. So first, we're going to get the fire URL, if there is a file URL, then we'll set the site content to now request that get this is going to be doing a an HTTP request to whatever URL that the person passed in and getting the text. Or we're just going to get whatever the user typed into the site content. And then we're going to find a function plumie program where we're going to call this function here the Create plumie program function. And we pass in the site content, the string of the site content. So that's how we actually create the website. But this function hasn't been called yet. Because we're going to do that within this try catch block. So a try catch this is just if you're not familiar, if you don't know a lot about Python, it's just an error handling thing. So we try the code in here. And if there's an error, then it's going to do what's down here. So the first thing that's gonna happen says Create new stack generate, generating our plumie program on the fly from the post body. So you can see Auto is the automation framework out that create stack. As a reminder, every plumie program is deployed to a stack, a stack is an isolated independently configurable instance of a plumie program. In this code, the stack name is based on the ID, that the user typed into the form. So my stack name right here was the ID. And then we got the project name, and then the plumie program, and pulling the program is this, which uses plumie to create the website on AWS. Now, it's not going to run the program, until we get down here, stack that up. If you had the, if you're on the plumie CLI, you would do clue me up. But first, we're going to make sure we have the correct way we can set the AWS region. Now there would already be one as default. But you could you could set a different AWS region here. And then we deploy. So stack that up. And then it's going to says output print. So this is going to print all the output so in the terminal, and then we have a flash. So this is going to flash up on the website successfully created site, or it may flash up an error. So this data up, let's just I'm going to talk a little bit more about that. Because once the stack is created, we can execute commands against the stack, including update, preview, refresh, destroy, import, and export. So stack that up is to up date the stack. And then you can pass in the a callback, which I already discussed, which is going to print to the standard output. Okay, I'm gonna add a new section of code, which we will discuss. And this is going to be a new route. This is just to the the route route the slash, but it's not just slash because it's still going to take into account the sites. So if you just go to slash site slash, it's going to list all the sites this is a get request. And it's going to so this variable right here site, it's the list. This is what's going to be passed into our template our front end, once it's full of sites, it will be passed in, and then it can display the list of sites, we're gonna get the org name, the project name. And then it's going to try this. And then if it's an error, we'll just go down to this except here. But the first thing is going to do is get the automation framework that local workspace, a workspace is the execution context containing a single plumie project, a program and multiple stacks. So here we're getting access to the workspace. And then we are passing in the project name of the workspace, then we have lists, stacks. So this just gives us access to the stack name. So we also have all stacks is just gonna be the names of all the stacks. So now we have to get access to the specific stacks. So that's why we do auto dot select stack, and we pass in the stack, we're trying to get stack dot name, and the project name. And then whenever you do select stack, you can pass in a program, but we don't want the program to do anything. So that's why just lambda none. So select select stack is very similar. If we scroll up here to create stack, so create stack and select stack have similar parameters. So in this case, the program was to run this plumie program. But when we're selecting the stack, we're not going to run any program or anything. That's why we just have a basically a blank function here. And out equals select outputs. So remember, when we initially created it up here, we export things. So the outputs are going to actually just be this information. So we're getting the website URL, and the website content for each item, easily each website. And once we get the information, if the website URL isn't out, then we'll append this information to the site where this is what's being passed to their front end, the name stack that name the URL. So it's going to be the the website URL, and then the console URL. So cancel URL. This just means where we can access information about this on the plumie website. That's one great thing about plumie is that you can get information about your application through the command line, and through different ways through your program. Or you could also go to the plumie website, every time you're you're creating a stack, every time we're creating a site or virtual machine, we can go to the plumie website to get information about that, about that whatever resource we created. So I'll show you that later when we try out this program that we're making. And then if there's an exception, we will flash this to the person. And then we we're going to return this, we're going to render the template. And it's the index html template. And we're going to pass in sites equal sites. So now we want to enter the template and path in the sites. That means if you remember, we'll just look at that really quick. But if we go to the index, it's looking for each site in that list to to display. Okay, I'm going to save that. And we're going to add a little bit more to this file. So I'm going to paste this in. And we're going to talk about this. So this is the update route. First is going to be the ID of the site slash update. And this can be a get request or a post request. So first, it's going to receive the ID into this function here. And we're going to store as the stack name. So if it's a post request, first, let's see what happens if it's a get request. So if it's a get request, it's going to render this template, update that HTML because the person wants to update it. And then once it actually is updated, it's a post request. And it's going to do this now this is going to look very similar to our previous function. When when someone creates a new site, it's very similar to when they're updating the site. So we get the, this is all the same the fire value Well, first we get the site content. We have the plumie program, we have the Select stack. Now this is all pretty much the same. We do stack that up. We do stack that up to update it. One good thing about updating with plumie It's going to see what's changed and only update those things and not not going to just update everything, it's going to only update whatever has changed. So even though we're putting all this thing, all this stuff here, it's only going to figure out what changed and update that. And then we're going to flash successfully updated, we have air. And then it's going to redirect to sites that list sites, which was just our slash, so not the update the index. But then this is what happens if it's a get request, first, we're going to get the stack and then the stack that outputs so we can get the website content. And then the website content will be used when we render the template, because that's where we want the content of the website to show in the in the update section. So users can see what they're updating. And there's only one more section to this file, which is the Delete route. So I'm going to paste in this here. Now this is very straightforward. So if the the the route is the ID slash, delete, it's a post. And there's not even any GET request here that so there's no page for delete, and you just click the Delete button, and then it's going to delete. So we get the, so we have a stack name, we're going to first wait to select the stack, then stack dot destroy. So previously, we did stacked stacked up to update it. But here we're going to destroy and then remove the stack. And this is a cool thing about plumy. Just doing stack that destroy, it's automatically going to delete the resource on AWS. So whether it's an s3 bucket, whether it's a virtual machine, or whatever resource that we create on AWS, just doing stack that destroy will delete it. So it's not going to charge you any money anymore, because it's just completely deleted off of AWS. And then it's going to flash the message. And then there's a few possible exceptions that could happen. And then it's just going to read redirect to the list of sites. Okay, this file is done. And there's really just one more file to create, which is kind of similar to this file, it's the same one, but for virtual machines. So I am going to go up here to new file, and this is going to be called virtual machines.pi. Now, this time, I'm just going to paste in the whole thing, and they're going to go through it, it's a little bit longer. But there's so much similarities, we're not going to have to go through everything. Because the automation framework makes working with different types of resources, very similar. It's not exactly the same, because AWS is going to require different information when you create different types of resources. But the whole top section is basically the same. Now here we have instance types, because when you're creating a virtual machine on AWS, you have to choose what type of instance you're going to use for your virtual machine. And, in reality, there's way more options on AWS than these three. But for this example, we're going to give the user three different options. But you could easily add more to this list here. And so here we're going to create the program. And right now the only thing that the user will be able to choose is the instance type. Or you could make it so a user could create it could do could choose other options. So here, this is the plumie library, but all this information is specific to AWS. So when you're creating a virtual machine, you're going to first have to get access to the AMI. And then we have specific information here. that's specific to AWS. And we also need the security group. And so we specify this and it's going this is how we're going to enable SSH access access because we want to be able to SSH into our virtual machine, which we will actually do, I'll show you how to do that once we get this all set up. Now this is going to be something that's different with the virtual machine than the the website hosted on s3, we are going to have a key. We're going to have a private a public private key pair. This is going to basically provide authentication when we want to access the virtual machine to make it so only the person who created the virtual machine can access it and not just anybody can get into it. When we're creating the virtual machine on AWS, we must give a public key then in order to access the VM Em, you have to have the private key. So what this is doing here is getting the public key information from our local file system. So we're getting the path. And it's just accessing this path, the home path, to access the public key on the file system. Now this is a file, and we're going to actually have to make sure we have created this file. So when this goes to access it, it's already there. Now this, this directory, this directory structure is generally the same on both Mac and Windows and Linux. So whatever operating system you have, this path is, this should work no matter what operating system you have. And the way that we're going to create the key value pair, it puts it into the same directory, basically, no matter what operating system you have. So this is something that when you're creating the virtual machine through the web interface, you're going to have to put in the string of characters, which is your public key. And then later, when you SSH into the virtual machine, you have to make sure you have the private key on your computer. So it can validate that you are the person who owns this virtual machine. And I'll be showing you how to do all of that and just a little bit, but it's going to strip all the whitespace from the public key is going to print the public key. Remember, public keys can be a public knowledge, anybody can know your public key, but you don't want anybody to know your private key. And we're going to create a key pair. And this is specific to AWS, how this is created. And then we are going to have to get the server. And you can see we're passing in the security group, the key pair, the instance type, and the AMI, this is all stuff that we created earlier. And then it's going to do a bunch of exports, the instance type public key public IP and public DNS. And this is the information that we're going to be able to use to access it through SSH. Okay, now, this was just the function, we just have to make the routes to use the function. So just like before we have the new route, we are going to get the form data, the form that is going to have the ID, which is just something that a user makes up and it's going to become the stack name, someone, the user is going to enter the key, the public key, which is now going to be the key data. And then they're going to choose instance type. And remember, the instance type is going to be one of these three options that is going to be basis can be a drop down menu on the front end. And that's going to be stored as instance type. And then with the plumie program, it passes in the key data and the instance type. And then the rest of this is very similar where we create the stack. And then we configure it, and then stack that up. And then on success on not success, then it's going to list the VMs again. And then this current app, that logger, this is just going to make sure information is we'll just log this information of the instance types. Now, if someone did a get request, it's going to go to the Creator HTML that everything else was the post request. And when does the Creator HTML, it's going to pass in some data, the instance types, because this is going to become a drop down menu on in, in the index that create that HTML file. And the current instance type is none. And then we have the this is just where it lists all the VMs because it's just slash it's a get request. And it's going to be very similar to what we've already looked at. Let's see what's new. The only real new thing in this compared to what we've already looked at in the sites is what's being outputted Well, I mean, what's gonna be in the list, but you get the DNS DNS name, but everything else is basically the same. And then the update will update is going to be very similar to when you're creating something new. I guess the only really the only difference when you're updating it is that when this renders update HTML, it's going to have a current instance type. Whereas when you create a new one, there was no current instance type. There's also we already have the public key, the stack name and the instance types. And then we have delete So now this is going to be almost exactly the same as the site's one because we just have to get access to the stack and destroy it. And it's going to completely destroy the virtual machine from Amazon dot AWS. Now, this can be super helpful, because if you've done any work on AWS, especially if you're just learning, you may find out the hard way that if you turn on things on AWS and forget to turn them off, it can start charging you a lot of money. But when you just do stack that destroy, well, that will just delete everything, and you will no longer be charged the money anymore. So even with this example, it's going to cost us a little bit of money, but just a few cents as long as you destroy it right away. Okay, I'm going to save this. And now I'm going to show you how to set up your key value pair, there is a program called SSH key Gen, and this is on both Mac and Windows. So you may already have it on your computer. If not, you can just look up SSH key Gen, a search for it and find out how to get it installed. But we're just going to run this SSH key Gen program to create a new key private public key pair. So I'm going to type in done to my terminal here, SSH key, Jen and dash m and I'm going to make up the type PIM and this is the type that you need to use for AWS and I'm just gonna press enter and then enter file missus save the key. Now I'm just going to go do the default and you and then you probably going to want to use a passphrase here Okay, now I've created it. Now we're going to go to that directory just to make sure we have it in there. So I'm going to change to the directory. Now this is the file we just created. But you're going to have to make sure it has a a.pm pe M extension, I already have this because I already created one with a dot p m extension. So you're gonna want to rename this. Now, it's different depending on what kind of operating system you have. But one way to rename on Mac and is just MV, you just put in the the name here. And then in v means move. So I'm moving it from one name to the other name. So I'm going to just put RSA dot PEM. So on Windows and you could basically do the same thing. But instead of doing MV for move, you're going to type and rename, so renaming a put the first file, and then what do you what you want to be. So this is our public key. So if you remember, our program will try to get that public key file. But you can also enter it as your key data. So you can either open up that file, and copy the key and then paste it into our web interface. Or if you don't, if you just don't put anything, it will try to get that information on its own. Okay, now let's see, let me just get back into their other directory. And then we're going to run our flask app, I'm going to start a little differently, so I can put in some environment variables first. So see I'm putting in the port, the environment, the plumie organization, and then I'm going to run Okay, it's time to test this out. Okay, this is looking good so far, except we still need to create our CSS files. So let's go back and make sure we get our CSS in there. So it looks a little nicer than this. But we do know that it is seems to be working so far. So actually just pasted in these files here. Static and this is just Bootstrap. We're just using basic bootstrap for our CSS. We're just trying to make it simple here. So let's go back over and refresh. Okay, this is looking good. I'm gonna zoom out a little bit. Okay, so Heroku cool. And we can either create a static website or a virtual machine. So let's test to see if everything works. I'm going to click get started. Okay, no websites are currently deployed create one to get started. So here is where we can create a name. And I'm going to just call it Hello, world. And the name, there can't be any spaces the way that we created this. So the file URL, well, I'm not going to have a file URL, I'm going to create some content. So I'm going to do hello. And I'm going to make put in some HTML here. So we can test to see if that works world. And then I'm going to click Create. And look at this successfully created site, hello world. Now this, it could actually take a while to create the site, especially if it's the first one. So you just got to kind of wait a while to see to finally kind of pop up like this. And so let's test a few things. First of all, I'm going to just click this. And it's going to open the URL. And now let me zoom in so you can see it hello world. And we see it's has bowled. And you can see this URL, it's right on s3, s3, this website is us. This is this one Amazon in the us.com. So we have this website on here. And if I click View, in console, well, before I do that, let's go back to our Visual Studio code. And you can see its output it website content, website URL, resources it created for resources. So we can see right in here that actually created the resources. And I'm going to try viewing and console here. This is opening right on Hulu, me. And then if you're signed in, then you can get to here look at so it's Beau Carnes slash Hero, Hero cool to slash hello world is zoom in a little bit here. And then we can see the website content, we can see the website URL. And then we can see more information like configuration, secrets management, we got some tags here. And we can see all this information about our site here. And then with resources, we can see additional information about the the bucket is what bucket is used index the policy. And then it's even going to give us information about how to destroy things and change things. But we don't need to do any of that. Because we can do all that from our web interface. We're going to actually try editing and deleting this. But before I want to show it to you on Amazon AWS. Now, the great thing about this is you never really wouldn't need to check on Amazon AWS bound, just see you show you what it looks like on there. Okay, now I'm on my Amazon AWS account, I'm on the s3 section. And you can see the buckets. And you can see right here, here is the bucket we just created. It's showing the index file here. And it's showing here's the URL, the URL that we were given that go that you can use to access this file. If I go and I'm going to just go back over here to show this here. Now I'm going to go back to our web app, our Heroku. Cool. And I'm going to first let's try a few things. I'm going to edit it and then I'm going to delete it. So first, I'm going to check to see if edit works. And we're going to put this all in an h1 Tag now just click update and it successfully updated. Now I'm going to click here and let me refresh. Oh no, I don't have to refresh. This is with the h1 tag. So that's why it's all way bigger than before. And with h1, bold really doesn't do anything. So that's why there's nothing no difference between hello and world. So now I'm going to delete this resource site HelloWorld successfully deleted. And then if we go if we go back into the terminal here, we can see that oh, it's going it's showing what it's doing. It's it's going through and deleting all these things. It's filling the bucket policy, the bucket object, the the s3 bucket Add the stack, it's deleting all of this stuff, anything that was associated with it, it just deletes. And if I go and refresh here on my am s3 page, oh, this bucket is no longer found, it's now no longer in the bucket list, it's completely deleted off Amazon AWS. Now I'm going to try creating another one. This time, I'm going to use a file URL. This is just a game that I found on GitHub. So I am going to see it's a, I just clicked on the raw file. And we're just going to put in this URL to see if it works, I'm going to call a snake. And then I'm going to create successfully created so they click here. And now I am playing Snake, I just put in that URL. And I can play this game cool. So I'm just gonna close this for now. And let's see what happens if I click Edit. Well, now, we don't just have the URL here, we have all the code that it got from the URL. And now we can make any changes we want. Like what if we want to change the canvas, let's change how big this is, instead of 400 by 400, I'm going to put 1000 by 1000 and update that Oh, Kevin, click here. And now wow, this is a really big, this game is gonna be really easy to not hit myself now. I think maybe the apples still are all gonna be in this one little corner. But I can go really far away. So I was able to update the code right from there Okay, and just so you can see what it looks like if you have multiple ones, we can call this test and test and I'm just gonna hit Create so now we have two here. And you can see it creates an Amazon creates a bucket for each. For each one that we create, there's a new bucket for each website. And then if I click view on console, you can see we can go back here and we can see snake and test. And then here we can even see for the snake while we can see all the code Okay, let's go back to here. And now we're going to create a virtual machine. Create a virtual machine. And this is going to be called potato. And then you can choose your instance type RS two c three that large. And then I can get the text on my public key and paste it here. But let's see what happens if I don't even do that I just click Create if I go back into my terminal, we can see it actually found my public key automatically. And it's now creating it. Now I could have opened up that public key file in a text editor and copy this and then paste it into that text box. But this way is even easier. And now it says it's done creating let's go back over here. And it successfully created the VM potato. Now let's find the in AWS is not going to be under s3 should be under EC two. Okay, so if I go over here, we can see that this one is running. It's initializing right now. And then here we can see more information about our virtual machine. But I'm gonna get this here And I'm going to try connecting it to it through SSH. So I'm gonna copy that. Now I'm back in my terminal that's not in VS code. And we're gonna paste in this URL here. And you can see it's accessing our dot p m file. I show do you want to continue? Yes. And then the passphrase that we created that I created when I was creating that file. And I'm in, I'm now inside the virtual machine, I can change directories. And you can see that see, I can see all these directories, right in this virtual machines, I can now actually use this to create a web server, or do anything I want with this Linux box. And you can do it right through your terminal. Now, the cost of these virtual machines adds up much quicker than the cost of the sites. So I'm gonna go ahead and delete this. And all these actions can take some time. But if you want one, you can always look in the console to see what's happening. See, it's still it's deleting this right now, that can take some time because it's, it's deleting everything associated with the virtual machine, from AWS and from our records on plumie. Okay, it just deleted everything. So let's try a few things. First, look, it says the connection was closed, closed by a remote host, I didn't even have to do anything. It says successfully deleted. And then if I go to my instances, it's now saying instance state, terminated. Okay, so now I'm not going to pay any more money for this instance. So we just created a very simplified version of Heroku. And you can use the same principles and concepts to create applications that provision all sorts of other resources. And like I mentioned, you can do it with a bunch of other programming languages, and cloud service providers to show you how it would work with different programming languages. I'm now going to show you how to write a simple JavaScript program that will provision a web app on AWS, this won't have any front end, but you'll be able to see how the code is very similar to the Python code. This is the type of thing that could be helpful if you're involved with platform engineering. Okay, I'm in VS code. And this time, I'm going to be using Node js and JavaScript instead of Python. Like I just said, there's not going to be any front end to this program, we're going to deploy an inline plumie program that will create a static website using the automation API. So it's gonna be a little different, but you'll definitely see a lot of similarities to what we just did with Python. So first, let's start our project just with an npm init. And this is just going to, we're just going to use all these default settings here. And this is just going to create a package dot json file, so we can install some dependencies. So first, we're going to be connecting to AWS with plumie. So let's do NPM install at pulumi slash AWS. So this will help us to connect to AWS with our JavaScript program. Now, we're going to install one more NPM and net install or npm install at pulumi slash pulumi. So this is just gonna be the basic pulumi program. Okay, we got that done. And I can create my file. And this is gonna be index.js. Okay, just like with the Python section, I'm gonna paste in some code, and then explain what it all does. And there'll be a link to the code in the description. So let me go back up to the top. And we're first going to require the plumie libraries that we just installed the Bluemix is Bluemix plumie slash a Ws. So that's the automation framework, and AWS. And then we need this process, because we're going to see if there's any arguments when the program is called. Now, we're going to make this program. So we can call it from the command line. And it's normally going to create a website, but we want to make it so if we want, we can also destroy the website from AWS. So that's why we're allowing the the user to put in an argument destroy after the program name when they're running the program. So that's what this does it figured out figures out if this is going to be destroying the website, if not, it's going to be creating the website. So let's go over here. And so let me just show you kind of the whole thing at a glance really quick, we have this run program, and we have this whole run program. And at the end, we run the program, we just call that function, and then we catch if there's any errors. So let's see what's in that function. Well, the first thing in this function is our plumie. Program. So this, this plumie program is in the inline function format, which is just a slightly different than than what we saw with the Python. So unlike a traditional plumie program, inline functions don't require a separate package on disk. So we won't need a pluing dot Yamo file. Inline programs are just functions. And they can be in they can also be imported from another package. But in this case, we are creating it right in this file here. So this so this first section, we are defining the plumie program that we want to run as a function within the overall program. And it looks just like a standard plumie program. So we create the site bucket, which is very similar to what we saw in the Python code. And this is just just like that, we're creating the site bucket, and we're specifying the index document. And then this is the the HTML that we're going to put into the site. Now remember, in Python, we had the user supply this information. But in this case, we're just putting it right in the program. And then we are running the index file into the site bucket. So that's the index content is the content in the buckets, one, the one we already defined up there. And so you should see a lot of similarities with the Python code. And then we're creating the s3 bucket policy to allow people to read everything in there. So this data, again, is just right from the AWS, all this information is what we have to AWS needs to say that anybody can access the files in the bucket, which in our case, are the is the index html file. And then we refer to the bucket right here. Okay, so here's where we actually create the policy. And we're going to apply what we create right up here. And then we are going to return the basically like a key value pair, the website URL is going to be the website endpoint, which we're gonna need to be able to access the website. And the website URL is just going to be the website endpoint, which will need to access the website. And now we're going to be associating it with a stack. So as with existing plumie programs, we need to associate this plumie program with a stack. The automation API provides methods to create or select stacks. And they're in JavaScript is just like, very similar to what it's like in Python. So this is going to do the Create Your create or select stack. So it's either going to create a new one, or if already exist, it's going to select the stack, it would already exist if we're trying to destroy it. So the first time we run this program is creating it. If we run the program again with the destroy, then it's going to select the stack that already exists. And just like with the Python code, we are going to install the AWS plugin. We're going to set this configuration and there could be a default configuration that's already been set up, but if not, it's going to use this one. The with AWS region And then we're just going to refresh the stack. And you can see what it does right on here, it compares the current stacks resource state with the state known to exist in the actual cloud provider. And then any such changes are adapted into the current stack. And both of these here are configuring the AWS plugin, the plumie AWS plugin. And we're just using the stack object to set the region and the provider. Okay, and if we go down, this is what we already talked about. If the destroy argument has been passed, then we'll do stack dot destroy, which will destroy everything on volumi, and will also destroy everything on AWS. So anything that's been created on AWS will be destroyed. And then the program will exit here. But if it doesn't get destroyed, we'll go down to this. So await stack.up Where up is update. And we are choosing to have a callback, which is going to the standard output and doing console that info. So it's outputting everything to the standard output. But you can do other things with this callback function. So you could choose to take different actions, if there were no resources updated, for example. Or you could use the stack outputs to drive another plumbing program within the same automation program. So that's with having the callback function, it opens up a lot of possibilities to what you can do after this update takes place. And then is going to log the URL that we've set way up here. So then we can go to the URL, and then it's going well, then, then that's the end of that function. And here we run the function. So let's test this out. I'm going to save this. And then I'm just going to do node index.js. And here's the website URL. So I can just copy this. And then I'll go to in the web browser. Okay, here it is in the web browser, hello world. And you can see even says hello s3 appear, because we set the title of the page. And you can see it's hosted on Amazon AWS. Okay, now I'm gonna run this program again, node index js. But this time, I'm going to pass in an argument, destroy. Let me just confirm that is what the destroy. So if I pass in destroy as you can see, everything's been deleted, we have four resources that were deleted. The s3 WePlay, bucket, bucket policy, the bucket object, that node here. Okay, they've been deleted. And then you can also run another command to remove the stack completely. This in the Python file, we actually did run that command in here, we didn't, but we can always run that manually. And then if we go and refresh on the page 404 not found. So I hope that gave you a good sense of how the JavaScript and the Python works, and the similarities and the differences. And there you have it. Our JavaScript program is able to provision infrastructure just like our Python program. So I hope you can take these concepts and this knowledge and start applying it to your own projects. Well, thanks for watching.\n"