Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Hosted-services / AWS

How to Build a Multi-Cloud App - A Step-by-Step of How to Run the Simplest Web-Page Hosted by the Load Balancer

5.00/5 (5 votes)
6 Mar 2020CPOL10 min read 23.2K  
In this article I will explain and show step-by-step how to run the simplest web-page hosted by the Load Balancer which has nodes both on AWS and Azure behind.
In this article, I will show how to build a real working multi-cloud solution. As an example, I chose two most known and common cloud providers: Amazon AWS and Microsoft Azure. So what I'm going to do is to create a Load Balancer at AWS and put two nodes behind: the first one is EC2 instance at AWS and the second one is Virtual Machine at Azure. To test and show how it works, I'll put the simplest web-page on both nodes with a small difference.

Background

The cloud solution I'm going to build is actually based on two big architectural chunks: connecting virtual private networks from two cloud providers and building the load balancer with nodes itself.

I want to say 'thank you' to Gavin Lewis whose article inspired me. In fact, the first chunk (connecting AWS and Azure VPNs) is repeating his steps but providing more explanation and depicting omitted steps. Some things were not obvious for me when I did it myself so I decided to show a step-by-step guide of how to do that instead of just referring to that article.

Using the Code

As was mentioned above before constructing multi-cloud load balancer solution, we need to connect AWS and Azure networks. It's needed so that load balancer can interact with nodes as they are in the same network.

Connecting Networks

