Hosting ASP.NET apps on AWS Part 5 - Servers in EC2 part 1

Cover Image for Hosting ASP.NET apps on AWS Part 5 - Servers in EC2 part 1

Hosting ASP.NET apps on AWS Part 5 - Servers in EC2 part 1

How-to written and screenshots taken on 2020 January 3114 min read

EC2 stands for elastic compute cloud, where AWS really focuses on the elastic part. EC2 basically is a big "cloud" of CPU's and memory. You use just the amount of those that your application needs at every moment. If used correctly it will scale elastically with your needs.

Although the premise of elasticity is awesome, we are not going to use that part yet. That will be something for another series. Now we'll keep it relatively simple and only run two "fixed" EC2 instances.

In this part we'll setup the basics for the instance and configure the Windows instance. In Part 6 – Servers in EC2 part 2 the Linux (Ubuntu) instance will be configured as well, we'll make snapshots and discuss some optional or future improvements.

1. Security features

Before we launch these instances, we'll first setup two security features: Security Groups and Key Pairs. You can also do it during the launch of the instance, but I found it easier to have them prepared in advance.

1.1 Security Groups

A security group can be seen as a virtual firewall. It will block all ports, except the ones you explicitly open. We're going to setup four security groups; one for webserver access, one for the MS SQL engine, one for remote management and one for our applications.

NameGroup NameDescription
sg-jodibooks-apps-mgmtjodiBooks appsAllow private connections to API and management apps
sg-ms-sqlMS SQL engineAccess MS SQL engine
sg-server-managementRemote server managementServer management (SSH and RDP) from private IP
sg-webserverWebserverWebserver ports (80 and 443)
  1. From the main console get to EC2 by searching for EC2.

  2. Check if you're in the correct region. You can change it in the top right corner. I'm in Frankfurt (eu-central-1).

  3. In the EC2 dashboard go to Security Groups in the menu on the left.

    security groups

  4. Click the Create Security Group button and add the Group name and description. We only have the default VPC, so we can't change this setting.

    add a name and description for the security group

  5. Next we add a rule for each port we want to open. For example, when creating the Webserver group, click Add Rule and select the HTTP as type. The Protocol and port will be automatically entered. Choose anywhere when you want people to see your website. Choose My IP when only you want to have access.

    Security groupTypeProtocolPort RangeSourceDescription
    sg-ms-sqlCustom TCPTCP445My IPMSSQL Express Management
    sg-ms-sqlMS SQLTCP1433My IPMSSQL Express Management
    sg-server-managementSSHTCP22My IPSSH from the office
    sg-server-managementRDPTCP3389My IPRDP from the office
    sg-webserverHTTPTCP80anywhereHTTP website traffic
    sg-webserverHTTPSTCP443anywhereHTTPS website traffic

    add inbound rules to the security group

  6. Click on the Outbound tab and notice that there is a rule for All traffic. This means all ports are open to anywhere. We'll leave it like it is and click Create to create the security group.

    outbound rule for security group

  7. We'll repeat this for every group.

1.2 Key Pairs

Next we need to make a key pair. We'll actually make two, one for each instance, but you can also choose to use the same one twice.

A key pair consists of a public and a matching private key. The public key will be used by AWS and added to your instances. If you want to access an instance it is only possible if you supply the private key that matches the public key. As only you have that private key, nobody else, even AWS, has no access to your data. So if you lose it, it's gone and you lose access to your instances. To prevent that I've stored mine in Bitwarden.

More info on key pairs in AWS:

  1. You can create key pairs yourself and import the public key, but we'll let AWS do it for us. Go to Key Pairs in the menu on the left and click Create key pair. We'll give it a name with prefix kp for key pair and for which server/application: kp-jodibooks-windows-server.

    create a key pair

  2. Because we want to use this key in Windows, we choose ppk as the file format. You can always change the file type later.

Source of .pem to .ppk instructions:

  1. Click Create key pair and save the private key. As said, I've stored mine in a password manager.
  2. We'll create another key, but this time we give it the name kp-jodibooks-linux-server. Again we choose ppk as type, because we'll use PuTTY to access it later. Also store this private key somewhere safe.

2. Windows EC2

We're ready to launch an instance. Yeah, finally!

