Transcripts
1. Introduction: Hi there, This is Valentine. And today I wanted to go over the process of hosting a website with AWS. I have just brought a new domain name. And I'll show you step-by-step how to host a simple HTML and JavaScript website with AWS S3, or go through the process of hosting a real domain. And together we're going to set up an AWS S3 bucket, upload some files, and configure everything to run properly. In the second part of the tutorial, I will show you how to automate the entire process with GitLab CI. And together we are going to build a simple CICD pipeline. Trust me, it is easier than you think and automation is so important. Today. We'll work from a Git repository and any changes that we make will be automatically deployed to the website. But first, let's make sure that we are on the same page right from the beginning of this tutorial, assumes that you have an AWS account hosting your files with AWS. S3 does not work if your website is more complex and needs a database where you need to run a programming language like PHP, SPX, or anything similar. This will also not work if you're trying to host a WordPress website. This will work quite well for Angular or React project. Hosting a website on AWS, S3 also does not support HTTPS. If you need this, you need to configure AWS Cloudfront In addition to what I'm showing you here. With that being said, let's jump straight into the tutorial.
2. Creating an AWS account: Amazon Web Services, or simply AWS, is a cloud platform offering over 170 services available in data centers all over the world. Such services include virtual servers, managed databases, file storage, content delivery, and many others. If you don't already have an AWS account, it's quite easy to create 10. Enter your personal details and click on Continue. If you are using this account for professional purposes like within your organization or plan to do deployments or to use AWS within your organization. Professional. Otherwise, if you are just learning AWS and experimenting with it, It's absolutely okay to start with a personal account. And ws is a paid service. And even though in the beginning there is a free tier which has some limits and it's ideal for learning AWS and experimenting this theory card, a credit card or debit card from you just in case you go over the free limit. So yeah, eventually AWS is a business, so they're trying to make money. This is why you need to input your credit card information here. Otherwise you will not be able to use AWS. And I'm going to add this credit card information. And additionally, I also have to verify my phone number. Now my identity has been verified and I can start using my AWS account. Aws also have a support system and you can select the support plan. I personally think that their support is actually very, very good. But you will only need support from them if you're deploying AWS within your organization. So for just learning purposes and getting started, you don't need any support from them. You'll have all the support from my side when it comes to the content of this course. So we'll simply click on free and continue with a free basic plan. Now we have an AWS account that is verified. It has a payment method. And what we need to do next is to signing into the console because from the console we can access all the services that AWS has. You think the AWS management console, it means that you have set up everything correctly and you can continue with the rest of the course and start using AWS right away. Aws is distributed in multiple datacenters. And you have the possibility of selecting the datacenter that you would like to use right here on the right side, on the top of the menu. Currently in my case I have US East Ohio. Typically, the US data centers in the US have a lower cost than anywhere else in the world. But you may want to check for your specific reason if you are interested in having those in your specific regions. For example, for data security reasons, many company within Europe preferred to have their data centers and their data from AWS physically located in Europe. So for that reason, AWS offers this service, but it is much more expensive than datacenters located in the US.
3. Creating the AWS S3 bucket: Why I'm here at named Chip.com. This is what I use for registering and managing domains. Typically they have very, very nice prices and the interface to manage the domains, it's okay. For that reason this is what I'm using and you don't have to use them. This tutorial will work with any domain regardless where you have registered with GoDaddy, Google domains, whatever the principles, absolutely the team. So the domain I'm trying to use today is this one. Learn DevOps dot link. Open up a new tab and show the contents of this website. You will see that it's currently just hosted here on this landing page from named ship. Nothing special about it. So what do I do? I try to do next is to create an AWS S3 bucket for this domain name. I'm here inside my AWS management console. And the service that I'm trying to use is S3. So I'm going to look here under storage and you will see S3. And I'm going to click here on the button Create bucket. Now we want to make sure that the bucket name is appropriate. So kinda type here, www dot learned DevOps, that link. So this is the domain name that I'm trying to register. Select a region that is more appropriate in your case and make sure that you remember this region, especially this part. So the technical name of the region. And after that you can simply write here, go over different settings, but simply go ahead and create a bucket from the list of available buckets, you should be able to click on it. And of course you will see that it is empty. Now, just a general remark, AWS has changed a lot. The interface of S3 of this management part here. If you're watching this tutorial bit later, it may look a bit different, but the principles should be automatically the same. Just a heads up on that direction. As you can see normally at this point, we don't have no files inside here. So what I'm gonna do here is first go ahead and upload the simple file. I'm going to click here on Add files. And I'm just going to start with a simple HTML file just contains something like hello world. So just to test things out and make sure everything works properly. Will upload, should work in a second. Additionally, what we're gonna do is gonna look here at properties. And somewhere here you should see static website hosting. So I'm going to click here on Edit because right now it is disabled. So I'm going to enable it, gonna specify what is the document. So what is the index document? In my case, the index document is index.html. And I'm going to specify the exact same page also for the error document is also useful if you don't have an error document and you're trying to host an angular website or react website. The index document has to be the same as the arrow document. We have here setup everything. This is exactly the name that we have. And I'll click here on save changes. And additionally going to permissions, you'll see here that public access is being blocked at this time. So we can unblock everything, save changes, confirm. If you're trying to get the link to this or we have to do is go to the properties. So the properties are here. And in a section with static website hosting, this will be the temporary address that we'll have for the website. So let's click on it and see our website. Oh, that doesn't look good. What happened? Well, what happened is that we still need to figure out a few permissions. So it is not enough to simply make here this public access. But additionally, when to specify a policy. In order to specify that policy which will be written in JSON. Going to click here on bucket policy on Edit. And we're going to take a look at some policy examples. The policy that we are interesting in adapting is something like this cranking read-only permission to an anonymous user because we don't know who is visiting or bucket who's trying to get this information. So we're going to simply copy this permission from here. Kinda go back to the management console. I'm going to paste it here. Originally, what we interested in is getting this resource name, right? So you'll see here, AWS is making our life a bit easier. So with providing here the exact bucket resource name. So we can simply copy this and make sure that we're not replacing everything. This is how it should look like. So you have to adapt it practically your own domain name at this point. So let's save the changes. And you will see here now the access is in red, is just trying to alert you that, hey, by the way, everything that you have in this bucket is public. And for that matter of fact, I don't recommend that you store anything in this bucket that is not intended to be public. So be we're very aware of that. If you need to store other files, don't use the website, don't use the bucket for this website for storing something else. Let's visit again the website and you will see here, my new website. It seems to be working and this is absolutely great.
4. Modifying domain name records (DNS records): Now, this is not everything that we need because you don't want to give your customers or to anybody else and address that looks like this. You actually have bought your own domain name and we're trying to host that. So now let's copy this. The following steps will be different depending on how exactly you're managing your domain records. So I'm going back to Nim trip.com and I'm going to click here on managing this domain. What we're actually interested in is managing the DNS. So there are some DNS entry that we want to change. And what we're going to try to do is either add an alias record or a CNAME record for this domain. So I'm going to simply remove anything that is already here because we're not interested in that. And add here a new record. I'm going to call it an alias record. This will be valid for www and the target will be this one. So I'm going to make sure that I don't have anything like HTTP. We should start with www, should end in.com. And of course, making this change, it takes a bit until you can actually see your updated website. My advice is to check in five to ten minutes to see if this change a word. But in a worst-case scenario, it can even take up to 24 hours for this change to propagate. Be a bit patient. But ideally you should see something in just a few minutes after a few refresh attempts. And sometimes it's even worth trying out to your browser. You should be able to see now that your new website is available. So this page is then served from AWS S3.
5. Getting the domain to work without www: So let's look at the following thing now. You will see that this domain name has www in front of it. Now it's possible that in your case, if you're trying to visit a domain as it is, that it will not work. So if you are trying without the www, this case, it's automatically added. You may get an error page. You may get an error page from AWS saying that he does nothing configured with this domain name without the www. So if that is the case, let me show you what you need to do. So going back to the S3 console, and I'll simply go ahead here, create a new bucket. This bucket name will be now the exact domain name, but this time without the www in front of it. And I'm going to simply go over defaults as they are. I'm going to create a bucket. Now the difference with this bucket is that will not contain any files, but we still want to use AWS S3 for static website hosting. So we're going to edit here the settings. Then I enable that. But this time we're gonna redirect to requests to another bucket or to another domain. So in this case, we want to enable static hosting and going to redirect the request. But the host name that we're going to enter here is the domain with www, because you already know that that works. So in my case it will be www dot learned DevOps dot link. And the protocol that we're going to choose is HTTP. As you remember, AWS S3 does not support HTTPS on EC2, some additional configuration. So I'm gonna save the changes here. And we should be able to get a link to this new bucket that we have created. And you will see now it's redirecting to the domain with www, my browser. This kind of details are automatically hidden. So if you click on it, you'll see here that it's still going to www. Now, still, that will not automatically work for you still need to An entry. So going back here to the Advanced DNS entries, we're going to add an additional entry. This will be again an alias and use here AT. And the target will be the address again removing HTTP before that. So you will see the first entry is with www dot learn, DevOps, and so on. And the second one is we doubt W, W dot. As I said, if it's working automatically, you also need to do this additional step. And then it will recognize what to do in each situation. So they are practically as two different domains, but there are various points, ways to read or write from one to the other.
6. Enabling access logs: Additionally, I wanted to set up something very important and that is also logging. So unless you have like a no Logging policy, I do recommend that you have some logs for your domains. For that reason, we are going to create a new bucket. I'm going to call the bucket WW, my domain name, and then simply add dash logs. Leave the settings as they are, and practically forget about it for a second. I'm going to go back to my bucket containing the actual website, revisit the permissions. And somewhere in this permissions you should see something like server access logging. So it will practically start writing any lock requests, any access to your bucket. And it's typically a good practice to have some logs just in case something happens to know exactly what's going on with your hosting. So I'm going to go ahead and enable that. And what we can do here is to specify our target bucket. So our target bucket will be the bucket with logs. I'm going to choose simply this one. This is the bucket name, and we can simply specify a prefix like logs or access and simply save the changes. What will happen? And this typically takes a while. You go inside this bucket, you should be able to see after a while some access files being logged there. Just forget about it right now and we'll come back to this later to see if it properly worked. The main idea is that I highly recommend that you enable this.
7. Project setup on GitLab: So now that my website is working both with and without www and actually managed to see everything. And I'm quite happy that everything is working properly. I want to move to the second part and that is automated. So what I have here is essentially a project which contains HTML and JavaScript files. It is a Gatsby project that is using some JavaScript in order to dynamically build some pages. But essentially in the end, I'll have here a public folder that contains all the HTML and all the JavaScript pages that are required. Because this is a build process. I want to automate this. I don't want to go from the CLI to be able to build everything and then to to go to the website, to the server, and then to go to AWS to manually drag and drop files and things like that. What we are going to do is we're going to use GitLab CI to automate this entire build process. And I'm going to take you step-by-step and explain what I mean by that. Now the first step is to go to GitHub.com and register for an account. When you are inside your account, you should be able to see something like new project. And we're going to create a blank project. So I'm going to name my project exactly as the domain name. And of course I'm going to remove anything like HTTP and things like that. So www and my domain name. And I'm going to leave this private. And I'm not gonna initialize with a read me because I already have a Git repository. So now this is the repository that has been created for my code. And I can look here at pushing an existing Git repository. So practically the command that I'm interested in is adding a new remote. And of course what I need to do is also to push all the changes. Now in my case, everything is working with doubt in additional configuration because I have Git installed locally. I have configured my private key and my public key with gitlab.com. So in this case, everything is ultimately integrated. If you're just getting started with this, probably easier if you just make a copy of the project that you will find in the video description and use the interface from getline HCI to edit those files. So if I refresh this page, we will be able to see that. No, I see all my files. Just in case you want to do something from here, you can simply click on any file or click on the plus here to add a new file. And if you just want to edit something, you can click on it. Click on edit. And you don't have to have Git installed and everything that I'm showing you from my ID.
8. Defining the CI/CD pipeline in GitLab: So this is the website that I'm trying to deploy. It is based on React and it's using Gatsby in order to easily make some things. I'm going to go very deep into that. But essentially what I have here is I have my source folder, which contains the pages and everything that I'm using here. There's also this public folder that is generated when are running a specific command. So let me show you what I mean by that. So for example, if I go ahead delete a public folder and run Gatsby build. Gatsby will start regenerating this public folder. And essentially, what I'm trying to deploy here is the contents of the public forum or be pulled contain JavaScript files that are just small enough so that the load fast. They compile and make everything good for a production environment, but put it like that. So this is essentially my build process. I'm using Gatsby to generate this public folder. And essentially many JavaScript application nowadays have this tab as well. If you're really just hosting HTML files, like you can see this one here, index.html. We have no compilation process to put it like that. You don't need this, builds them. But because I needed and I want to automate it, we're going to go ahead here and on the root part of the website, I'm going to create a new file. And you have to be careful to name this file exactly as I mentioned it here. So the name of the file, we'll start with dot git, lab, dash, ci, dot YAML. So if you don't name it exactly as you see it here, this file will not be detected and the pipeline itself for not run. In this pipeline, I have here two simple stages. There's this build websites stage. In the second state that I have is to deploy to AWS S3. Let's start with the first one. So essentially what's happening here is this stage. And I've indented here two spaces just to show that everything is below build website, There's going to be part of the build stage. Additionally, because this is a project that needs npm to install dependencies and needs no JS to run mpm. I'm going to also use a docker image. So I'm going to specify an image width image and the name of the image will be node. We're going to use node in version ten. Now, when I have this, I can use the script block. And inside the script, OK, I can add any comments that I want. So the main command that I'm interested in is npm install. This will install all the dependencies that I need. Additionally, what we're doing is we need a tool, it's called FASB CLI. So we're going to install that as well. It's always a good practice when you have any tools. Just to shorter version, just to have an idea like what we are installing, especially if you're not installing a specific version. And then I'm going to do Gatsby build. So this is exactly the same command that I've executed locally. So I'm trying to replicate in my CI, CD pipeline the exact same steps that I would locally. This is practically the key to automation. As, as soon as you know exactly which commands you need to execute, you can easily put them inside a pipeline. So this is the bills state essentially. And the stages are created inside Docker images that don't have, they don't share information with one another. We also need a way to exchange this information. So practically, what we didn't discuss is to create an artifact, or essentially our public folder is the artifacts. So I'm going to define it under artifacts paths. So we're gonna define a path, this artifact that the path will be public won't have this path. So we know that when Gatsby build will be executed, this public folder will be created. It's not part of our git repository, so it's never there. And because we want to save it after the job completes, we have to specify it as an artifact at the Weizmann, the job ends, the Docker image gets destroyed and all the information is lost. So we definitely don't want that because we want to use this to deploy to AWS S3. This new want to keep things as separated from one another, one to have like a big job that does everything on a keep things as clean as possible. Also, the deploy tool as three, this will be part of the deploy stage. Afford the deploy stage, we're going to use an official image from AWS. It's called Amazon AWS CLI. We have to do something a bit different. So this image has a weird thing. It's called an entry point. I don't want to get too much into that, but it conflicts a bit with a way GitLab CI works with images. So we'll have to override that entry points. So in order to do that, I'm going to specify here the name. And we're going to also specify an empty entry point. So make sure that this looks exactly as you see it here. Otherwise you will get some weird errors when you're trying to start this. At this point, what do we have? Well, we have this AWS CLI and the AWS CLI allows us to interact with the AWS Web Services. But this time we're not using the interface. This is something that will be due manually. We're using this command line interface to practically tell S3, Hey, here are some files, host them for us, okay? Just to make sure everything worked properly, going to output here the version of AWS, and this is the name of the program, so it's going to be simply AWS. And what we're doing here is I'm trying to copy all the files. So practically we have here AWS. S3 is a service that we are trying to use. Seeing here, copy public. And you can see here that we're referencing this artifact that we have published here. So when this Docker image will be started, this folder will be also available there. Otherwise, if I don't specify it here as an artifact is not available here either. In the entire thing will not work. What we're doing here is we have to specify the path. So the path in S3 start with S3 slash slash. And then we'll have to specify the name of the bucket. I. Typically we could enter here the name of the bucket as it is. I don't like to have like things that give any information about the environment itself in the pipeline. For that reason, I'm going to use here an environment variable. I'm going to simply name it as S3 bucket. Make sure you put a dollar sign in front obeyed. Otherwise it will not be recognized as variable. And we're also interested in copying all the files as you saw here in the public folder. There are a lot of file, so every day or subfolders and we don't want to copy or specify on file. So for that reason, I'm going to use here a flag called recursive. There's still another thing that I would like to do just to feel a bit more comfortable. Probably it's not required, but I just want to start every time with an empty state of the bucket. I want to make something like AWS as three. And I want to remove practically everything that is inside the bucket. Before I add new files. For that reason, I'm going to simply specify here remove, and I'm going to also use this recursive flat. So this is essentially what we're doing here. We are using this official Docker image from AWS, outputting the version, we are simply deleting everything that is inside the bucket just to make sure that we don't have any conflict. And then we're copying the entire contents of the public folder. This is how the pipeline looks like, but it doesn't mean that it will work.
9. Generating AWS user credentials: Now what happens here is that we need to tell AWS CLI like who are we? Which, where's the bucket? Which region is the bucket, and so on. So there's still a level of configuration. And in order to finish that configuration, we have to go back to AWS. This is the main bucket that is hosting the website. And you will see here that we have defined this region. Typically what I recommend is that you select a region that is closer to you or closer to the intended audience. But it doesn't really matter. This has been automatically selected for me because I live in Europe. And this would be like the closest region that I have and I'm interested in is remembering which region I am. And this is like the code for that region. So I'm going to copy this and I'm going to go to git lab ci and we need to specify some variables just to help AWS CLI with a few things from this left menu, you should be able to see here something like settings, CICD. You will see here a block of variables. I'm going to add here a variable, and this variables will be available to the job itself. So if I start typing something like AWS will always see a few variables and we're going to use all of them. So first of all, I'm interested in the default region. The default region that I want to use this US Central one. So I'm going to simply add this variable, initially going to specify two other variable. Going back to AWS, we have to use a service called IAM. This is for identity management. Here in the IAM dashboard, we're going to click here on users. And we're going to create a new user that only has access to the S3 buckets. Let's call this user GitLab CI. This will help us identify what is this user supposed to do or what, where are these provisions used? And very importantly, you need to select here programmatic access. So this gives us access to the AWS CLI. This is exactly the tool that we have inside preeclampsia. I'm going to click Next on permissions, and I'm going to go the easy path of attaching an existing permission. So if I search here for S3, I will select this permission, Amazon S3, full access. This permission means that you're giving this user access to all your buckets. And essentially the user can delete all the buckets and so on. I'm just using this permission because it's just demonstrating the principle. But if you have like a little buckets that contains sensitive data, it may be wise to create your own policies that restrict access to only specific bucket. Going to click here on next. Don't have any tags. And I'm going to simply go ahead and create this user. As soon as you create this user, you will see here that you have like an access key ID and also a secret access key. And I'm showing you just to have an idea like how they look like. I'm going to remove this user just after recording this tutorial. So in, just in case you're wondering why I'm showing you this secret here. What I'm going to do next is I'm going to copy here the access key ID, going GitLab CI and add a new variable. And this variable will be starting here with AWS. And you can see I'm using AWS Access Key ID. This is a special name and this variable will be automatically picked up by the AWS CLI when you're executing this. So all the variables will be in the environment variables and AWS. We'll look into, hey, is there a variable called AWS Access Key ID? And I will use that variable in order to establish who is trying to use AWS CLI. And the same goes with the secret. I just want to make sure that I copy the entire secret. And variable AWS and paste here the value as well. And I'm simply added. Essentially what we did is to establish a connection between our AWS account, the resources that we are trying to access, in this case, S3 and GitLab CI, while at the same time giving only a limited access to this user. So this user will not have access, for example, to Use the management interface, but through the CLI, it's possible to do many things, but they're only limited to the bucket. Practically GitLab CI will inject this variable. So I'm going to show you in a bit how that works.
10. Running the GitLab CI pipeline: So now that we have our pipeline in place and my hope that everything is good, otherwise we'll debug it later. Cannot simply committees and say add pipeline. And I'm going to push the changes were soon as I did that. If I go back to the project page, you should be able to see something like this here, like pipeline is running in originally. If you don't see it here or something is happening, you can go here to CICD pipeline. This is the first pipeline that is currently running, and you'll see it has two stages. So the first stage is simply the build stage, and the second stage is the deployment stage. See here the job build website has started. So if you want to see exactly what's going on, can simply click on it. It'll show you're like what's doing currently. It's practically starting this node Docker image. After this has been started, it starts going through the commands that we have. So I'm gonna go here to the overview page. I'm going to leave it for a few minutes to run. Typically shouldn't take more than two or three minutes. Here, coming back a few minutes later, you're looking at your pipeline. In this case, something went wrong, so that's not a problem. It's going to be a good example of trying to understand like what's going on. And anytime you're writing any scripts, things may go wrong. And what happened here is you can see the first part with the belt that work without any issues. So we'll see here that all the commands have been executed, including gets rebuilt. And we can even here, take a look at a job artifacts. So if you click here on Browse, you will see here that we have a public folder to practically contains the entire website. But we doubt, though, for example, a good lab CI pipeline and things like that. So only the public folder has been added here. So that definitely looks right. Now let's see what happened with the second part of the pipeline that is to deploy to S3. And I cannot stress how important it is to have this ability of looking over the console logs and to try to understand like what's going on here. So we'll see in this step and in this case typically the last thing that failed is also the reason for our, all our troubles. In this case, you will see that no AWS is running in the sense that the CLI is available it right here, which is the version. So that's a first step. Okay, we know that we have the right tool. And then as soon as we try to do something, so for example, we try to remove all the files from the bucket. We'll see here something like invalid bucket name and says empty. So essentially it says, hey, the bucket name is empty. So it is empty because I was a bit fast when trying to do is, and I have forgotten to define this variable. So as you remember, we defined other variables here in Settings, the ICD, but I didn't really find the bucket name. This is also variable that is required here. So I'm going to simply click here on Add variable. And the way you name it, it's totally up to you. It's not one of those variables that really matters how you call them. It just, they have to match with what you're using in such a script here, the value that I'm using is this one. So this is the name of the bucket. So normal, simply click here on Add variables. And because it hasn't been a problem with the pipeline script itself, I can simply go ahead here on the pipeline, on Deploy job and click here on this retry. And you can even follow along if you click now, you'll be able to see exactly what is happening. This only took a few seconds to run. I will see this time the job itself has passed, so everything is looking properly. Essentially, we have removed everything and it's telling you exactly what has been removed and then starting uploading. So it will go through each individual file and upload. And so from just by looking at a number of the files that have been uploaded here does look like, like everything worked properly. We can go back to our domain here and click on the refresh button. And you should be able to see the website. So this is the website that I was trying to deploy. It's also a good idea like to check to see if all the pages are working properly. This is it, this is how it is supposed to work. We now have everything set up through our continuous integration pipeline here.
11. The process for making a change: Let's make sure that we can make also a small change. So I'm going here inside the ID, I'm going to click on the source code, kinda go to pages index.html. And instead of high people are going to say something like hello world. Very small changes like indicates how easy it is later on to make changes and deployed. And so I'm gonna say here like changed message. And we'll push. And of course again, the pipeline is responsible for ensuring that I didn't break anything. So just as important is also to build process that will verify again if anything goes wrong. We'll also send you an email notification if something didn't work out. So probably you can just make your changes and continue doing something else without worrying too much about this thing. So this is like the power of automation altogether. Just a few minutes later the pipeline has been successful. Let's go back to the website. It says high people, we refresh. And now it says Hello World. This is what it means to have a simple but very powerful continuous deployment pipeline in place simply takes a change that you have and the place them to your infrastructure.
12. Conclusion: Since we're coming to the end of this tutorial, let's do a small recap of what we did so far. Going back to the AWS services, we can look back into S3. S3 we have essentially what our three buckets. So one of them is the main bucket with www and the domain name that contains all the files that we're using in the project. And essential for this, we have specified a few things, a few permissions here in regards to the public access. But also like this additional configuration for the bucket policy that allows essentially anyone to get information from here. And what I typically recommend is that you don't store any other folders inside here. So essentially you could have a sub folder if you go to your configuration for properties. And you can specify, if you're looking here at static website hosting, you can easily specify it in a subfolder. So we could have something like public slash index.html. That would work. But the question is, what would you like to have on the root part? Because that theoretically still accessible. So this is something that I don't recommend that you store anything else inside here. It just for security reasons altogether. Part from the permission things in the properties we have also set up here some server access logging. And this is the part with Access Logging. And as you remember, we have used another bucket nor to store data access logs to take a bit until the logs are available. So typically wait 24 hours to see something inside the folder. And the other bucket without the www is simply there to create this reader. Ok, So inside here the DNS settings. You'll see here I've created this alias record. Pretty similar. You could have created a CNAME record. My understanding I'm not an expert by any means. My understanding is that a CNAME, we'll do another DNS lookup. So for that reason, alias record is typically faster. The way I did it here is pretty similar. Before DNS, I'm using Cloudflare. They have like a very powerful interface and also prepare for caching and many other mechanisms. Since here the service for registering domains has allowed me to directly added. This didn't need anything more advanced than this one. Since we have established how to upload files to S3 and how to practically link as 32 or domain name. In the second part, we have looked at building this pipeline. So essentially the pipeline just takes any build process that you have if you have one. And in the second part, it uses AWS CLI to automatically deploy any files that you have to S3. So essentially, you don't have to log back to the S3 interface. And especially if you're already using Git for your workflows, may be much faster solution. Thanks for sticking around until the end. I know that this has been a long tutorial and hopefully have managed to follow along. You will find a project files including the GitLab CI pipeline in the period description. I've integrated a continuous deployment pipeline in this example to demonstrate to you how easy it can be to automate manual tasks. See you next time. Bye-bye.