Azure

  1. First of all, we create Virtual Network. Specify its Name and Address space, let it be 172.18.0.0/16. Choose existing Resource group or create a new one. And let's set West US Location for this Azure part of architecture.

    Also, we need to create the Subnet. Set its Name and Address range where we reduce address range increasing subnet mask to 17 - 172.18.0.0/17. Leave the rest of the parameters as they are.

    Image 1

  2. For connecting this VNet to AWS network, we will need a gateway, that's why we create Gateway Subnet for this VNet with Address range (CIDR block) 172.18.128.0/24 as suggested by default.

    Image 2

  3. The next step is creating Public IP Address to be assigned to Virtual Network Gateway in future. We only need to specify its Name and leave the rest by default.

    Image 3

  4. Now we are ready to create Virtual Network Gateway which is a junction point for AWS network. We set Name, change SKU parameter to Basic to save money sacrificing throughput, choose created earlier VNet and its Gateway Subnet. The last parameter to set is Public IP Address created on the previous step.

    Creating VNet Gateway takes the most time (up to 60 minutes), so keep calm and switch to AWS console to continue there while it's under progress.

    Image 4

    AWS

  5. Now we need to prepare a similar architecture for another provider. So we start from creating VPC. We should specify some free CIDR block for your region, so let it be 172.16.0.0/16.

    Image 5

  6. Then we need to create Subnets for this VPC. For creating AWS Load Balancer, we need at least 2 subnets based on different Availability Zones. 

    So choose just created VPC, then choose one of possible Availability Zone and specify CIDR block for Subnet 1. Repeat these actions for the second subnet but with another CIDR block.

    Image 6

    • Subnet 1: 172.16.0.0/18
    • Subnet 2: 172.16.64.0/18
  7. To create VPN tunnel, we need to have Virtual Private Gateway on AWS side. Set some name and leave Amazon default ASN option as it is.

    Image 7

  8. For some reason, they don't have an option to attach Virtual Private Gateway to particular VPC while creating. So we should do it manually. Choose our multi-cloud VPC, status of the gateway should be changed to 'attached'.

    Image 8

    Image 9

    Azure

  9. For the next step at AWS environment, we need to know Public IP address of created Azure Virtual Network Gateway from step 4. For this, choose your Public IP address from the list and note down IP address itself. In my example, it is 40.112.249.133. It will appear only when VNG is fully created.

    Image 10

    AWS

  10. Now we are ready to create Customer Gateway at AWS side and link it to Azure network using Public IP address from the previous step. We use static routing not to make stuff more complicated.

    Image 11

  11. This is one of the key steps of connecting two networks. So we're going to create Site-to-Site VPN Connection to join our networks. Ultimately, we will get two tunnels inside this VPN Connection which are joined to Local Network Gateways inside Azure network.

    To create VPN Connection, fill in Name tag, choose Virtual Private Gateway from step 7. and existing Customer Gateway from the step 10. We don't have BGP and actually don't need it, so choose Static Routing Option and enter Static IP Prefix 172.18.0.0/17 - it is IP address range of Azure VNet Subnet 1 from step 1.

    Leave the rest of the parameters by default.

    Image 12

  12. Once VPN Connection is created, we can download its configuration. We need Outside IP Address of Virtual Private Gateway and Pre-Shared SHA Key for each IPSec Tunnel.

    If we choose Generic value for Vendor and Platform, Vendor Agnositc value for Software in Download Configuration dialog, we should get plain text file in downloads.

    Image 13

    So find #1: Internet Key Exchange Configuration section for IPSec Tunnel #1 in the file you just downloaded, there is a line with Pre-Shared Key value and line with Virtual Private Gateway Outside IP Address:

    IPSec Tunnel #1
    - Pre-Shared Key                     : RyLbEbDeQEfRgyfNMCazi74Ifa8NCCR2
    - Virtual Private Gateway            : 13.59.179.250

    The same for IPSec Tunnel #2.

    IPSec Tunnel #2
    - Pre-Shared Key                     : rNaec.9VsurcpGgdfP7CwfQU4OvRRrzs
    - Virtual Private Gateway            : 18.224.76.18

    Image 14

    Azure

  13. Now we go back to Azure VNG where we need to create 2 Connections with their Local Network Gateways for each connection. There, we will specify the settings we got in the previous step. This is the final step of joining 2 networks.

    Choose your Virtual Network Gateway, go to Connections in Settings section and click Add button.

    Image 15

    Enter some Name for your connection, choose Connection type as Site-to-Site (IPsec), the same as we had for AWS VPN Connection. Enter Shared key from the first IPSec Tunnel we got in step 12. After that, click 'Choose a local network gateway' and 'Create new' button there.

    Image 16

    Now we jump into Local Network Gateway creating dialog where we need to enter gateway's Name and IP address from the first IPSec Tunnel we got in step 12, it was Outside IP Address in configuration file. Also, specify Address space, it's CIDR block of AWS VPC - 172.16.0.0/16.

    Image 17

    Then, create the second Connection and Local Network Gateway for it. Repeat these actions but take data for Shared key and LNG IP address from the second AWS IPSec Tunnel.

    You can also find these settings in Local Network Gateways, Configuration section.

    Image 18

  14. After some time, we can check our Connections of Virtual Network Gateway, the Status should be 'Connected'.

    Image 19

    AWS

  15. Then check Status of two tunnels on AWS side. Pick your VPN Connection and click on Tunnel Details tab. The Status for both should be UP.

    It means we successfully connected networks of 2 providers. But before we can really build multi-cloud solutions here, we should tune Route Table of VPC on AWS side to show where to route traffic.

    Image 20

  16. To tune Route Table, we need to have Internet Gateway. Let's create it with some name.

    Image 21

  17. After creating Internet Gateway, we need to attach it to our multi-cloud VPC. It needs just a few clicks.

    Image 22

    Image 23

  18. Now we can edit Route Table entries for our multi-cloud VPC. Find Route Table which belongs to multi-cloud VPC, click Actions and Edit routes.

    Image 24

    We should add 2 routes. Traffic addressed to 172.18.0.0/16 (Azure VNet) we route to Virtual Private Gateway from step 7 and the rest traffic (except our local network which is already targeted locally) goes to Internet Gateway from step 16.

    Image 25

    That's it, let's test if nodes in these networks can really interact with each other using private IP addresses.

        Testing

  1. To test interaction, we will create 2 nodes - EC2 instance at AWS and Virtual machine at Azure inside connected networks and try to ping each other.

    I will not describe how to create EC2 instance and Virtual machine, it's too trivial and you can easily find how to do that. Don't forget when creating that, you will need to ssh to these machines, so allow this in rules and save keys and passwords not to lose access.

    To be able to ping EC2 instance, we have to allow it intentionally tuning Security Group which is assigned to created EC2 instance. Choose Security Group, go to Inbound tab, click Edit and add rule with next parameters:

    Type - Custom ICMP, Protocol - Echo Request and Source 0.0.0.0/0.

    Image 26

  2. Connect to both machines via ssh and try to ping each other by their private IP addresses. It should work. It also approves then networks are successfully connected to each other and we really can start building multi-cloud solutions here.

    Image 27

    Load Balancer

  3. So the idea is to create Load Balancer at AWS and put to associated Target group 2 instances: one from VPC where LB is located itself and one from connected network. This way, we build LB target group which is placed not at different AZs or Regions, but different providers. So we get multi-cloud solution with nodes across the world.

    Before creating LB, we need to prepare our nodes to act as web-servers. For that, we need to install any web-server there. This is also quite a trivial issue, there are many examples of how to do that. I can say that httpd service will be more than enough for our purpose.

    After installing web-server service on our nodes, put index.html file to /var/www/html folder. Put the next HTML code to AWS EC2 instance index.html:

    HTML
    <html><h1>Hello Multi-Cloud (AWS)</h1></html>

    And the same but with (Azure) for Azure Virtual Machine:

    HTML
    <html><h1>Hello Multi-Cloud (Azure)</h1></html>
  4. Let's start to create LB itself. We will need an Application Load Balancer type. After choosing the type, we should fill in LB Name, choose internet-facing scheme to be able to test it via its DNS name.

    Image 28

  5. At the bottom of Configure Load Balancer tab, we can find Availability Zones section. On this step, LB doesn't know that it will be multi-cloud balancer, so we have to choose at least 2 AZs with subnets there. That's why we created 2 subnets in step 6.

    Image 29

  6. We can leave everything on Configure Security Settings by default and skip to Configure Security Groups. Here, we create a new security group with suggested TCP rule.

    Image 30

  7. The next Configure Routing tab is more interesting. We create a new target group for our nodes, specify some Name tag for it. Then we should choose IP as Target type. Leave Protocol and Port by default.

    For the Health check, enter /index.html to the Path. So it should find our index.html files we created on each node.

    Image 31

  8. On Register Targets tab, we register two targets.

    The first one is local EC2 instance. We choose our multi-cloud VPC and specify instance's Private IP address. Then click 'Add to list' button. For my case, it's 172.16.20.207.

    The second one is Azure VM. To register it, we choose 'Other private IP address' as Network value and type Private IP address of Azure VM in 172.18.0.0 subnet. For my case, it's 172.18.0.4.

    Image 32

  9. After review, we create LB. When it's done, we can see newly created LB in the list. It takes some time to check that our targets are healthy. You can see this at Targets tab in Status column.

    Image 33

  10. Load Balancer is created and its targets are in healthy state. Let's check it live. Click on Description tab and find its DNS name. Copy it to clipboard and open URL in browser.

    Image 34

  11. You will see something like that. Try to refresh the page a couple of times. (Azure) should change to (AWS) and vice versa. It means LB route traffic to different nodes which are placed on different cloud providers.

    Multi-cloud solution works!

    Image 35

Points of Interest

I just showed how to build multi-cloud solutions and not be locked-in with some particular provider. It can help to minimize risks of any single provider related to its price, availability and so on.

Of course, you can find much better business cases for multi-cloud approach, but I didn't pursue the goal to make a business solution. It's more about the technical solution and a fundamental example of how to join and mix different cloud providers. This solution is based on my experience at Intetics.

I'll be glad to see in the comments any other examples (real or just your ideas) of any business cases where it really make sense to build your architecture across multiple clouds.

History

  • 12th November, 2019: V1
  • 6th March, 2020: minor changes, title updated 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)