[Yandex Cloud documentation](../../index.md) > [Yandex Application Load Balancer](../index.md) > [Tutorials](index.md) > Setting up virtual hosting

# Setting up virtual hosting


This tutorial describes how to set up virtual hosting: use [Yandex Application Load Balancer](../index.md) to host multiple websites with different domain names at the same [IP address](../../vpc/concepts/address.md).

As examples, we are going to use these three domain names: `site-a.com`, `site-b.com`, and `default.com`.

To set up virtual hosting:
1. [Get your cloud ready](#before-begin).
1. [Create a cloud network](#create-network).
1. [Reserve a static public IP address](#reserve-ip).
1. [Create security groups](#create-security-groups).
1. [Import TLS certificates of the websites to Yandex Certificate Manager](#import-certificates).
1. [Create instance groups for websites](#create-vms).
1. [Upload the website files to the VMs](#upload-sites-files).
1. [Create backend groups](#create-backend-groups).
1. [Create and configure HTTP routers](#create-http-routers).
1. [Create an L7 load balancer](#create-l7-balancer).
1. [Configure DNS for the websites](#configure-dns).
1. [Test the hosting](#test).

If you no longer need the resources you created, [delete them](#clear-out).

## Get your cloud ready {#before-begin}

Sign up for Yandex Cloud and create a [billing account](../../billing/concepts/billing-account.md):
1. Navigate to the [management console](https://console.yandex.cloud) and log in to Yandex Cloud or create a new account.
1. On the **[Yandex Cloud Billing](https://center.yandex.cloud/billing/accounts)** page, make sure you have a billing account linked and it has the `ACTIVE` or `TRIAL_ACTIVE` [status](../../billing/concepts/billing-account-statuses.md). If you do not have a billing account, [create one](../../billing/quickstart/index.md) and [link](../../billing/operations/pin-cloud.md) a cloud to it.

If you have an active billing account, you can create or select a [folder](../../resource-manager/concepts/resources-hierarchy.md#folder) for your infrastructure on the [cloud page](https://console.yandex.cloud/cloud).

[Learn more about clouds and folders here](../../resource-manager/concepts/resources-hierarchy.md).

### Required paid resources {#paid-resources}

The cost of virtual hosting includes:
* Fee for continuously running [VMs](../../compute/concepts/vm.md) (see [Yandex Compute Cloud pricing](../../compute/pricing.md)).
* Fee for using a [public static IP address](../../vpc/concepts/address.md#public-addresses) (see [Yandex Virtual Private Cloud pricing](../../vpc/pricing.md)).
* Fee for using the computing resources of the [L7 load balancer](../concepts/index.md) (see [Application Load Balancer pricing](../pricing.md)).
* Fee for public DNS queries and [DNS zones](../../dns/concepts/dns-zone.md) if using [Yandex Cloud DNS](../../dns/index.md) (see [Cloud DNS pricing](../../dns/pricing.md)).
  
## Create a cloud network {#create-network}

All resources created in this tutorial will belong to the same [cloud network](../../vpc/concepts/network.md).

To create a network:

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select a folder.
  1. Navigate to **Virtual Private Cloud**.
  1. Click **Create network**.
  1. Specify the network **Name**: `vhosting-network`.
  1. Select **Create subnets**.
  1. Click **Create network**.

{% endlist %}

## Reserve a static public IP address {#reserve-ip}

For your virtual hosting to run, you need to assign a static public IP address to the [L7 load balancer](../concepts/application-load-balancer.md).

To reserve an IP address:

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select a folder.
  1. Navigate to **Virtual Private Cloud**.
  1. In the left-hand panel, select ![image](../../_assets/console-icons/map-pin.svg) **Public IP addresses**. Click **Reserve public IP address**.
  1. In the window that opens, select the `ru-central1-d` [availability zone](../../overview/concepts/geo-scope.md). Click ** Reserve**.

{% endlist %}

## Create security groups {#create-security-groups}

[Security groups](../concepts/application-load-balancer.md#security-groups) include rules that allow the load balancer to receive inbound traffic and redirect it to the VMs so they can receive it. In this tutorial, we will create two security groups: one for the load balancer and another one for all VMs.

To create security groups:

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select a folder.
  1. Navigate to **Virtual Private Cloud**.
  1. In the left-hand panel, select ![image](../../_assets/console-icons/shield.svg) **Security groups**.
  1. Create a security group for the load balancer:
     1. Click **Create security group**.
     1. Specify the group **Name**: `vhosting-sg-balancer`.
     1. Select **Network**: `vhosting-network`.
     1. Under **Rules**, create the following rules using the instructions below the table:

        | Traffic<br/>direction | Description | Port range | Protocol | Destination name /<br/>Source | CIDR blocks |
        | --- | --- | --- | --- | --- | --- |
        | `Egress` | `any` | `Select entire range` | `Any` | `CIDR` | `0.0.0.0/0` |
        | `Ingress` | `ext-http` | `80` | `TCP` | `CIDR` | `0.0.0.0/0` |
        | `Ingress` | `ext-https` | `443` | `TCP` | `CIDR` | `0.0.0.0/0` |
        | `Ingress` | `healthchecks` | `30080` | `TCP` | `Load balancer healthchecks` | — |

     1. Select the **Egress** or **Ingress** tab.
     1. Click **Add**.
     1. In the **Port range** field of the window that opens, specify a single port or a range of ports open for inbound or outbound traffic.
     1. In the **Protocol** field, specify the appropriate protocol or leave `Any` to allow traffic transmission over any protocol.
     1. In the **Destination name** or **Source** field, select the rule purpose:
        * `CIDR`: Rule will apply to the range of IP addresses. In the **CIDR blocks** field, specify the CIDRs and masks of subnets traffic will move to/from. To add multiple CIDRs, click **Add**.
        * `Security group`: Rule will apply to the current or selected security group VMs.
        * `Load balancer healthchecks`: Rule allowing a load balancer to health-check VMs.
     1. Click **Save**. Repeat these steps to create all rules from the table.
     1. Click **Create**.
  1. Similarly, create a security group for the VM named `vhosting-sg-vms` with the same `vhosting-network` and the following rules:

     | Traffic<br/>direction | Description | Port range | Protocol | Source | CIDR blocks |
     | --- | --- | --- | --- | --- | --- |
     | `Ingress` | `balancer` | `80` | `TCP` | `Security group` | `vhosting-sg-balancer` |
     | `Ingress` | `ssh` | `22` | `TCP` | `CIDR` | `0.0.0.0/0` |

{% endlist %}

## Import TLS certificates of the websites to Certificate Manager {#import-certificates}

To access the websites using the secure HTTPS protocol (HTTP over TLS), you must have [TLS certificates](../../certificate-manager/concepts/managed-certificate.md) issued for them. To use the certificates in the L7 load balancer, import them to Certificate Manager.

If your websites do not have certificates, you can [use Certificate Manager to get them from Let's Encrypt<sup>®</sup>](../../certificate-manager/operations/managed/cert-create.md). You do not need to do anything else after creating certificates this way, because the certificates are imported automatically.

To import an existing certificate for `site-a.com`:

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select a folder.
  1. Navigate to **Certificate Manager**.
  1. Click **Add certificate** and select **User certificate**.
  1. Specify the certificate **Name**: `vhosting-cert-a`.
  1. In the **Certificate** field, click **Add certificate**. Upload the **File** with your certificate or enter its **Content** and click **Add**.
  1. If your certificate is issued by a third-party certificate authority, click **Add chain** in the **Intermediate certificate chain** field. Upload the **File** with the certificate chain or enter its **Content** and click **Add**.
  1. In the **Private key** field, click **Add private key**. Upload the **File** with the key or enter its **Content** and click **Add**.
  1. Click **Create**.

{% endlist %}

Similarly, import the certificates for `site-b.com` and `default.com` named `vhosting-cert-b` and `vhosting-cert-default`, respectively.

## Create instance groups for the websites {#create-vms}

Compute Cloud VMs will act as web servers for the two websites: one [group](../../compute/concepts/instance-groups/index.md) of multiple identical instances for each website. In this tutorial, the LEMP stack (Linux, NGINX, MySQL®, PHP) will be installed on the servers. For more information, see [LAMP or LEMP-based website](../../tutorials/web/lamp-lemp/index.md).

To create an instance group for `site-a.com`:

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select a folder.
  1. Navigate to **Compute Cloud**.
  1. In the left-hand panel, select ![image](../../_assets/console-icons/layers-3-diagonal.svg) **Instance groups**. Click **Create group of virtual machines**.
  1. Specify the VM group **Name**: `vhosting-ig-a`.
  1. Under **Allocation**, select multiple availability zones to ensure the fault tolerance of your hosting.
  1. Under **Instance template**, click **Define**.
  1. Under **Boot disk image**, open the **Marketplace** tab and click **Show all Marketplace products**. Select [LEMP](https://yandex.cloud/en/marketplace/products/yc/lemp) and click **Use**.
  1. Under **Computing resources**:
     * Choose a VM [platform](../../compute/concepts/vm-platforms.md).
     * Specify the required number of vCPUs and the amount of RAM.

     This minimum configuration will do for functional website testing:
     * **Platform**: `Intel Ice Lake`
     * **Guaranteed vCPU performance**: `20%`
     * **vCPU**: `2`
     * **RAM**: `1 GB`
  1. Under **Network settings**, select the **Network** named `vhosting-network` you [created earlier](#create-network) and its [subnets](../../vpc/concepts/network.md#subnet).
  1. In the **Public address** field, select `Auto`.
  1. Select the `vhosting-sg-vms` security group [created earlier](#create-security-groups).
  1. Specify the VM access data:
     * In the **Login** field, enter the username.
     * In the **SSH key** field, paste the contents of the public key file.

       You need to create a key pair for the SSH connection [by yourself](../../compute/operations/vm-connect/ssh.md).

     {% note alert %}

     Once created, the VM gets an IP address and a [host name (FQDN)](../../compute/concepts/network.md#hostname) for connections. If you selected `No address` in the **Public address** field, you will not be able to access the VM from the internet.

     {% endnote %}

  1. Click **Save**.
  1. Under **Scaling**, specify the instance group **Size**: `2`.
  1. Under **Integration with Application Load Balancer**, select **Create target group** and enter `vhosting-tg-a` as the group name. [Read more about target groups](../concepts/target-group.md).
  1. Click **Create**.

{% endlist %}

Follow the same steps to create a second instance group named `vhosting-ig-b` and a target group named `vhosting-tg-b` for `site-b.com`.

It may take a few minutes to create an instance group. As soon as the group changes its [status](../../compute/concepts/instance-groups/statuses.md#group-statuses) to `RUNNING`, and all its VMs to `RUNNING_ACTUAL`, you can [upload the website files to them](#upload-sites-files).

![ig-running](../../_assets/application-load-balancer/tutorials/virtual-hosting/ig-running.png)

## Upload the website files to the VMs {#upload-sites-files}

To test your web servers, upload `index.html` files with different contents to the VMs: one content version for the `vhosting-ig-a` instance group VMs, and another for the `vhosting-ig-b` instance group VMs.

{% cut "Example of the `index.html` file for the `vhosting-ig-a` group" %}

```html
<!DOCTYPE html>
<html>
  <head>
    <title>Site A</title>
  </head>
  <body>
    <p>This is site A</p>
  </body>
</html>
```

{% endcut %}

{% cut "Example of the `index.html` file for the `vhosting-ig-b` group" %}

```html
<!DOCTYPE html>
<html>
  <head>
    <title>Site B</title>
  </head>
  <body>
    <p>This is site B</p>
  </body>
</html>
```

{% endcut %}

To upload a file to a VM:

1. On the VM page of the [management console](https://console.yandex.cloud), under **Network**, find the VM's public IP address.
1. [Connect](../../compute/operations/vm-connect/ssh.md) to the VM over SSH.
1. Grant your user write permissions for the `/var/www/html` directory:

   {% list tabs group=operating_system %}

   - Ubuntu {#ubuntu}

     ```bash
     sudo chown -R "$USER":www-data /var/www/html
     ```

   - CentOS {#centos}

     ```bash
     sudo chown -R "$USER":apache /var/www/html
     ```

   {% endlist %}


1. Upload the website files to the VM via [SCP](https://en.wikipedia.org/wiki/Secure_copy_protocol).

   {% list tabs group=operating_system %}

   - Linux/macOS {#linux-macos}

     Use the `scp` command line utility:

     ```bash
     scp -r <path_to_directory_with_files> <VM_user_name>@<VM_IP_address>:/var/www/html
     ```

   - Windows {#windows}

     Use [WinSCP](https://winscp.net/eng/download.php) to copy the local file directory to `/var/www/html` on the VM.

   {% endlist %}

Repeat the above steps for the files you want to upload to each VM in the `vhosting-ig-a` and `vhosting-ig-b` groups.

## Create backend groups {#create-backend-groups}

Target groups created together with instance groups must be linked to the [backend groups](../concepts/backend-group.md) that define the traffic allocation settings.

For the backends, the groups will implement [health checks](../concepts/backend-group.md#health-checks): the load balancer will periodically send health check requests to the VMs and expect a response for a certain period.

To create a backend group for `site-a.com`:
1. In the [management console](https://console.yandex.cloud), select a folder.
1. Navigate to **Application Load Balancer**.
1. In the left-hand panel, select ![image](../../_assets/console-icons/cubes-3-overlap.svg) **Backend groups**. Click **Create backend group**.
1. Enter the backend group **Name**: `vhosting-bg-a`.
1. Under **Backends**, click **Add**.
1. Enter the backend **Name**: `vhosting-backend-a`.
1. In the **Target groups** field, select the `vhosting-tg-a` group.
1. Specify the **Port** the backend VMs will use to receive inbound traffic from the load balancer: `80`.
1. Click **Add health check**.
1. Specify the **Port** the backend VMs will use to accept health check connections: `80`.
1. Specify the **Path** the load balancer will use for health checks: `/`.
1. Click **Create**.

Follow the same steps to create a second backend group named `vhosting-bg-b` for `site-b.com`. In this group, create the `vhosting-backend-b` backend and link the `vhosting-tg-b` target group to it.

## Create and configure HTTP routers {#create-http-routers}

Backend groups must be linked to [HTTP routers](../concepts/http-router.md) that define the HTTP request routing rules. In this tutorial, you will create two routers for the main sites (`site-a.com` and `site-b.com`) and the default router for `default.com`, which will respond to each request with the `404 Not Found` HTTP status code.

### Create HTTP routers for the websites {#create-http-routers-sites}

To create an HTTP router for `site-a.com`:

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select a folder.
  1. Navigate to **Application Load Balancer**.
  1. In the left-hand panel, select ![image](../../_assets/console-icons/route.svg) **HTTP routers**. Click **Create HTTP router**.
  1. Specify the HTTP router **Name**: `vhosting-router-a`.
  1. Click **Add virtual host**.
  1. Specify the virtual host **Name**: `vhosting-host-a`.
  1. In the **Authority** field, specify the website domain name: `site-a.com`.
  1. Click **Add route**.
  1. Specify the route **Name**: `vhosting-route-a`.
  1. In the **Backend group** field, select the `vhosting-bg-a` group.
  1. Click **Create**.

{% endlist %}

Follow the same steps to create the `vhosting-router-b` HTTP router for `site-b.com` and link the `vhosting-bg-b` backend group to it.

### Create the default HTTP router {#create-http-routers-default}

To create an HTTP router for `default.com`:

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select a folder.
  1. Navigate to **Application Load Balancer**.
  1. In the left-hand panel, select ![image](../../_assets/console-icons/route.svg) **HTTP routers**. Click **Create HTTP router**.
  1. Specify the HTTP router **Name**: `vhosting-router-default`.
  1. Click **Add virtual host**.
  1. Specify the virtual host **Name**: `vhosting-host-default`.
  1. In the **Authority** field, specify the website domain name: `default.com`.
  1. Click **Add route**.
  1. Specify the route **Name**: `vhosting-route-a`.
  1. In the **Action** field, select `Response`.
  1. In the **HTTP status code** field, select `404 Not Found`.
  1. In the **Response body** field, click **Select**. Select the `Text` method and enter the following in the **Content** field:

     ```text
     404 Not Found

     This is the default site.
     ```

     Click **Add**.
  1. Click **Create**.

{% endlist %}

## Create an L7 load balancer {#create-l7-balancer}

To create a load balancer:

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select a folder.
  1. Navigate to **Application Load Balancer**.
  1. Click **Create L7 load balancer**.
  1. In the menu that opens, select **Manual**.
  1. Enter the load balancer **Name**: `vhosting-alb`.
  1. Under **Network settings**, select the `vhosting-sg-balancer` security group you [created earlier](#create-security-groups).
  1. Create a listener to redirect HTTP requests to HTTPS:
     1. Under **Listeners**, click **Add listener**.
     1. Enter the listener **Name**: `vhosting-listener-http`.
     1. Under **Public IP address**, select **Type** `List` and the IP address you [reserved earlier](#reserve-ip).
     1. In the **Protocol** field, select `Redirect to HTTPS`.
  1. Create an HTTPS request listener:
     1. Click **Add listener** again.
     1. Enter the listener **Name**: `vhosting-listener-https`.
     1. Under **Public IP address**, select **Type** `List` and the IP address you [reserved earlier](#reserve-ip).
     1. In the **Protocol** field, select `HTTPS`.
     1. Under **Main listener**, select `vhosting-cert-default` for the certificate and `vhosting-router-default` for the HTTP router.
     1. Add an SNI handler for `site-a.com`:
        1. Click **Add SNI match**.
        1. Specify the **Name** for the SNI handler: `vhosting-sni-a`.
        1. In the **Server names** field, specify `site-a.com`.
        1. Select `vhosting-cert-a` for the certificate and `vhosting-router-a` for the HTTP router.
     1. Follow the same steps to add an SNI handler for `site-b.com` with `vhosting-sni-b` as its name, `site-b.com` as the server name, the `vhosting-cert-b` certificate, and the `vhosting-router-b` HTTP router.
  1. Click **Create**.

{% endlist %}

## Configure DNS for the websites {#configure-dns}

The `site-a.com`, `site-b.com`, and `default.com` domain names must be mapped to the L7 load balancer IP address using DNS records.

To configure DNS for `site-a.com`:
1. In the [management console](https://console.yandex.cloud), select a folder.
1. Navigate to **Application Load Balancer**.
1. Copy the IP address of the load balancer that you created.
1. On the website of your DNS hosting provider, navigate to the DNS settings.
1. Create or edit the A record for `site-a.com` so that it points to the copied IP address:

   ```text
   site-a.com. A <L7_load_balancer_IP_address>
   ```

   If you use Yandex Cloud DNS, follow this guide to configure the record:

   {% cut "Configuring DNS records for Cloud DNS" %}

   {% list tabs group=instructions %}

   - Management console {#console}

     1. In the [management console](https://console.yandex.cloud), select a folder.
     1. Navigate to **Cloud DNS**.
     1. If you do not have a public [DNS zone](../../dns/concepts/dns-zone.md), create one:
        1. Click **Create zone**.
        1. Specify the zone **Name**: `vhosting-dns-a`.
        1. In the **Zone** field, enter the website domain name with a trailing dot: `site-a.com.`.
        1. Select a **Type** of the zone: `Public`.
        1. Click **Create**.
     1. Create a record in the zone:
        1. In the list of zones, click `vhosting-dns-a`.
        1. Click **Create record**.
        1. Leave the **Name** field empty for the record to match the `site-a.com` domain name (rather than a name with a subdomain, e.g., `www.site-a.com`).
        1. Select the record **Type**: **A**.
        1. In the **Data** field, paste the load balancer's IP address.
        1. Click **Create**.

   {% endlist %}

   {% endcut %}

Follow the same steps to configure DNS for `site-b.com` and `default.com` using the same IP address.

You can test your websites 15-20 minutes after you have configured DNS.

## Test the hosting {#test}

To test the hosting, open each of the three websites in your browser:
* For `https://site-a.com` and `https://site-b.com`, you should see the pages you [uploaded to the VMs](#upload-sites-files).
* For `https://default.com`, you should see the `404 Not Found` error page configured when [creating the HTTP router](#create-http-routers-default).

## Delete the resources you created {#clear-out}

To shut down the hosting and stop paying for the resources you created:
1. Delete the non-billable resources that block the deletion of billable resources:
   1. [Delete](../operations/application-load-balancer-delete.md) the `vhosting-alb` L7 load balancer.
   1. [Delete](../operations/http-router-delete.md) the `vhosting-router-a`, `vhosting-router-b`, and `vhosting-router-default` HTTP routers.
   1. [Delete](../operations/backend-group-delete.md) the `vhosting-bg-a` and `vhosting-bg-b` backend groups.
1. [Delete](../../compute/operations/instance-groups/delete.md) the `vhosting-ig-a` and `vhosting-ig-b` instance groups.
1. [Delete](../../vpc/operations/address-delete.md) the static public IP address that you reserved.
1. If you used Yandex Cloud DNS, [delete](../../dns/operations/resource-record-delete.md) the DNS records and [delete](../../dns/operations/zone-delete.md) the DNS zone.