2.1 Launch instance

  1. You can start the process from the main EC2 dashboard. There is a big orange button on the dashboard that says Launch instance. Click it and choose Launch instance. Alternatively you can go to Instances through the menu on the left and click a blue Launch instance button on the top of the page.

    ![launch instance button](ec2-7.png "Left: the launch instance button on the EC2 dashboard. Right: the launch instance button in the Instances screen)"

  2. In step 1 we choose an AMI (Amazon Machine Image). Click AWS Marketplace on the left. These are AMI's maintained by AWS. Then search for Windows 2019 sql express. Currently it returns 4 results from which we'll select Microsoft Windows Server 2019 with SQL Server 2017 Express.

    4 results for windows 2019 sql express
    You can also select SQL Server 2019, but we only tested our application with 2017.

  3. After we press the Select button, we get a summary of the chosen AMI and link to the license agreement. Also we get a list of Instance Types and their pricing. You don't have to choose anything yet and click Continue.

    Product (AMI) details and instance types with fees

  4. In step 2 we choose the instance type. This will be the Windows instance with MS SQL, so we need at least 2 GB of memory. To get started with a t-type instance is best. It's the cheapest option and has sufficient computing power for webhosting. We choose the t3.small instance (more on instance selection in Appendix D).
    Mind that we will click on Next: Configure Instance Details not the shiny blue Review and Launch button.

    selection of t3.small instance
    We want a "General purpose" instance type with 2 GiB of memory.

  5. Step 3 let's you configure the instance. Most of the default values are fine, but we'll change a few.

    1. Subnet: As shown we have 3 availability zones and each has it's own subnet. We can let AWS decide where to create this instance, but we can also select a specific zone here. In the architecture we had this one in zone b.
    2. T2/T3 Unlimited: Disable this option. With a t-type instance you get a certain amount of CPU credits per day. When you need more, you pay an additional fee. This option enables you to use an unlimited amount of addition credits.

    Source CPU credits:

    choose the subnet and disable unlimited mode

  6. After we press Next: Add Storage we can add the EBS volumes in Step 4. These are the "virtual hard disks" for your instance. The volumes exist separate from the instance, so if the instance is terminated, the volumes (and your data) are still there (if configured).

    1. The root (OS) volume is automatically added. We uncheck Delete on Termination and select (default) aws/ebs encryption.
    2. Next we add a new (second) volume for our application data and logs. Again we select (default) aws/ebs encryption. You can also store your data on the OS drive, but I like to keep it separate.

    select encryption and add a second volume

  7. In Step 5 we can add tags. I added 4 tags:

    1. Name: jodibooks-server-w01
    2. Applications: our applications
    3. Database: database name
    4. Tools: installed software

    add tags: name, applications, databases and tools
    Obviously you can add whatever tags you want.

  8. Step 6 is adding or configuring your security group. As said, you can create a new group here, but we already made one earlier, so we can select the Webserver, MS SQL engine and Remote server management security groups. Here you can see why it is important to add a good name and description, because sg-00fe53048d876aa05 isn't really descriptive.

    select our existing security group
    This screenshot shows a single security group with all rules. I later learned you can apply multiple groups, which I like better for clarity.

  9. Almost there, just step 7 to go. Review all the details and click Launch. You can ignore the "Your instance configuration is not eligible for the free usage tier" remark.

    1. AMI Details: Microsoft Windows Server 2019 with SQL Server 2017 Express
    2. Instance Type: t3.small
    3. Security Group: Webserver, MS SQL engine, Remote server management
    4. Instance details: T2/T3 Unlimited Disabled
    5. Storage: Encrypted and Delete on Termination: No
    6. Tags: Name, apps, databases and tools

    review all details
    This screenshot doesn't show all details. Just scroll down to find the others.

  10. After pressing Launch you have to select a key pair. We already made one for our Windows instance, so let's select that one, acknowledge that you have the private key and press Launch Instance.

    choose your key pair
    After a few minutes, the instance will be in running state and we can continue with adding the Elastic IP and IAM role.

2.2 Elastic IP

  1. Go to the Elastic IP addresses screen by clicking on Elastic IP in the menu on the left. Now click Allocate Elastic IP address.

    elastic ip addresses screen

  2. There's nothing much to do in the next screen, but to click Allocate.

    allocate an elastic ip address

  3. Now we click Actions and choose Associate Elastic IP address.

    associate elastic ip address

  4. Click in the Choose an instance search bar and select the Windows instance. Now click Associate. Select the Allow this Elastic IP address to be reassociated option.

    choose windows instance

  5. Now that the IP address is associated with the instance we can select it, click on the Tags tab and click Manage tags.

    manage tags

  6. Now we can add a name by adding Name as Key and eip-jodibooks-windows-server as value. Finish by clicking the Save button.

    add name to elastic ip tags

2.3 Attach IAM role

An IAM role allows the EC2 to communicate with other AWS services on your behalf. Our Windows instance will send log data to CloudWatch, user data (PDF's) to an S3 bucket and backups of our database to another S3 bucket.

  1. Select the Windows instance, click Actions, Instance Settings and Attach/Replace IAM Role.

    attach an IAM role

  2. Select the IAM role we made for dotnetapp and click Apply.

    select the dotnetapps role

2.4 Logging into Windows

Now that we have a running Windows instance with a fixed IP public address, let's connect through the RDP (remote desktop). You can read the full guide here:

  1. Open the remote desktop tool in Windows. Copy the Public DNS from your instance and past it as the Computer address. Click connect.

    use the public dns to connect through the remote desktop tool ](

  2. If you are connecting from the IP address you've allowed, you're now asked to enter your credentials. Your user name is administrator to find your password, we have to decode the private key. Click Actions and then Get Windows Password.

    get windows password

  3. Now browse to your private key file or paste the key in the text area.

    add your private key

  4. After clicking the Decrypt Password button you will get your login password.

    windows login credentials
    I see I have to change my admin password soon

2.5 Initialize Data volume

The second volume we added to our instance needs to be initialized and formatted, before it's usable in Windows. Start the Server Manager if it hasn't automatically started. Search for Server Manager in the start menu.

  1. Go to File and Storage Services.

    main screen server manager

  2. Click Disks, select the volume with 4GB unallocated space and click To create a volume, start the New Volume Wizard link.

    start create volume wizard

  3. Before You Begin: Click Next.

    start of create volume wizard

  4. Server and Disk: select the server and disk and click Next.

    select server and disk

  5. Yes, we want the disk to be brought online and initialized as a GPT disk.

    confirm to initialize as GPT

  6. Select the full capacity: 3.97 GB and press Next.

    Set volume size

  7. Select a Drive letter, we I chose D. Press Next.

    set drive letter

  8. Set File system to NTFS, Allocation unit size to default and Volume label to Data. Press Next again.

    set file system and drive label

  9. Verify the settings and press Create.

    verify and create

2.6 Windows firewall

When connected to the instance through the remote desktop, we can open the Windows Firewall. We are going to open the ports for a remote connection to the MS SQL database.

  1. Click on the "Windows flag" and type firewall to search for it.

    search for firewall in Windows

  2. Click Advanced settings.

    go to advanced settings

  3. Click Inbound Rules on the left and than New Rule on the right. In the screen that pops up select Port as the rule type and click Next.

    select new port rule

  4. Select TCP and type 1433, 445 in the Specific local ports box.

    type TCP port numbers 1433, 1434

  5. In the action part choose Allow the connection.

    allow the connection

  6. Check if every box is checked and click next.

    check all the boxes

  7. Type a name like Remote MS SQL access and click Finish. A description is optional.

    add a name for the rule

  8. Now select the rule you just created and click on properties. Go to the Scope tab and change to These IP addresses for remote IP address. Then click Add.

    add office ip address

  9. Add the IP address of the office or your home address and press OK twice. Now close the firewall.

    add your office ip address

2.7 System settings

Just one more thing before we move on to the Linux instance. We are going to change the computer name and workgroup.

  1. Right click on the "Windows flag" and click on System.

    go to system

  2. Now go to System info.

    go to system info

  3. Now click Change settings and Change and in the new windows change your Computer name and Workgroup.

    set a computer name and workgroup

  4. Now check for Windows updates, install them and restart Windows.

3. Next Ubuntu

This part has gotten way longer than I thought, so I split it in two. The Linux instance will be configured in the next part.