19

Deploying Ubuntu in the Cloud

Up until now, in each chapter, we've been working with an instance of Ubuntu installed on either a local virtual machine, a physical computer or server, or even a Raspberry Pi. We've learned how to deploy Ubuntu on such devices, and we've even gone as far as deploying virtual machines as well as containers. These on-premises devices have served us well, but the concept of cloud computing has already become quite popular, even more so since the previous edition of this book. In this chapter, we're going to take a look at running Ubuntu in the cloud. Specifically, we'll deploy an Ubuntu instance on Amazon Web Services (AWS), which is a very popular platform for cloud computing. While we won't go into extreme detail on AWS (it's an extremely large and complex platform), you'll definitely get a feel for what it's like to deploy resources in the cloud, which will be more than enough to get you started.

This exploration will involve the following topics:

  • Understanding the difference between on-premises and cloud infrastructure
  • Important considerations when considering cloud computing as a potential solution
  • Becoming familiar with some basic AWS concepts
  • Creating an AWS account
  • Choosing a region
  • Deploying Ubuntu as an AWS EC2 instance
  • Creating and deploying Ubuntu AMI images
  • Automatically scaling Ubuntu EC2 deployments with Auto Scaling
  • Keeping costs down: understanding how to save money and make cost-effective decisions
  • Taking the cloud further: additional resources to grow your knowledge

Since cloud computing is something of a different mindset than we're used to, we'll first go through a few sections that are dedicated to helping us understand the difference, as well as some of the considerations we should make before choosing to implement Ubuntu in the cloud. In the next section, we'll explore how the concept of cloud computing differs from on-premises hardware.

Understanding the difference between on-premises and cloud infrastructure

As mentioned at the very beginning of this chapter, we've been solely utilizing on-premises Ubuntu installations thus far. Even if we're running Ubuntu on a virtual machine in our data center, it's still considered an on-premises installation even when it's not on physical hardware. In short, an on-premises installation is something that resides locally with us, regardless of the type of server that serves as the foundation.

The first difference when it comes to cloud computing is somewhat obvious: it's the exact opposite of a resource being on-premises. With a cloud instance of Ubuntu, it's someone else's hardware that it runs on. Most of the time, we won't know what kind of server a cloud instance is running on—when we subscribe to the services of a cloud provider and pay a fee to run a server on that platform, we're able to access the operating system just like we would a virtual machine, with little knowledge of the underlying data center. Although utilizing a cloud instance will have some sort of recurring cost, we don't need to worry about monitoring hardware components nor replacing failed physical devices. With the cloud, that becomes someone else's problem.

I could actually end this section right there, as knowing the difference between on-premises and cloud is literally that simple (at a high level). But it also constitutes a change in mindset too, as well as how you manage cloud instances.

There are several cloud providers you can choose from, with AWS, Google Cloud Platform (GCP), and Microsoft Azure. Those are three very popular platforms. There are also Virtual Private Server (VPS) providers as well, such as Digital Ocean and Linode, among others.

Amazon also has a VPS service available as well, which they refer to as Amazon Lightsail. The concept of cloud computing has become more complex, since you have a variety of different services you can choose from.

First, let's understand the difference between a cloud service provider and a provider of VPSes. This distinction is rather complicated nowadays because the line between them seems to blur more and more as time goes on. Essentially, a cloud service provider such as AWS, GCP, or Azure provides you with a full menu of services, not just servers. This includes (but is definitely not limited to) services such as DNS, database instances, configuration management, software-defined networking, and more. AWS, for example, offers a service called Route 53 that acts as a managed DNS service, and it allows you to not only configure DNS for your cloud network but even register domain names as well. AWS even offers a service for hosting servers to act as the backend infrastructure for online multiplayer games, which they call GameLift. In addition, cloud providers will also provide a managed service for running Kubernetes, so you won't have to manage the underlying cluster yourself. Other cloud service providers will also give you a full menu of services, often with different unique marketing terms.

VPS providers are very similar to cloud service providers in that they also offer "cloud" servers for a fee, but often with fewer services available to you and simpler flat pricing. For example, while VPS providers will all give you the ability to create an Ubuntu server on their platform, they won't typically have a service you can utilize to register domain names. Basically, their "menu" of available services is stripped down quite a bit from what full cloud providers will offer. However, as I've mentioned, the line between cloud and VPS providers blurs more and more, as VPS providers are starting to offer services that until recently were only available from cloud providers. For example, both Digital Ocean and Linode offer a managed Kubernetes service on which you can run containers, which previously was offered only on cloud platforms. VPS providers now also offer object storage as well, another service they didn't use to offer. Amazon now offers a VPS service of their own with Lightsail, for those of you that want to create cloud servers from a simpler service.

So, which should you choose? Should you sign up with a VPS provider such as Digital Ocean, Linode, or Lightsail? Or should you choose a full cloud provider such as AWS, GCP, or Azure? The decision comes down to why you want to create cloud infrastructure in the first place, and the features you desire to take advantage of. If you compare each offering, you'll see the features they offer to you, and you can choose according to which fits your use case best. Make sure to not only consider the features you need right now but also features you may need in the future.

Perhaps the most important question to ask right now is whether or not creating cloud resources is appropriate for your goals. That's exactly what we'll explore in the next section. We'll also explore some of the differences in mindset when it comes to cloud computing as well.

Important considerations when considering cloud computing as a potential solution

Before choosing to sign up with a provider, it's important to first make sure that creating cloud resources is a good idea for you or your organization in the first place. Often, IT professionals can get so excited when it comes to a new trend that they may make the mistake of trying to use such a service even when it doesn't make sense to do so. Above all, as an administrator, it's important to utilize the best tool available for whatever it is that you wish to accomplish, instead of using a technology just because you're excited about it. Cloud computing is awesome for sure, but for some use cases, it's just not a good fit. This is similar to containers as well: containerization is an exciting technology but some applications just don't run well on that platform. It takes trial and error.

There are some considerable benefits when it comes to cloud computing. When it comes to physical servers, the hardware will fail eventually. It's not a matter of "if," it's a matter of "when." All hardware will fail eventually. And even if you have hardware that doesn't end up failing in the short term and lasts for a long time, it will be made obsolete by more powerful hardware that is more power-efficient. When it comes to managing physical servers, you'll need to replace the hardware eventually.

This is also true when it comes to cloud computing; the hardware such services run on will need to be replaced whenever it fails or becomes obsolete (whichever happens first). The difference is that when that happens, the liability on you (the administrator) is greatly reduced. You won't have to order a new server, replacement parts, or even pay attention to the hardware at all. It's solely the responsibility of the cloud service or VPS provider to keep track of that.

The trade-off, though, is potentially cost. Why I mention cost as a "potential" trade-off is because whether or not it's cheaper for your organization to purchase physical servers or pay a monthly fee for servers in the cloud comes down to which offers a better Return on Investment (ROI). To better understand this, consider an organization that utilizes only on-premises hardware for their data center with no cloud resources being used at all. Let's also assume that every 3 years or so, they have to replace some of the more critical servers with newer hardware; and every 5-10 years the lesser-important servers are replaced. There's also a need to pay for full-time administrators with specialties in managing physical hardware as well as maintaining a cooling system and making sure a room is available to designate as a data center. Add all of this up—how much is it costing the organization on average?

With physical infrastructure, you're paying an up-front cost to purchase servers every time you need to do so. With cloud computing, you never have to purchase physical server hardware, but instead you're paying a fee each and every month for the privilege of utilizing cloud infrastructure instead. When you add up the monthly costs for cloud resources, how much would that cost the organization? Would it cost more than running physical hardware, or less?

One very important consideration here is storage. If your organization doesn't store much data, then storage costs won't really be a concern. Many companies are perfectly satisfied with employees utilizing something like Google Drive for shared storage and won't need cloud storage. Some organizations, especially those that develop software, have massive storage needs. For these companies, there could be tens or even hundreds of terabytes of data being stored, as well as the bandwidth costs for the data going in and out of the company. If you were to attempt to migrate such a large amount of data to a cloud server provider, you would no longer have to manage storage hardware, but your costs for cloud storage would go up dramatically and might easily be much more expensive than it costs you to continue to use physical hardware.

Another consideration is stability. It's often argued that utilizing a cloud provider will result in a more stable infrastructure. That makes sense, considering that by using a cloud provider you're no longer responsible for managing hardware. There's definitely some truth to the claim that cloud resources are more stable, but it's not quite that simple.

Cloud providers will often advertise a high level of uptime, often measured in "9s." For example, AWS offers a general uptime of 99.99%, as of the date this book is being prepared for publishing. That sounds great, doesn't it? Before you get too excited about a cloud provider's uptime claim, it's important to also know what exactly they count as part of that uptime. If an upstream provider, such as a backend internet resource, goes down and service is completely unavailable, they may not count that and continue to claim the same amount of uptime. Massive outages of cloud providers are not uncommon, and a major outage of AWS occurred in 2017 where Amazon's S3 service suffered a major outage due to one of their engineers mistyping a command. In that situation, many services throughout the internet were unavailable to customers. So while it is true that a cloud service provider is less likely to suffer an outage than you are to witness hardware failures, it's important to keep in mind that outages are still possible. I don't mention this to scare you or steer you away from cloud providers, but merely to underscore the importance of backups and automation to get back up and running quickly during a failure. We can't ever assume any service (our own, or otherwise) is bulletproof.

Automation is a very important consideration with the cloud. If your resources encounter an issue, it's a really good idea to have an automated means of re-deploying your important services. On a physical server, you can set it up exactly as you want it and take an image of the hard drive in case the server fails. Cloud providers offer you essentially the same service, giving you the ability to create images of your important servers so you can redeploy them in the future should you need to do so. If you do go with a cloud provider, make sure you keep regular backups as well as images. And be sure to keep a copy of at least the most recent backups locally outside of the cloud provider, because if the cloud provider itself goes down then you also lose the backup. I can probably better summarize this by advising you to not become over-confident in the stability of your cloud provider. Always assume your infrastructure will fail eventually, regardless of where it's located.

The warnings I gave around the stability of cloud providers are not intended to scare you away from using them, but instead to steer you toward maintaining good hygiene with the cloud, just as you would with physical infrastructure. Cloud providers actually provide you with all the tools you need in order to build a stable infrastructure that's easily reproducible and recoverable. If you utilize those tools effectively, you shouldn't have anything to worry about. We'll explore these concepts further as we go along, but you can go as far as to have cloud servers recover themselves when a problem occurs. It all goes into how you architect your solution.

In the next section, we're going to explore some concepts specific to AWS, so we'll have a stronger foundation of knowledge to use for building an actual cloud solution later on in this chapter.

Becoming familiar with some basic AWS concepts

As discussed earlier, AWS is one of several competing cloud service providers. For the purpose of this chapter, AWS was chosen because more than any other provider, the platform requires an administrator to adopt a completely different mindset when it comes to managing infrastructure. This different mindset is a healthy one even outside of AWS, so it represents a logical evolution at this point in our journey.

Up until now, we discussed server installations as essentially pets, meaning we want to keep them around, make sure they're healthy, and if something goes wrong, try to fix it. We want to keep our servers operational for as long as possible. We want to be able to rely on them, and that helps our organization—customers and clients appreciate using a website or service that is stable, with minimal or no downtime.

That last part, minimal downtime, doesn't change regardless of the mindset we use when managing our infrastructure. Downtime and service disruption is bad in this industry, and that's always going to be the case. The difference is what we do about it, and how we go about recovering from it. In fact, we can even try our best to automatically recover when we have a problem. If the customer never notices there was ever an issue, even better.

With AWS, it's best to consider our servers as disposable, not as pets. This may seem a bit surprising at first, but if we effectively use the tools we're provided, we can build infrastructure that is scalable. This concept in particular is known as Auto Scaling and is a very important aspect of AWS. With Auto Scaling, resources are automatically created and destroyed as demand increases and decreases. For example, let's say that your web server receives more visitors than normal, and its CPU is starting to max out. Auto Scaling would then bring up a new web server automatically, and with a load balancer, route clients between instances as needed. You can set the maximum number of instances that can be brought online, and then when the load decreases, the servers that were brought online to handle the load will automatically get deleted. This means that you will automatically have the number of servers in existence as you need at any given time.

Another level above Auto Scaling is Auto healing. Just as the name implies, auto healing means that if your server runs into a problem, it will automatically be disposed of and recreated. This is the ultimate goal of AWS, to have infrastructure that is not only scalable but is able to recover by itself. For example, perhaps you have a pair of web servers that handle requests from clients. One of them encounters some sort of issue and fails some sort of test that would imply that the server is unreliable. Such a test is known as a health check. With auto healing, a server that fails health checks is considered unhealthy and is deleted. With Auto Scaling, you also set a minimum number of servers for your application. If the number of servers falls below the minimum, then a new one is created to replace it. Depending on how you architect your solution, the customer may notice some degradation if the application is running on fewer servers, but that's only temporary. Everything will return back to normal when the new server comes online.

With AWS, Auto Scaling and auto healing are extremely important. I've seen many administrators make the mistake of not utilizing those features of the platform, and that should never be the case. Without such high availability features, you risk having your server go away at any moment. This may be a bigger problem than you think. AWS consists of physical servers all over the world, and just like any other physical server, hardware failures are possible. If your application is running on a physical host within an AWS data center that encounters a hardware failure, your server may get deleted when they go and replace it. With Auto Scaling, this isn't a problem. A new virtual server will be brought online to replace it.

But without Auto Scaling, this can result in manually having to rebuild your server. Don't worry though, we'll cover Auto Scaling in this very chapter, so you'll definitely understand how to implement it before we're done.

The concepts around high availability are not limited to AWS. Similar features exist on other cloud platforms as well. The main difference between competing cloud providers is the marketing terms they use for these features, but you can set up similar infrastructure on each. With AWS, they really focus on this aspect though, so it's important to learn. But even if you're not utilizing AWS in production at your organization, the concepts around being able to easily recover from disasters is still important and can still be implemented. If nothing else, you should at least consider implementing automation for rebuilding servers so you don't have to do so much manual work if a problem occurs.

Back to AWS: there are many services within the platform that you can use that will provide a variety of features. In fact, there are well over a hundred different services within the platform. Therefore, it's impossible for us to cover each in this chapter. It would be difficult to cover every service even in a book dedicated only to AWS. But don't let the number of services overwhelm you though, you'll only need to learn the services that are related to what you're trying to achieve with the platform. For example, if your organization doesn't develop multiplayer computer games, then learning the GameLift service will be of no benefit to you at all. In this chapter, we'll focus on the services required to get you up and running with a basic web server running in the cloud. The following services and terms will be discussed:

  • Virtual Private Cloud (VPC): A VPC is a higher-level abstraction of your overall cloud network and resources. Each of the servers and related services you provision will fit within a VPC. You can think of a VPC as your overall network. In your organization, you may have various routers, gateways, firewalls, virtual machines, printers, or other network-connected devices. Your organization's network is essentially a VPC in AWS, a software version of a complete network.
  • Elastic Compute Cloud (EC2): EC2 is the service within AWS that your virtual machines will run in. Individual virtual machines within AWS are referred to as EC2 instances. You can think of this service as the AWS-equivalent of VMware ESXi, Microsoft Hyper-V, Proxmox, or whatever virtual machine platform you're more familiar with. EC2 instances, just like a virtual machine, have memory and CPU allocated to them and run an operating system. We'll run Ubuntu in an EC2 instance before the end of the chapter.
  • Elastic Block Store (EBS): As you learn more about AWS, you'll notice that even the simplest component seems to have a marketing buzzword attached. EBS provides block storage, essentially the same type of storage we've been working with all along. So in a nutshell, an EBS volume is a hard disk. When you create an EC2 instance, the operating system for your server will run from an EBS volume, and you can set the size of the volume accordingly. We'll work through this later in the chapter.
  • Elastic Load Balancer (ELB): As you may be able to guess from the name, an ELB is the AWS equivalent of a load balancer and offers similar features. This allows you to have multiple EC2 instances serving your application, and you can create an ELB to route traffic between them. ELB is actually a feature of EC2 and not its own service.
  • Identity and Access Management (IAM): IAM is the tool within AWS that you'll use to create and manage user accounts, determine user permissions, and even create API keys that can be used to programmatically access and manage AWS. Basically, it's your one-stop shop for all things related to user privileges, regardless of whether the "user" is a human or a script.
  • Route 53: Although we're not going to cover Route 53 in this book, I recommend at least understanding what it is in case you need it in the future. If you do decide to utilize AWS in production, Route 53 will simplify the process of managing DNS entries and also registering new domain names. If your organization is a managed service provider, you may find yourself using this quite a bit.
  • Simple Storage Service (S3): Amazon's S3 service is another offering we're not going to cover in this chapter, but it's a good idea to know that it exists and what it's for, in case you find a use for it later. S3 is actually a very popular service, and it provides object storage. Object storage is a new type of storage that is different than a disk (virtual or physical) that you add to your server, format, and mount. While you can still mount S3 on your server, it doesn't have a filesystem (such as ext4 or STON), nor does it understand permissions. It's simply a name-object pair, where you store files, and they have a name. With S3, you create "buckets," and each bucket can have files stored inside. Each bucket name must be unique. S3 is very useful if you want to make downloadable files available to your clients or store backup files.
  • Elastic Kubernetes (EKS): In the previous chapter, we covered Kubernetes and even set up our own cluster. AWS has its own Kubernetes solution, called EKS. Although we're not going to cover it in this book, it's worth considering if you want to continue to use Kubernetes and have your containers running in a managed service, rather than managing your own cluster. EKS combines Kubernetes with the flexibility of the AWS platform, so it's a very useful service to consider.
  • Security Groups: Access to many AWS resources from the public internet is disabled by default, and security groups are used to determine what is able to access a resource within AWS, and you can allow or disallow access by IP address as well as port. With regard to EC2 instances, outbound access is allowed by default, but every port is blocked inbound. You can create a security group that allows specific IPs to access the instance, which increases security. We'll see an example of this later.

Now that we have some basic understanding out of the way, we can get started and build an application in the cloud, running on AWS.

Creating an AWS account

As mentioned in the previous section, a VPC within AWS represents a high-level abstraction of your overall network. All of the resources that we create will run inside a VPC. Therefore, we'll need to create a VPC first before we can create an EC2 instance and deploy Ubuntu.

Before we can create a VPC though, we'll need an AWS account. Before this chapter, I typically advised you to use whatever hardware you have available in order to create Ubuntu installations to work with the platform. This time, we're going to utilize an actual cloud provider, which comes at a cost. While there are free components available for a limited time with a new account, it's up to you, the reader, to keep track of billing. We'll cover costs in greater detail later in this chapter. As a general rule of thumb for now, always use whatever the cheapest option is. If a free instance type is available, go with that. Of course, if you're intending to deploy actual resources for production use within an organization, then you'll want to choose whatever instance type is appropriate for the use-case. For our purposes, we're just learning the platform for the first time, so be sure to go with the lowest-cost resources available and delete everything when you're done.

Signing up for AWS

To get started, let's create an account. If you navigate to https://aws.amazon.com, you'll see an orange button on the upper-right corner with the label Create an AWS Account. It's possible that the layout of the page may change after publication, but you should see a button to create a new account somewhere on the page:

Figure 19.1: The AWS main page

When you click the button to create a new account, a form will appear asking you for basic information. An example of some of the fields you may be asked for is shown in Figure 19.2, though the exact information you may be asked for may vary. Fill out each field accordingly, then click Continue:

Figure 19.2: Signing up for a new AWS account

After you click Continue, another screen will appear asking you to fill out additional fields, such as your full name, company name, address, and so on. This process will also include asking you to provide credit card details as well, so proceed through each screen and enter the required information. At the end of the process, you'll see a selection where you can choose your support plan:

Figure 19.3: Choosing a support plan while signing up for an AWS account

If you are asked to select a support plan during the process, choose the one that makes sense for your use case. If you're going to be using AWS to create production instances for your organization, the Developer or Business Plan may offer additional value to you. If you're only going through the process to learn AWS and work through the examples in this chapter, choose the Basic Plan.

Once you've finished the process of creating your new account, it may take some time before your new account is ready. When it is, you should receive an e-mail saying that it's ready for use. After you do receive that e-mail, you'll be able to log in. There should be a button on the screen to sign in to the console, and then you'll see the following prompt:

Figure 19.4: Signing in as Root user

Here, you have a choice to log in as the root user or an IAM user. We haven't created any IAM users yet, so we only have a root user at this point. The root user is accessed by signing in with the same e-mail address that you've provided during the sign-up process. Enter that e-mail address in the prompt, and click Next, followed by your password on the next screen.

If all goes well, you should be logged in and see the AWS Management Console:

Figure 19.5: The AWS Management Console main screen

Now that you have access to the management console, you can begin using AWS. Before we start creating cloud resources, we should implement some basic security to protect our account.

Implementing basic user security

Before we continue any further, there are some very important security best practices we should employ regarding the ability to authenticate to our AWS account. Although it's very likely that our new account was created as a test account for following along with examples in this chapter, we should make it a habit to always protect our AWS account, regardless of how important it actually is.

We can begin with protecting the root account, it's a common target for hackers. Specifically, we should enable two-factor authentication for this account. Doing so will make it much harder for an outside threat to access it, since they would need access to your second factor in addition to your password. Since we're already logged in as the root user at this point, we can set this up immediately.

In the management console, you'll see a search field labeled Find Services. If you already know the name of the service you would like to configure, you can begin typing its name in the search field, and if your query matches an available service, it will show it in the list. If you don't know the name of the service you'd like to use, you can click on Services at the top-left corner of the console, to see a complete list of the services available. For setting up second-factor authentication, we will access the IAM service. You can start typing IAM into the search field, and it should show it as an available option. Go ahead and click on it:

Figure 19.6: Using search within the AWS Management Console to locate the IAM service

When the IAM dashboard appears, you may see a security alert that complains about the root user not having Multi-Factor Authentication (MFA) enabled. Although enabling this feature is optional, I recommend you enable it.

MFA is critical for ensuring the security of any account that is important to your organization, especially an account for a cloud computing provider such as AWS. MFA will enhance the security of the account in terms of authentication, requiring an additional factor before a user will be able to access the account. The root account is the most critical account to protect in AWS, since it has full access to every available service. To enable MFA, click on the link that reads Enable MFA (or similar verbiage if the layout on this page changes):

Figure 19.7: IAM dashboard, with an alert that MFA is recommended to be set up

Next, click on MFA to expand it (if it isn't already), and then click on the Activate MFA button:

Figure 19.8: Setting up MFA (continued)

The next screen will give you a choice of which type of device to use to facilitate MFA. The default (Virtual MFA device) is a good one to go with if you don't have a physical hardware key, such as a Yubikey. If you have no other preference, choose the Virtual MFA device option and click Continue:

Figure 19.9: Choosing a type of MFA device to set up

To set up your virtual MFA device, you'll need to download a second-factor application to serve this purpose. Google Authenticator is a popular choice here, but I recommend Authy instead. Both are perfectly acceptable, but Authy also features a desktop app you can use, as well as the ability to recover your account if your primary device is not accessible for any reason. Authy is compatible with Google Authenticator, so you can typically use it with services that offer a Google Authenticator option. To continue, reveal the QR code, scan it with your phone app, and then type in two subsequent values generated by the app.

Finally, click Assign MFA to finalize the process:

Figure 19.10: Setting up the MFA device

Now that we have two-factor authentication enabled for our root account, we should stop using that account immediately. This is actually a best practice when it comes to AWS; it's recommended that you create individual accounts for the individuals that will work on your AWS account, giving them the permissions they need to perform the tasks they need to complete. We'll discuss the principle of least privilege in Chapter 21, Securing Your Server, but it doesn't hurt to start thinking about the concept now. For now, what we'll do is create an administrator account for ourselves that we can use in place of the root account. We can always use the new account to create additional users if we need to do so.

To create a new administrator account, we will again utilize the IAM console. Once there, you'll see a Users link on the left, and then you can click the blue Add user button to begin the process:

Figure 19.11: Setting up a new administrative user for AWS

The next screen will have you type the desired username, as well as setting Access Type. For the username, you can name the user whatever you'd like. For Access Type, we'll choose AWS Management Console access. Click Next: Permissions to continue:

Figure 19.12: Setting up a new administrative user for AWS

Next, we will set up the appropriate permissions for our user. The third icon, labeled Attach existing policies directly, is the first selection we'll make here, and then below that we'll place a mark next to the check box for Administrative Access, and then we'll click Next: Tags:

Figure 19.13: Setting up a new administrative user for AWS (continued)

We can skip the tags screen by leaving the fields blank and clicking Next: Review.

The next screen will provide us with an overview, and if everything appears to be correct here, we can click Create User:

Figure 19.14: Setting up a new administrative user for AWS (continued)

Finally, we can retrieve the password for our new user by clicking Show on the next screen, which will display a randomly generated password for the user:

Figure 19.15: Setting up a new administrative user for AWS (continued)

You can now log in to the AWS management console with the new user and the password that was provided. I recommend you use the new user going forward, as it's a good practice to not use the root account unless you absolutely have to. In addition, I recommend you follow the procedure to set up MFA as we did earlier, but this time with the new user.

Choosing a region

As discussed earlier, a VPC within AWS is the high-level abstraction of your overall network. You can have multiple VPCs, which is similar to the concept of managing several physical networks. In fact, we already have VPCs created for us in our account, so we won't need to create one. In the future, keep in mind that creating additional VPCs is an option, should you ever need to have more than one. In our account, we have a default VPC in each region, so choosing which one to utilize comes down to which region is most appropriate for our use.

For production use, you'll want to create instances in AWS that are as close to your customer as you can get. For example, let's say that the customers that your organization markets to are primarily located in the Eastern United States. There's a region available within AWS that is available that's labeled US East, so that would be an obvious choice in that scenario. You're not limited to regions within the USA though; there are regions available all over the world, such as in Germany, China, and Canada (among others). In a nutshell, you'll want to create resources as close to your customers as possible. If you don't have a preference, you can choose to utilize whichever region is closer to you.

Although it's beyond the scope of this book, AWS offers a service called CloudFront that acts as a Content Delivery Network (CDN) that you can use to make your resources available in various edge locations, that users can be routed to in order to ensure they're retrieving your content from a location closest to where they are geographically. For organizations that produce media content, this is especially valuable. If this is something that might benefit you, I recommend reading more about CloudFront.

In addition, there are often multiple availability zones within various regions, which allow you to get even closer to your target audience. For example, when it comes to the US East region, there are two availability zones inside it, one in Virginia as well as another in Ohio. Availability zones not only give us the ability to get another step closer to our customers, they also offer us additional options for redundancy as well. For example, if one availability zone goes down for whatever reason, you can route your customers to another. Availability zones have a specific naming syntax, which consists of both the name of the region as well as the availability zone within that region. Using the Eastern United States as an example again, the two availability zones there are labeled us-east-1 for Virginia, and us-east-2 for Ohio. Not all regions will have multiple availability zones, though. Canada currently only has one region with one availability zone: ca-central-1.

In addition to availability zones, there are also local zones, which are intended to allow you to set up resources even closer to your customers than availability zones are able to get. Local zones are a great choice if your application is sensitive to network latency, such as running a server for an online game. We won't go over local zones in this book at all, because this is a very new offering from AWS, and there are only two of them in existence as of the time this book is being prepared for publishing. Amazon intends to add additional local zones in the future, so there may be more of them available by the time you're reading this. If your organization offers a service that is sensitive to network latency, this may be a feature you'll want to keep up to date on as they roll it out to more locations.

For now, the only consideration is which region will benefit your customers by being as close to them as possible. When it comes to following along with the examples in this book though, choosing a region closest to you geographically is a good idea.

Now that we've selected our region, how about we create an actual Ubuntu instance in the cloud? That's exactly what we'll do in the next section.

Deploying Ubuntu as an AWS EC2 instance

With a great deal of discussion out of the way, it's time to create an actual Ubuntu deployment in the cloud. This will allow us to see the AWS service in action and give us some working experience with the EC2 service. This requires two individual steps: the first to create a required IAM role, and the second to create our instance. Let's first make sure we understand the requirements of the IAM role, then we'll set up the role and then create our new instance.

Setting up an IAM Role for Session Manager

Session Manager is a service within AWS, which we can use to access a command prompt for our instance. It's actually part of Systems Manager and not its own service. If you want to access Session Manager, you will need to search for Systems Manager, and you'll find Session Manager as a service underneath that. You'll see this shortly.

Why should we use Session Manager? Just like with any other Linux server, we can still use OpenSSH to connect to the EC2 instance we'll be creating, just as we have many times while working with non-AWS instances throughout this book.

There's nothing wrong with using OpenSSH; with the right settings it can be a very secure option. In fact, we will explore methods of better securing it in Chapter 21, Securing Your Server. With AWS, we can use Session Manager as an alternative to OpenSSH, and it's a worthwhile alternative to learn that offers additional security in that its backend security is not something we have to manage ourselves. In addition, we can control access to it through the AWS console as well.

By default, Session Manager is not accessible at all. It requires a specific package to be installed within Ubuntu Server for it to work, and it also requires specific permissions to be enabled. The required package for Ubuntu is preinstalled by default, so the first requirement will be automatically taken care of for us immediately when we create our instance. If you have an existing Ubuntu Server in AWS that was set up before June 27th of 2018, you will need to install the required package manually:

sudo snap install amazon-ssm-agent --classic

If you don't have an existing AWS account with Ubuntu Server instances created before the package was included by default, then you're all set here. As you can see from the command above though, the amazon-ssm-agent package is distributed as a snap package, which is a special kind of package we've discussed previously in Chapter 3, Managing Software Packages.

For the second requirement of adding permissions, we'll need to create an IAM role to allow the EC2 instance we're about to create to communicate with the Session Manager service. When I mentioned earlier that Session Manager isn't accessible by default, this is why—it's missing the permissions needed until we add them. To add the required permissions, we'll access the IAM service within the AWS console, the very same one that we used earlier to create a user account for ourselves. IAM itself has many tricks up its sleeves, more than just simply allowing us to create users. It also allows us to create IAM roles, which give us the ability to add permissions to entire objects. For example, we can create a role with the permissions that are required, and then we can attach that role to any EC2 instance to immediately give it the ability to be connected to by Session Manager.

Let's get started and set up the required IAM role for Session Manager. Return to the IAM section of the AWS console that we've worked with a few times now, and we'll create the required role.

In the IAM menu on the left side of the window, click on Roles, and then click on the blue button labeled Create role:

Figure 19.16: Creating an IAM role to enable Session Manager

On the next screen, make sure AWS service is selected, and in the menu below that, choose EC2 as the service. Click Next: Permissions to continue along:

Figure 19.17: Creating an IAM role to enable Session Manager (continued)

Next, we are able to attach policies to our role. In the search field next to Filter policies, we can type a keyword to narrow down the list, and then click on a checkbox next to a policy we wish to attach to our role. A full overview of all of the built-in policies and what they're for is beyond our scope, but as a short summary, each service within AWS has pre-built policies that can be attached to a role, which allows access to various features. Specific to our needs, we will add the AmazonSSMFullAccess policy to the role we're creating.

The purpose of this will become clearer when we create our EC2 instance, so for now, click Next: Tags to continue on:

Figure 19.18: Attaching the AmazonSSMFullAccess policy to our role

The next screen that will appear will give us the ability to add one or more tags. We'll skip this for now, but you can feel free to add any tags you'd like here. Tags allow you to attach information to a resource and aren't limited to IAM roles. You can add any descriptive information you feel is pertinent, if you wish. Tags are simply "key: value" pairs, so there's no specific naming scheme to follow here. Add tags if you wish to do so, and when you're finished with this screen click Next: Review.

The final screen will give us a review of the settings we've chosen so far, as well as an option to name the role, and add a description if we wish to do so. Although it's optional, I recommend giving the role a name, to make it easier to identify later. When you're finished, click Create role:

Figure 19.19: Adding a name and description to our role

When it comes to setting up our IAM role, we're all set—the role has been created and we can go ahead and use it. Next, it's time to create our Ubuntu instance.

Creating an Ubuntu Server instance in AWS

Now it's time to see our work come together and create our Ubuntu instance. In the AWS console, we should first access the EC2 service to get started. You can easily find any service by typing it into the search box within the console, so if you start typing EC2 into that field, you should see EC2 on the list. Alternatively, you can click on Services in the top-left corner of the console window. After that, click on Instances on the left side of the screen. After doing that, you'll see a screen with a button labeled Launch instances:

Figure 19.20: The main window of the EC2 service

Normally, the Instances section of the EC2 console will show us a list of all of our server instances, but unless you've read ahead, we don't have any yet so the window is blank. When you click on Launch instances, you'll see various operating systems on the list, and there are quite a few. If you start typing Ubuntu in the search field, you should see an option for Ubuntu 20.04, similar to Figure 19.21:

Figure 19.21: The Ubuntu option for EC2

Click on the Select button to proceed. Once you do, you should see a list of instance types similar to Figure 19.22:

Figure 19.22: Choosing an instance type

On the Choose an Instance Type screen, there will be quite a few instance types from which to choose. I've shrunk Figure 19.22 down to show the first two options, but there are many more. I selected the t2.micro instance type, and I recommend you do the same. It's eligible for the free tier, which is a special tier you'll have access to within the first 12 months of the age of the account. You most likely wouldn't choose this instance type for a production server, as it will be quite slow—it only has 1 CPU and 1GiB of memory. And it's a burstable instance type, which means the speed fluctuates based on usage. It's able to burst to take care of busy workloads, but its ability to do so depends on CPU credits that it earns in a particular time. A full explanation is beyond the scope of this chapter, but if you're going to use AWS in production, it's a good idea to read about the various instance types available. Although you don't see it in the screenshot, you should also see the cost on this page as well. But again, we'll utilize the free tier for now. Choose t2.micro as the instance type, then click Next: Configure Instance Details.

The next screen that appears will allow us to choose individual details about our instance, and we'll have quite a few options to choose from. We'll accept the defaults for most of these options:

Figure 19.23: Setting options for our new EC2 instance

The first field gives us the ability to create more than one server, otherwise by default we will create a single server each time we launch an instance. If you do decide to create multiple instances, remember to keep track of them and delete them when you're done, so you don't get an actual charge on your bill.

We can also choose the Network and Subnet for our instance as well, but we'll leave the defaults for that. With advanced usage of AWS, you can create multiple public and private networks and have the EC2 instance utilize specific ones. We won't work on configuring that in this chapter, but keep in mind that it's a possibility to do so.

Skipping ahead a bit, I did change the IAM role option, and I set it to the IAM role that we created earlier. The AllowSSM role that we set up provides access to Session Manager, so by attaching this role to our instance, we're ensuring that we'll be able to use Session Manager to connect to it. If we omit this role, then connections to the instance via that service will fail. We'll see Session Manager in action shortly. But for now, scroll down a bit further as there is an additional option we'll want to set up:

Figure 19.24: Adding user data for the EC2 instance

At the bottom of the same screen, we see an option to add User data. Sometimes overlooked, user data is a very powerful feature of AWS. The name can be misleading, we're not adding information about a user account here. What it's actually used for is adding commands that we want to run when the instance is being created. I've added the following code to the User data field in my case:

#!/bin/bash
apt update
apt dist-upgrade -y
apt install -y apache2

If you think the code resembles a Bash script, then you're correct—it is. I added four lines of Bash statements to the User data field, to have some commands run automatically. The code should be relatively straightforward: I have it set up to update the repository index, then perform a full system upgrade.

This is important; we always want our servers to start with the latest patches available. As a proof of concept, I added a statement to install Apache. Notice that I included the -y option to all of the apt commands. This automatically responds "yes" to any question apt may ask, since we don't have a display hooked up to this server and are unable to answer questions ourselves. Without that option, the user data will fail to apply. Anyway, click Next: Add Storage to continue. On the next screen that appears, we'll set some parameters regarding storage:

Figure 19.25: Adding user data for the EC2 instance

The most important decision on this screen is how much storage to provide our EC2 instance. I chose 16 GiB in my case. You'll want to make sure that this is large enough to accommodate whatever it is you intend to use the server for. You can also click Add New Volume, to add secondary storage. If you do, then you'll need to format and mount this storage manually after the instance comes online, similar to how we added additional storage volumes back in Chapter 9, Managing Storage Volumes. Refer back to that chapter if you do decide to add additional storage and need a refresher on how to format the volume and get it mounted. Go ahead and click Next: Add Tags to continue.

The next course of action will be to add tags, if we wish to do so:

Figure 19.26: Adding tags to our instance

Adding tags is optional, but I recommend you at least add a tag called Name and set the value to whatever you would like to call your instance. This makes it easier to find in the list and is a good habit to get into.

There are no specific requirements here, so continue on by clicking Next: Configure Security Group:

Figure 19.27: Configuring a security group for the instance

Security groups, as briefly touched on earlier in this chapter, give you the ability to allow additional communication to occur to the instance. By default, outbound is completely enabled. Anything from within the instance attempting to access the outside internet will be allowed. The reverse isn't allowed though; nothing is allowed to access the instance from the outside until you allow it.

Let's spend some time and carefully consider what we allow here, because security groups are a critical consideration. In the example screenshot, I've added a random IP twice, the first for accessing SSH and the second for Apache. Standard practice would be to add the external IP address for your internet connection here, and only requests coming from that IP are allowed to communicate to the instance via that port.

If your instance will serve a website to the public internet, then the IP address you would add is 0.0.0.0/0. If you allow a port to be accessed by 0.0.0.0/0, then that means you're allowing every IP address to be able to connect to that port. In the case of hosting a public website, then that is likely what you'll want. But the general rule of thumb is to only allow specific IP addresses to connect to a port on your instance, unless you have a very important and unavoidable reason to allow public access to it.

When it comes to port 22 for OpenSSH, you should never allow public access to that. In the screenshot above, let's assume 172.11.58.105 is the IP address for my home office. I added /32 to the end of that IP address, which signifies that it's not referring to a network but instead a specific IP address. It's standard practice to allow the IP address of your organization and/or your home office to access OpenSSH, but nothing else should be able to do so. This keeps OpenSSH away from hackers and outside threats but still gives you the ability to allow public connections to something like Apache, if you want to do so.

In my case, I limited access to Apache as well as OpenSSH. It's a good idea to be very restrictive when it comes to allowing things from the outside to access your server. Always default to "no" unless you have no other choice.

With the security group created, the next screen will give you an overview of our selections so far, and if everything looks appropriate, click Launch:

Figure 19.28: Preparing to launch an instance

Although the button in the previous step was labeled Launch, the instance won't launch yet—a very important screen will now appear. At this stage, you'll create an SSH key pair to access your instance. We'll be using Session Manager to connect to it, but it's a good idea to create a key here. In fact, you can't continue until you choose to create a new key and download it or select an existing key. Since we haven't created a key yet, type a name for the key pair and click on the Download Key Pair button. Be sure to keep the key in a safe place: you'll literally never be able to download it again, this is your only chance to do so. If you lose it, you cannot retrieve it. After you've downloaded the key, click Launch Instances to continue:

Figure 19.29: Creating an OpenSSH key pair for the new instance

With regards to the key file that you'll end up downloading, you can use it to connect to your instance via OpenSSH with a command similar to the following:

ssh -i /path/to/key.pem ubuntu@<Instance Public IP>

For me, if I add the path of my key as well as the public IP address listed for my instance, the command becomes this:

ssh -i /home/jay/downloads/jay_ssh.pem [email protected]

Again, we'll use Session Manager shortly, but it's nice to have another method of accessing our instance if Session Manager ever fails us for some reason. At this point, we should see the new instance in the list of EC2 instances in our account, and it will take some time for it to be ready for use:

Figure 19.30: The new EC2 instance listed, and in the process of being provisioned

In Figure 19.30, the Instance State field shows a status of pending, which means that the instance is being prepared and after 5-10 minutes or so, it will change to available. Once it does, we will be able to connect to our instance. To do so, right-click on the instance and click Connect, and the following window should appear:

Figure 19.31: Choosing a method to use to connect to the EC2 instance

As you can see in Figure 19.31, I chose Session Manager as the connection method, and I recommend you do the same. Then, click Connect to attempt to initiate a console window with a connection to our instance. If successful, you should see an actual command prompt just as you would if you used OpenSSH:

Figure 19.32: An active Session Manager connection to the new EC2 instance

In Figure 19.32, I entered the following command in order to display details for the version of Ubuntu that was deployed in the instance:

cat /etc/os-release

The /etc/os-release file is included with all Ubuntu installations, and as you can see from the output, it contains some information regarding the version of Ubuntu we're running. That command was entered directly into the Session Manager window, to show that the connection is actually working and we can now configure the instance right from within our web browser!

If you recall, we added User Data earlier, and that included a command to install Apache. If you enter the public IP address of your EC2 instance into a web browser, you should see the default Apache web page:

Figure 19.33: The Apache default web page running on an EC2 instance

Congratulations! You've successfully deployed Ubuntu Server to the cloud, and now have an actual web server running on it. That's all there is to it. Using Session Manager is also simple; all you need to do to customize the server further is right-click on it, click Connect, and you can then continue to build the instance. That's awesome!

What's not so awesome, though, is when something happens to your server and you have to start over and rebuild it from scratch. In the next section, we're going to explore the process of creating an image of the server that we can utilize to deploy customized versions of Ubuntu.

Creating and deploying Ubuntu AMI images

Just about every cloud platform I know of includes some sort of feature that can be used to create images of the instance's hard disk. An image can be used to create copies of the original server, as well as acting as a starting point so if the server needs to be rebuilt, we won't have to start over from scratch. In AWS, images are known as Amazon Machine Images (AMIs). For all intents and purposes, there's nothing very unique about AMIs; if you've worked with disk images in the past, it's the same thing. When it comes to what you should include in an AMI, you can (and should) use your imagination here—anything you find yourself manually setting up or configuring while rolling out a new server is a candidate to be included in an image, and the more customizations you include inside the image, the more time it will save you later.

Let's see this in action and create an image of the server we've just set up. We should consider shutting down our server first, although this isn't required. Taking an AMI of a server that is shut down is preferred over doing the same on a server that is running. When the server is shut down, nothing is writing to its disk, so we don't have to worry about corruption if we're capturing an AMI in the middle of a critical operation. The likelihood of running into an issue while creating an AMI of a running server is very small, but I recommend shutting down the server if you can to be on the safe side.

In the EC2 console of AWS, you can right-click on the instance to access Session Manager, and then you can simply power it off from the command prompt:

sudo poweroff

In AWS, it can take a minute or two for an instance to power down. You can refresh the page after some time, and the status should change to stopped:

Figure 19.34: The Apache default web page running on an EC2 instance

Once the instance has stopped, you can right-click on it to begin the process of creating an AMI. Hover over Images and Templates and then click Create Image:

Figure 19-35: The Apache default web page running on an EC2 instance

Next, we can enter some details about our AMI. Give it a name and a description. This information will help others you work with understand what the image is for, and it can also help you remember why you've created the image later on down the road. Once you're finished, click Create image to continue:

Figure 19.36: Creating a new AMI

Believe it or not, that's all there is to it. The process of creating an AMI is very straightforward, with just a few steps. You should now see a confirmation screen, letting you know the image is in the process of being created:

Figure 19.37: Confirmation while creating a new AMI

If you click on the underlined text that contains the AMI ID, you'll be directed to the AMI section of the EC2 console, where it will show your image on the list:

Figure 19.38: Our newly created AMI, available for use

In the AMI section of the EC2 console, you should see the list narrowed down to just the AMI we created just now. We only have one AMI anyway, unless you created multiple AMIs for practice. At the end, the Status column should read available if the AMI is ready for use. If not, give it some time, and refresh the page later. Sometimes it can take a few minutes. But with regard to creating an AMI, that's it!

Now that we have an AMI, how do we go about using it? Well, that's even easier actually. Simply right-click on the AMI on the list and click Launch. You'll see the same launch settings we worked through earlier when we originally created the instance, but this time, we're using our own AMI instead of the one provided to us. And now, we have our own custom AMI of Ubuntu with Apache built in that we can use to simplify our process a bit. Keep in mind, though, that our original instance is still stopped. You can return to your list of EC2 instances and start it by right-clicking on it, then clicking Start, but you don't have to, we're going to work through a fun automation example shortly.

In the next section, we're going to take a look at the concept of Auto Scaling.

Automatically scaling Ubuntu EC2 deployments with Auto Scaling

If we maintain one or more servers for our organization, it's hard to predict sometimes what the demand will be on that server. In the case of a popular news site, some articles may be more popular than others, and if something goes viral online, then requests to our site can increase by orders of magnitude. In the past, keeping up with customer demand was a very tedious process, one that may result in having to purchase an entire new server with more powerful hardware. With our instance being in the cloud, we have more flexibility and can automate the process of bringing more servers online. And that's exactly what we're going to work on in this section.

Before we get started, keep in mind that we don't actually have a popular server in AWS; we only have a simple test server that's currently running Apache. We can simulate things to a point, but Auto Scaling is one of those things that requires a bit of practice to fully utilize. We will definitely get a working example here, though.

But another important thing to keep in mind is that the more instances we run, the higher the potential cost. We'll explore how to keep costs down in the next section, but as a general rule of thumb, delete whatever you're not using. As you've gone through examples in this chapter, we've set up our own EC2 instance. This is great: we were able to practice some concepts around AWS and put that to use. But if we leave something running that we don't need, we can have a surprise bill. It's a good idea to write yourself a reminder to delete everything in your test AWS account when we're done with the chapter, so you won't have to worry about that.

Continuing, one of the requirements of Auto Scaling is that we have an AMI ready that it will use to bring additional servers online. Since we've worked through creating an AMI in the previous section, we already have that requirement met. If you haven't already worked through the previous section, make sure you do so before we continue. The process of setting up Auto Scaling involves a handful of steps, and we'll work through each in their own sub-section within this chapter.

Creating a launch template

Earlier in the chapter, we walked through the process of creating a new EC2 instance. We chose the option to launch an instance, and then configured various settings within multiple screens we worked through. We chose Ubuntu as our platform, added user data, and set an IAM role (among other things). What a launch template does is allow us to automate these choices. A launch template gives us the ability to automate the entire launch process.

On the left-hand menu of the EC2 console, there will be a link titled Launch Templates. Click on it. Once you do, you can click on the orange button labeled Create launch template. You'll then see a form you'll need to fill out, where you select all the defaults for the launch template. There's no screenshot on this page, because it's quite long and won't fit on one page. Instead, I'll include the relevant options below, with a short description and a recommendation regarding what to set the option to:

  • Launch template name: This is simply a name for your launch template; set it to the name you feel is most appropriate. Note that this cannot contain spaces.
  • Template version description: For the description, you can add some details that you think are relevant to the purpose of the launch template.
  • Amazon Machine Image (AMI): Choose the AMI that you created in the previous section. It might be hard to find on the list, so you can copy the AMI ID (located in the AMI section of the EC2 console) and paste it here.
  • Key pair (login): When you created the EC2 instance earlier, it had you create an OpenSSH key pair. If you drop down this list, that same key pair should be available. Choose that same key.
  • Instance type: If you recall, we chose t2.micro as the instance type earlier. That's a good selection for this field as well, since t2.micro is eligible for the free tier.
  • Security groups: Earlier, when we added a security group, we set it up to allow OpenSSH and Apache. Feel free to choose that same security group for this.

Near the bottom will be an additional section you can expand to give you the ability to configure advanced details. Underneath that, you'll have an option to set the IAM role for the template. For this, choose the same IAM role we created earlier to facilitate access via Session Manager.

With all of those details set, click Create Launch Template near the bottom of this screen. Now we have our launch template created and configured, and we can use it as part of the Auto Scaling feature we're in the process of building.

Creating an Auto Scaling group

Our next requirement is to create an Auto Scaling group, which will be a shorter process than setting up the launch template. An Auto Scaling group is a logical group of instances that are related to the overall application. We will add our launch template to this group and use it to customize requirements such as how many instances to have online.

Back in the EC2 dashboard, you'll find an option for creating Auto Scaling groups in the menu on the left side of the screen, closer to the bottom. Once there, give it a name:

Figure 19.39: Naming the Auto Scaling group

Further down on that same screen, we will choose the launch template. Go ahead and do so, and then click Next:

Figure 19.40: Selecting a launch template for our new Auto Scaling group

On the next screen, you can leave the purchase option on its default, which is Adhere to launch template:

Figure 19.41: Creating an Auto Scaling group (continued)

Underneath the purchase option on the same page, you can leave the VPC selection on its default, and then add one of the subnets on the list of those that are available. We won't be creating any resources available across availability zones in this walk-through, so it doesn't matter which you choose. Click Next to continue:

Figure 19.42: Creating an Auto Scaling group (continued)

On the next page, we can choose to enable load balancing. A load balancer allows us to route clients between multiple servers, so the end-users only see one endpoint, but behind the load balancer we can have more than one server available to serve client connections. We'll want to utilize this, so be sure to check the box titled Enable load balancing.

There's also an option listed to create a Classic Load Balancer. A classic load balancer is only used in existing environments that were created in classic EC2 networks, but since this is a new account, we don't have existing environments to take into consideration.

The next option directly below that allows us to select a target group. However, we don't actually have one yet since we've never created one. You can click the Create a target group link on this page to create one now:

Figure 19.43: Creating an Auto Scaling group (continued)

This will cause a new window to appear, taking us directly to the place within the AWS console that allows us to manage our target groups. A Target Group is a group of instances that are responsible for serving our application. In our case, we installed Apache in our EC2 instance earlier, and we used that instance to create an AMI. Following along with this example, a target group for us could be a group of web servers created via this AMI, each of which can serve our web page to clients. We didn't actually alter the default Apache web page, but the example still works.

For the first screen while creating our target group, we should ensure that the Instances box is selected, then we can give the target group a name.

That's all we need to do here, so go ahead and click Next to continue:

Figure 19.44: Creating a target group

On this page, ensure Instances is selected and give the target group a name.

On the next screen, we will have an option to add existing EC2 instances to our target group. Let's leave everything blank, and not add any targets. We can click Create target group to finalize the process.

Back on the page we were on while creating the Auto Scaling group, we can now select the target group that we created in the previous step:

Figure 19.45: Creating an Auto Scaling group (continued)

Next, we can set the size and scaling policies. This is where the magic happens: we can choose the minimum number of instances to have running at any one time, the maximum number of instances we will allow the application to scale up to. We can leave each field at 1 for now:

Figure 19.46: Creating an Auto Scaling group (continued)

For the remainder of the configuration on this page, we can ignore the rest and continue along. In fact, you can keep the defaults for each remaining screen, clicking Next each time, and then at the end click Create Auto Scaling group.

At this point, our Auto Scaling group is created, and we should have everything ready to go. At first, we'll have 0 instances within this group, so we'll see the current number of instances shown as 0:

Figure 19.47: Auto Scaling groups, showing our newly created configuration

After it finishes updating capacity, it will automatically spin up a new EC2 instance in order to meet our requirement of always having one instance online. If we check our list of EC2 instances, we should have a new one on the list now:

Figure 19.48: A new instance was created as part of our Auto Scaling configuration

As you can see in the screenshot, the original EC2 instance has a state of stopped. We stopped it earlier so that we could create an AMI of that instance. In my case, I never started that instance again after creating the AMI, so it's completely stopped. The Auto Scaling configuration went ahead and created a new instance, because its requirement of having at least one instance running was not met.

Before we implement the final component, we need for everything to function properly, let's take a moment to understand the value that we already have in place. If we were to increase the number of desired instances within the Auto Scaling group, then it would immediately spin up a new instance for us. Although advanced usage is beyond the scope of this book, we can set this up to automatically happen when the CPU of our instance gets to a certain point, which can trigger Auto Scaling to bring another one online.

With just a single instance, we don't have Auto Scaling in play yet, but we can easily enable that. Another benefit that we get automatically is auto healing, and we have that benefit even with a single instance. If something were to happen to our only running instance, Auto Scaling will bring a new one online to replace it automatically.

In this situation, the website will be down for several minutes while the new instance is being created, but a bit of downtime is certainly better than having to manually replace the server ourselves. If we set the desired instances to a number higher than 1, a user will not notice anything if one of the servers goes down, the other will take care of the load while the new one comes up. These are amazing benefits to be able to take advantage of and will give us additional peace of mind right away. To test this yourself, feel free to delete the running EC2 instance by right-clicking it and then clicking Terminate. The instance should then get terminated, and a new one should appear within several minutes to replace it.

Next, we can implement the final piece of our puzzle by creating a load balancer.

Creating a load balancer

A load balancer, as mentioned earlier, routes our clients to a server in order to facilitate their requests. Having a load balancer is what allows us to be able to withstand one or more EC2 instances going down and becoming inaccessible, the load balancer will route users to an instance that is working fine, while Auto Scaling takes over and replaces failed instances for us. To get started, you can click on the Load Balancers section of the EC2 console. Once there, click on the Create button located on the first of three squares that appears:

Figure 19.49: Creating a load balancer

Next, give the load balancer a name. Note that you cannot have spaces here. The other two settings can remain at their defaults:

Figure 19.50: Creating a load balancer (continued)

Beneath that section on the same page, we can set the protocol and port for the load balancer. Port 80 is fine for our tests, although we would want to consider implementing TLS and utilizing port 443 if this were a production application:

Figure 19.51: Creating a load balancer—Load Balancer Protocol

Further down, we can choose Availability Zones for our application. You can just leave the defaults and choose the first two subnets. Click Next: Configure Security Settings to continue:

Figure 19-52: Creating a load balancer—Availability Zones

The next page will warn you about not using HTTPS for our application, which we can safely ignore since this is just a test. Click Next: Configure Security Groups to move on:

Figure 19.53: Creating a load balancer—Configure Security Settings

Continuing on to the next page, we're able to choose one or more security groups to provide access to the application. We're able to use the existing security group here that we created earlier, but since we enabled OpenSSH on that security group, I don't recommend we use it as we don't want to enable OpenSSH on everything. Instead, we can create a new security group (as shown in the following screenshot) to allow access to port 80 for Apache. After adding those values, click Next: Configure Routing to proceed:

Figure 19.54: Creating a load balancer—Configure Security Groups

For the fourth step in the process of creating the load balancer, we'll select our target group and set that to point to the target group we've already set up. This means that if a user goes to access our site, the load balancer will forward them to the target group, which will in turn send them to one of its instances.

We can leave the rest as it is and click Next: Register Targets to go to the next step, and accept the defaults and click through the next sections that appear after that:

Figure 19.55: Creating a load balancer—Configure Routing

At this point, the load balancer is created, and we have almost everything we need. The only thing left now is to ensure that our instances within our Auto Scaling configuration can be reached via port 80, and to do that, we'll need to add the IP range of our VPC into our security group. To find this value, we can access the VPC service within the list of available AWS services, and find our default VPC. After you access the VPC console, you should see an option titled Your VPCs in the menu on the left. After you click on that, you can then click on the VPC ID that's on the list in the middle (there should only be one), which will show you the details for the VPC:

Figure 19.56: Creating a load balancer—VPC details

Notice the IPv4 CIDR that is listed within the details. Copy that entire value, as we'll need it shortly. Next, access the EC2 service, and access the Security groups section, where we should find the first security group we added earlier in the chapter. Click on that security group, and then click the button labeled Edit Inbound Rules and you should be able to add the VPC IP range to be accessible via port 80. The new line should look similar to the following:

Figure 19.57: Adding a new security group entry to allow VPC traffic

With that final setting implemented, our application should be accessible to our users via the load balancer. To test that everything is working correctly, we can access the Load balancer section of the EC2 console, which is available in the menu at the left, to see details regarding the load balancer that is currently in front of our target group:

Figure 19.58: Viewing load balancer details

Note the DNS name that appears when you select the load balancer. If you copy and paste that into a browser, the default Apache page should appear:

Figure 19.59: Viewing load balancer details

Congratulations! At this point, you've created a complete load-balanced solution in AWS that will automatically heal from failures. Feel free to experiment a bit more, and then when you're finished, consider removing the test components we've created in this chapter to avoid a cost later on.

Speaking of cost, in the next section, we'll talk a bit further about how to manage costs and keep our bills under control.

Keeping costs down: understanding how to save money and make cost-effective decisions

As you just saw, there were many components and configurations we had to implement in order to implement a load-balanced solution in AWS. As we grow our AWS infrastructure and implement more solutions, we should also keep an eye on our bill. Although we can utilize the free tier for now, production applications will likely need more powerful instances than what the free tier will provide, and the free tier itself won't last forever. Not only that, but we should also know how to check how our bill is trending to make sure we don't accidentally implement something that is expensive or waste money by running something we no longer need.

In this section, we'll explore some concepts around billing. Although it's beyond the scope of this chapter to do a complete deep-dive into the world of billing, the subsections that follow will provide you with essential advice needed to help prevent unexpected charges.

Viewing billing information

Within AWS, the billing section is its own service along with others, such as EC2 and S3. You can find the Billing area from the service list. Once there, you'll be shown the Billing & Cost Management Dashboard, which will show you your current expenses and allow you to see current and past billing information:

Figure 19.60: Viewing the Billing & Cost Management Dashboard

Since the account I'm working with currently was just created a week or so ago, and I'm only using instances in the free tier, I have no costs currently. But if I did incur charges, I'd see the current balance on the main page of the dashboard. In addition, I'll receive the same information in a monthly statement that is sent to the primary email account.

However, I don't recommend waiting for the bill to arrive before checking your totals. To effectively manage billing, you should check this dashboard manually, which might enable you to catch an error before the end of the month, which might save you money. The links on the left will give you additional billing information, as well as providing a way of accessing previous bills.

Adding a billing alert

In the previous section, I recommended that you check the bill regularly instead of only when the monthly invoice arrives. While that is good advice (if I do say so myself), the reality is that server administrators are busy and may not remember to check the bill on a regular basis. This is why we typically set up system alerts to notify us when our servers are encountering an issue. Similarly, we can actually set up an alert inside our AWS account that can notify us if our bill gets too high. In fact, even though the AWS account we've been working with was likely only created as a test account, it's especially important that we add a billing alert so we can be alerted if any of our experiments were misconfigured in such a way that we're incurring costs we didn't intend to.

In the Further reading section at the end of the chapter, I have included a link to AWS documentation that details how to set up billing alerts, and I definitely recommend you enable them. If you're using an AWS account for your organization to run actual production servers, it's a good idea to enable billing alerts there as well. In fact, be sure to create billing alerts in every AWS account you manage. Another important element to consider is removing backups that aren't needed anymore, which can also lower costs.

Removing unneeded backups

This may seem like a no-brainer, but you'd be surprised—every organization I've ever worked for or consulted with in regards to AWS has run into an issue where backups get out of control and generate large costs. My personal record for witnessing a waste of money in this manner is one company that had over 23,000 unnecessary snapshots in their account, sitting around for over 5 years. I don't remember the exact dollar amount, but this error cost them thousands of dollars a month for years.

Backups themselves are extremely important though, and the previous example might've been understandable if the organization had legal requirements that forced them to retain all backups for a specific period (such as 5 years). And backups, as you well know by now, are essential if the organization runs into some sort of issue and needs to restore something from the past. But the general rule of thumb here is to ensure that when the day comes to add an automatic backup feature, you also implement (and regularly test) an automatic cleanup procedure as well.

Running EC2 instances only when they're needed

Many organizations do business around the clock and all year round, while others conduct business only during daytime business hours. While it might not be immediately apparent why this matters, consider the fact that you don't get charged for an EC2 instance while it's powered off. You do get charged for things like storage regardless of its state, but you aren't charged for the instance itself if it is not running. If your organization has a server that is only used during certain hours, consider stopping the instance outside of that time period and then starting it back up when it's needed.

There's additional functionality in AWS that allows you to automatically schedule an instance to run only during certain hours, so there are ways to ensure your infrastructure is available when it's needed. Make sure you keep this in mind as you navigate AWS, if you're creating a new server, is it going to be necessary to make it run 24/7, or is it only necessary to run it at certain times? You'd be surprised how much money this may save you.

Stopping or terminating unneeded EC2 instances

Similar to the advice in the previous section about having instances run only when necessary, consider deleting instances completely if they're not needed at all. Unless you're utilizing a very specific type of instance, you won't be billed for an EC2 instance that doesn't exist. Make a habit of deleting things when you're done with them. If you think you may need a server again in the future but you're not sure, consider creating an AMI of the server, and then removing it. Although the AMI itself will have a cost, it's going to be less than running an actual server.

This advice isn't exclusive to EC2 instances, other services within AWS will cause you to incur costs if you don't clean them up. Make sure to keep an eye on other components and services that charge by usage, such as RDS, S3, EBS volumes, and so on.

So, there you have it—with some basic advice, you should be able to keep your billing under control. And even if you make a mistake, as long as you've configured billing alerts, you should be notified and be able to correct the problem quickly. I can understand if some of the billing advice was overwhelming, but you'll get used to it. AWS has a lot of components that can make up a bill, but as long as you set up alerts and delete items you're not using, you shouldn't have any problems.

We've gone over quite a bit in this chapter, but where should you go from here? In the next section, I'll provide some advice for continuing your learning and taking your AWS skills to the next level.

Taking cloud further: additional resources to grow your knowledge

AWS is a huge service, and we haven't even scratched the surface of the platform in this chapter. We've just created a simple load-balanced application in an earlier section, and we'll even learn how to automate creating cloud resources in the next chapter. But if you've found this chapter fun and want to work with AWS more and enhance your skills, I thought I'd provide some additional advice that will hopefully help you do that.

Online training and labs

There is quite a bit in the way of online resources to expand your knowledge. Some of these resources are free, such as a section of the AWS web site that provides free hands-on training: https://aws.amazon.com/training/intro-to-aws-labs-sm/.

While you may already be aware of the value of YouTube when it comes to training videos, it's a great source of knowledge. (And you may have even stumbled across my YouTube page, over at LearnLinux.tv). There are many videos on YouTube that can provide training, but that's not the only source of video content; Packt Publishing features video training courses as well, in addition to Udemy, which also has some great content.

Overall, there's no shortage of training materials available, but I'd recommend starting with the free training provided by AWS that I've mentioned above, as well as the additional training content that Amazon makes available at https://aws.training.

Certification

While it will take a bit of work, achieving one or more certifications in AWS will lead you down a path where you'll learn the platform in much greater detail. In addition, individuals with AWS certifications are in high demand in the IT industry, so achieving certification is a good idea all around. I recommend looking into the AWS Certified Cloud Practitioner credential, which is a more entry-level certification that is approachable to those just starting out.

After you grow your expertise, you may want to consider the AWS Certified Sysops Administrator credential, which is more challenging but will boost your knowledge even further.

Keep experimenting and learning

Even if you don't decide to achieve a certification, keep experimenting with the platform. Getting your hands on the technology and making use of it on a regular basis is usually the best way to learn and keep your skills sharp. Try to create additional types of infrastructure, build and rebuild test instances, and above all have fun. For many people, there's no greater way to learn something than to get your hands dirty and experience it. I also recommend you follow any blogs around cloud computing and related technologies as well.

AWS documentation

The documentation provided by AWS is well written and very detailed. You can learn everything you need to know from the AWS documentation alone. The documentation pages are above and beyond the typical level of quality you would expect from such a large service; Amazon takes the AWS documentation seriously. The documentation pages are available here: https://docs.aws.amazon.com/index.html.

New resources for learning about AWS are being created on a regular basis, so keep your eyes open for new books, training videos, and more as you study the platform. I think you'll have a lot of fun taking your skills to the next level and exploring everything the AWS platform has to offer.

Summary

This chapter has been one of the most involved in the entire book so far, and you've accomplished a lot. During the course of this chapter, you learned about AWS, set up your own cloud server, set up Auto Scaling to ensure that your server is able to automatically heal from disasters, and even set up a load balancer to enable routing between multiple instances. Make sure you take some time to let all this knowledge sink in before continuing on, and I also recommend you spend some additional time with AWS before moving on to the next chapter.

Speaking of the next chapter, we're going to work with AWS again, but this time, we're going to focus on learning Terraform, which is an awesome tool that will enable us to automate the building of our cloud resources from the ground up. It's going to be a lot of fun.

Further reading

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.224.33.107