# Configure Multiple Origins with Load Balancing

import Tabs from '~/components/tabs/Tabs'
import Apiv4Rollout from '~/includes/snippets/apiv4Rollout/en/snippet.mdx'
import Code from '~/components/Code/Code.astro'

<Apiv4Rollout />

When you [create an application](/en/documentation/products/start-with-a-template/), you need to define an origin. However, more complex and robust infrastructures may need multiple origins for the same application. The [Load Balancer](/en/documentation/products/secure/connectors/load-balancer/) feature allows you to use load balancing algorithms to manage high access numbers and control the behaviors of your origin.

:::caution[warning]
If **Load Balancer** is activated, data transfer could generate usage-related costs. Check the [pricing page](/en/documentation/products/pricing/) for more information.
:::

There are separate instructions for API v3 using [legacy Origin](/en/documentation/products/build/applications/origins/) settings and API v4 using the new [Connectors](/en/documentation/products/secure/connectors) product.

:::tip
In this guide, there are separate instructions for API v3 and API v4. If you're not sure which steps apply to your account, see [the Verify Your Account Migration guide](/en/documentation/products/guides/verify-account-migration/) to determine if your account has already been migrated.
:::

The following steps will walk you through a hypothetical scenario where the default origin should be of the Load Balancer-type with the [Round Robin algorithm](/en/documentation/products/secure/connectors/load-balancer/#balancing-method). Feel free to interpret and modify the step-by-step instructions according to your specific use case.

The following business rules of different origin servers must be configured with load balancing:

- The application should have three origins.
  - The primary server should have a higher load capacity.
  - The secondary server should have a medium load capacity, enough to handle large surges of incoming traffic.
  - The backup server should have a low load capacity and only be active in special circumstances.
- Each of these servers should be hosted in a different storage provider or cloud service since server outages don't often occur simultaneously.
- All origins must contain the same content and be set up in the exact same way for the application.

Therefore, the setup would be:

| Origin | Role | Address | Load capacity | Status |
| --- | --- | --- | --- | --- |
| 1 | Primary server | `example.com` | High load capacity | Should always be active. |
| 2 | Secondary server | `example.net` | Medium load capacity | Should always be active. |
| 3 | Backup server | `example.org` | Low load capacity | Should only be active in case of maintenance or traffic surges. |

---

<Tabs client:visible>
    <Fragment slot="tab.consoleedgeconnector">Console - Connectors</Fragment>
    <Fragment slot="tab.consoleorigins">Console - Origins</Fragment>
    <Fragment slot="tab.apiv4">API v4</Fragment>
    <Fragment slot="tab.apiv3">API v3</Fragment>

<Fragment slot="panel.consoleedgeconnector">

Now you need to configure a new **Connector** to link your application to your Object Storage bucket. To do so:

1. [Access Azion Console](/en/documentation/products/guides/how-to-access-azion-console/) > **Connectors**.
2. Click the **+ + Connector** button.
3. In the **General** section, give your connector a unique and descriptive name (for example, `Multiple Origins Connector`).
4. In the **Connector Type** section, select **HTTP**.
5. Enable the **Load Balancer** switch, this enables you to add multiple addresses.
6. In the **Method** field, select **Round-Robin**.
7. In the first **Address** field, specify the primary server. For example, `example.com`.
8. Since this origin has a higher load capacity, in the **Weight** field, add a weight of `3` to this first origin.
9. In the **Server Role** field, keep **Primary** selected.
10. Keep this address **Active**.
11. In the second **Address** field, specify the secondary server. In this case, `example.net`.
12. Due to its lower capacity, in the **Weight** field, add a weight of `2` to this address.
13. In the **Server Role** field, select **Primary**. This address has a lower weight value, so the preferred address for connections will be the first.
14. Keep this address **Active**.
15. Add a third origin by clicking the **+ Add Address** button.
16. In the **Address** field, specify the backup origin. In this case, `example.org`.
17. Keep the **Weight** field blank. It'll assume a default value of `1`.
18. In the **Server Role** field, select **Backup**.
19. Disable this address by turning off the **Active** switch.
20. Click the **Save** button.

To activate the Connector in your application:

1. Access the **Rules Engine** tab.
2. Edit the default rule or add a new request rule.
3. In the **Criteria** section, to apply the Connector for your whole application, set the **criteria** to `If ${uri} starts with /`.
4. In the **Behavior** section, select the **Set Connector** behavior.
5. Select the Connector you want to apply.
6. Click the **Save** button.
7. Wait some time for the changes to propagate to the edge. Then, access your application or use the command line to make a request and check if the changes were made.

</Fragment>

<Fragment slot="panel.consoleorigins">

First, to enable the **Load Balancer** module:

1. Access [Azion Console](/en/documentation/products/guides/how-to-access-azion-console/) > **Applications**.
2. Click the application for which you want to configure a new origin with load balancer.
3. On the **Main Settings** tab, under **Modules**, activate **Load Balancer**.
4. Click the **Save** button.

:::caution[warning]
In this section, you'll modify your default origin, which is of the Single Origin-type, into a Load Balancer-type origin. Editing your default origin will override the origin you configured when creating the application. To create a different origin, see [how to work with origins](/en/documentation/products/guides/build/work-with-origins/).
:::

To customize the origin according to the scenario described above:

1. Select the **Origins** tab.
2. In the **Origins** tab, click the **Default Origin** from the list.
3. Give your new origin a name.
4. Under **Type**, select **Load Balancer**.
5. In the **Method** field, select **Round-Robin**.
6. In the first **Address** field, specify the primary server. For example, example.com`.
7. Since this origin has a higher load capacity, in the **Weight** field, add a weight of `3` to this first origin.
8. In the **Server Role** field, keep **Primary** selected.
9. Keep this origin **Active**.
10. In the second **Address** field, specify the secondary server. In this case, `example.net`.
11. Due to its lower capacity, in the **Weight** field, add a weight of `2` to this origin.
12. In the **Server Role** field, select **Primary**. This origin has a lower weight value, the preferred origin for connections will be the first.
13. Keep this origin **Active**.
14. Add a third origin by clicking the **+ Add Origin** button.
15. In the **Address** field, specify the backup origin. In this case, `example.org`.
16. Keep the **Weight** field blank. It'll assume a default value of `1`.
17. In the **Server Role** field, select **Backup**.
18. Disable this origin by turning off the **Active** switch.
19. Click the **Save** button.

Wait a few minutes for the changes to propagate. Then, access your application or use the command line to make a request and check if the changes were made.
</Fragment>

<Fragment slot="panel.apiv4">

1. Run the following `POST` request in your terminal, replacing `[TOKEN VALUE]` with your [personal token](/en/documentation/products/guides/personal-tokens/) to create an Connector.

<Code lang="bash" code={`curl --request POST \
  --url https://api.azion.com/v4/edge_connector/connectors \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
    "name": "Multiple Origins Connector",
    "active": true,
    "type": "http",
    "attributes": {
      "addresses": [
        {
          "active": true,
          "address": "example.com",
          "http_port": 80,
          "https_port": 443,
          "modules": {
            "load_balancer": {
              "server_role": "primary",
              "weight": 3
            }
          }
        },
        {
          "active": true,
          "address": "example.net",
          "http_port": 80,
          "https_port": 443,
          "modules": {
            "load_balancer": {
              "server_role": "primary",
              "weight": 2
            }
          }
        },
        {
          "active": false,
          "address": "example.org",
          "http_port": 80,
          "https_port": 443,
          "modules": {
            "load_balancer": {
              "server_role": "backup"
            }
          }
        }
      ],
      "connection_options": {
        "dns_resolution": "preserve",
        "transport_policy": "preserve",
        "http_version_policy": "http1_1",
        "host": "\${host}",
        "path_prefix": "",
        "following_redirect": false,
        "real_ip_header": "X-Real-IP",
        "real_port_header": "X-Real-PORT"
      },
      "modules": {
        "load_balancer": {
          "enabled": true,
          "config": {
            "method": "round_robin",
            "max_retries": 0,
            "connection_timeout": 60,
            "read_write_timeout": 120
          }
        },
        "origin_shield": {
          "enabled": false,
          "config": null
        }
      }
    }
  }'
  `} />

2. You should receive a response confirming the creation of your Connector, then copy the ID field. This will be used in the following step.
3. Run the following `POST` request in your terminal to create a **Rules Engine** rule. This will bind your Connector to your Applications, replacing the `<application_id>` variable with the Applications ID and the `<connector_id>` with the Connector ID you copied previously: 
3. Run the following `POST` request in your terminal to create a **Rules Engine** rule. This will bind your Connector to your Applications, replacing the `<application_id>` variable with the Applications ID and the `<connector_id>`with the Connector ID you copied previously: 

<Code lang="bash" code={`curl --request POST \
  --url https://api.azion.com/v4/edge_application/applications/<application_id>/request_rules \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "string",
  "active": true,
  "criteria":
    [
      {
        "conditional": "if",
        "variable": "\${uri}",
        "operator": "starts_with",
        "argument": "/"
      }
    ]
  ],
  "behaviors": [
    {
      "type": "set_edge_connector",
      "attributes": {
        "value": "<connector_id>"
      }
    }
  ]
}'
`} />

</Fragment>


<Fragment slot="panel.apiv3">
1. Run the following `GET` request in your terminal, replacing `[TOKEN VALUE]` with your [personal token](/en/documentation/products/guides/personal-tokens/) and `<application_id>` variable with [your application ID](/en/documentation/products/guides/build/configure-main-settings/) to retrieve your default origin's `<origin_key>`, which is a UUID value:

<Code lang="bash" code={`curl --location 'https://api.azionapi.net/edge_applications/<application_id> \
--header 'Accept: application/json; version=3' \
--header 'Authorization: Token [TOKEN VALUE]'
`} />

2. You'll receive a response similar to this:

<Code lang="json" code={`{
    "results": {
        "origin_id": <origin_id>,
        "origin_key": "<origin_key>",
        "name": "Default Origin",
        "origin_type": "single_origin",
        ...
    }
}
`} />

3. Copy the `<origin_key>` value.
4. Run the following `PATCH` request to modify the default origin as follows, replacing the key and application id in the URL:

<Code lang="bash" code={`curl --location --request PATCH 'https://api.azionapi.net/edge_applications/<application_id>/origins/<origin_key>' \
--header 'Accept: application/json; version=3' \
--header 'Content-Type: application/json' \
--header 'Authorization: Token [TOKEN VALUE]' \
--data '{
    "name": "Default Origin (RR3)",
    "origin_type": "load_balancer",
    "addresses": [
        {
            "address": "example.com",
            "weight": 3,
            "server_role": "primary",
            "is_active": true
        },
        {
            "address": "example.net",
            "weight": 2,
            "server_role": "primary",
            "is_active": true
        },
        {
            "address": "example.org",
            "weight": 1,
            "server_role": "backup",
            "is_active": false
        }
    ],
    "host_header": "\${host}",
    "method": "round_robin"
}'
`} />

5. You'll receive a response similar to this, confirming the changes have been made:

<Code lang="json" code={`{
    "results": {
        "origin_id": <origin_id>,
        "origin_key": "<origin_key>",
        "name": "Default Origin (RR3)",
        "origin_type": "load_balancer",
        "addresses": [
            {
                "address": "example.com",
                "weight": 3,
                "server_role": "primary",
                "is_active": true
            },
            {
                "address": "example.net",
                "weight": 2,
                "server_role": "primary",
                "is_active": true
            },
            {
                "address": "example.org",
                "weight": 1,
                "server_role": "primary",
                "is_active": false
            }
        ]
        "host_header": "\${host}",
        "method": "round_robin"
        ...
    }
}
`} />

6. Wait a few minutes for the propagation to occur.

:::tip
Check the [Azion API documentation](https://api.azion.com/) and the [OpenAPI specification](https://github.com/aziontech/azionapi-openapi/) to know more about all features available via API.
:::
</Fragment>

</Tabs>