> ## Documentation Index
> Fetch the complete documentation index at: https://docs.controlplane.com/llms.txt
> Use this file to discover all available pages before exploring further.

# GVC (Global Virtual Cloud)

> GVC configuration reference with YAML examples. Covers locations, pull secrets, domain assignment, environment variables, tracing, and load balancing.

## Overview

Refer to the [GVC concepts](/concepts/gvc) page.

## Create a GVC

Refer to the [Create a GVC](/guides/create-gvc) guide for additional details.

## GVC Configuration Example

Here's a comprehensive example of a GVC configuration that includes all available options:

```yaml theme={null}
kind: gvc
name: my-gvc
spec:
  staticPlacement:
    locationLinks:
      - //location/aws-us-west-2
      - //location/aws-eu-west-1
    locationOptions:
      - locationLink: //location/aws-us-west-2
        routingTier: 0
      - locationLink: //location/aws-eu-west-1
        routingTier: 1
        latencyToleranceMs: 500
  pullSecretLinks:
    - //secret/docker-registry-secret
    - //secret/ecr-secret
  endpointNamingFormat: org
  tracing:
    provider:
      controlplane: {}
    customTags:
      environment: production
    sampling: 10
  env:
    - name: ENVIRONMENT
      value: production
    - name: LOG_LEVEL
      value: info
  loadBalancer:
    dedicated: true
    trustedProxies: 1
    redirect:
      class:
        status5xx: https://error.example.com
        status401: https://auth.example.com/login?return_to=%REQ(:path)%
    ipSet: //ipset/my-ipset
  keda:
    enabled: true
    identityLink: //identity/keda-identity
    secrets:
      - //secret/keda-trigger-auth-1
      - //secret/keda-trigger-auth-2
```

## Switching between GVCs

Using the console, if an [Org](/reference/org) has multiple GVCs, there will be an angle bracket `>` to the right of the current GVC name in the left menu. Click the bracket to show and select a GVC.

## GVC Namespace

The GVC namespace is used when constructing the canonical endpoint and individual location endpoints to avoid naming collision between workloads with the same name in different GVCs. The namespace is also used when performing [service-to-service](/guides/service-to-service) calls.

## GVC Locations

The cloud provider [locations](/reference/location) that [workloads](/concepts/workload) will be served from are mapped to a GVC. At least one location is required. The global and canonical endpoints will use DNS to route the request to the nearest healthy location.

<Note>Adding a location immediately provisions it for all workloads. Removing a location gracefully terminates running replicas in that location and shifts traffic to remaining healthy locations. DNS updates propagate automatically.</Note>

The available [locations](/reference/location) are scoped to an org and can be enabled/disabled globally. Any changes to the location at the org will be propagated to all GVCs using that location.

## Location Routing Options

You can configure per-location routing options to control how DNS geo-routing selects locations for traffic. This enables scenarios such as primary/failover locations and fine-tuning traffic distribution across locations.

Location routing options are configured in `spec.staticPlacement.locationOptions`, which is an array of objects, each specifying a location and its routing parameters. Each GVC independently controls these options, so the same location can have different routing behavior in different GVCs.

### Configuration

```yaml theme={null}
spec:
  staticPlacement:
    locationLinks:
      - //location/aws-us-west-2
      - //location/aws-eu-west-1
      - //location/aws-ap-southeast-1
    locationOptions:
      - locationLink: //location/aws-us-west-2
        routingTier: 0
      - locationLink: //location/aws-eu-west-1
        routingTier: 0
        latencyOffsetMs: -5
      - locationLink: //location/aws-ap-southeast-1
        routingTier: 1
        latencyToleranceMs: 300
```

### Location Options Properties

* **`locationLink`** (required): A link to the location this option applies to. Must use the same link format as `locationLinks` (e.g., `//location/aws-us-west-2`). Must be unique across all items in the `locationOptions` array.
* **`routingTier`** (optional): An integer (minimum 0) that controls location priority for DNS geo-routing. Lower values indicate higher priority. Locations with the same priority form a group. Within a group, the location with the lowest measured latency is selected. If all locations in the highest-priority group are unavailable, the next priority group is used, and so on. Locations without an explicit priority are treated as lowest priority when any other location has an explicit priority set.
* **`latencyOffsetMs`** (optional): An integer in milliseconds that is added to the measured latency for this location. Positive values make the location appear farther away (pushing traffic to other locations), while negative values make it appear closer (attracting more traffic). This can be used to fine-tune traffic distribution percentages across locations. Default: 0.
* **`latencyToleranceMs`** (optional): An integer in milliseconds. If the measured latency to a location exceeds this threshold, the location is treated as unavailable for DNS geo-routing. This can be used to ensure that traffic is only routed to locations that meet a performance requirement.

<Note>If all locations are filtered out by their latency thresholds, the thresholds are ignored and all locations remain candidates. This safety mechanism ensures that traffic is never left without a destination.</Note>

### Priority-Based Failover Example

Configure primary and failover locations so that traffic only goes to the failover when all primary locations are down:

```yaml theme={null}
spec:
  staticPlacement:
    locationLinks:
      - //location/aws-us-east-1
      - //location/aws-us-west-2
      - //location/aws-eu-west-1
    locationOptions:
      - locationLink: //location/aws-us-east-1
        routingTier: 0
      - locationLink: //location/aws-us-west-2
        routingTier: 0
      - locationLink: //location/aws-eu-west-1
        routingTier: 1
```

In this configuration, `aws-us-east-1` and `aws-us-west-2` are primary locations (priority 0). Traffic is routed to whichever has the lowest latency. If both primary locations become unavailable, traffic fails over to `aws-eu-west-1` (priority 1).

### Latency Tuning Example

Use `latencyOffsetMs` to shift traffic distribution without changing priority:

```yaml theme={null}
spec:
  staticPlacement:
    locationLinks:
      - //location/aws-us-east-1
      - //location/aws-us-west-2
    locationOptions:
      - locationLink: //location/aws-us-east-1
        latencyOffsetMs: -10
      - locationLink: //location/aws-us-west-2
        latencyOffsetMs: 10
```

This configuration makes `aws-us-east-1` appear 10ms closer and `aws-us-west-2` appear 10ms farther, shifting more traffic toward the east coast location.

## Load Balancer Configuration

The `loadBalancer` property allows you to configure load balancing settings for the GVC.

### Dedicated Load Balancer

When a dedicated load balancer is enabled on a GVC:

* All inbound traffic is routed through a custom cloud load balancer for each enabled location
* Additional charges apply per location
* Any [domains](/reference/domain) configured to route traffic to this GVC will also leverage the custom load balancer
* The following additional [domain](/reference/domain#dedicated-load-balancer-options) features become available:
  * [Custom Ports](/reference/domain#custom-ports): Route TCP traffic on a variety of ports
  * [Accept All Hosts](/reference/domain#accept-all-hosts): Accept traffic for any hostname

<Note>Enabling or disabling the dedicated load balancer can cause a brief period of connectivity failure during DNS propagation.</Note>

### Load Balancer Properties

* **`dedicated`**: Creates a dedicated load balancer in each location and enables additional Domain features: custom ports, protocols and wildcard hostnames. Charges apply for each location.
* **`multiZone.enabled`**: Enable/Disable multi-zone load balancing. Cross zone charges apply.
* **`trustedProxies`**: Controls the address used for request logging and for setting the X-Envoy-External-Address header. Valid values are 0, 1, or 2.
  * `0` (default): Use the source client IP address
  * `1`: Use the last address in an existing X-Forwarded-For header
  * `2`: Use the second to last address in an existing X-Forwarded-For header
* **`ipSet`**: A link to an [IP Set](/reference/ipset) that reserves a static public IP per location for this load balancer.

### Load Balancer Access Logs

You can view access logs for the load balancer by navigating to the logs page in the console and filtering by `{gvc="<GVC_NAME>",workload="_loadbalancer"}`.

### Redirect Configuration

When a dedicated load balancer is enabled on a GVC, you can specify URLs to redirect users for different HTTP status codes.

<Tabs>
  <Tab title="YAML">
    ```yaml theme={null}
    kind: gvc
    name: example-gvc
    spec:
      loadBalancer:
        dedicated: true
        redirect:
          class:
            status5xx: https://redirect.example.com
            status401: https://your-oauth-server/oauth2/authorize?return_to=%REQ(:path)%&client_id=your-client-id
    ```
  </Tab>

  <Tab title="JSON">
    ```json theme={null}
    {
      "kind": "gvc",
      "name": "example-gvc",
      "spec": {
        "loadBalancer": {
          "dedicated": true,
          "redirect": {
            "class": {
              "status5xx": "https://redirect.example.com",
              "status401": "https://your-oauth-server/oauth2/authorize?return_to=%REQ(:path)%&client_id=your-client-id"
            }
          }
        }
      }
    }
    ```
  </Tab>
</Tabs>

#### Redirect Properties

* **`class.status5xx`**: Specify the redirect URL for any 500 level status code. Must be a valid URI.
* **`class.status401`**: An optional URL redirect for 401 responses. Supports Envoy format strings to include request information (e.g., `%REQ(:path)%`).

### Static IP Addresses

By default, the public IP assigned to each location is not reserved and may change. To assign a static public IP per location, link an [IP Set](/reference/ipset) to the dedicated load balancer via `loadBalancer.ipSet`.

<Tabs>
  <Tab title="YAML">
    ```yaml theme={null}
    kind: gvc
    name: example-gvc
    spec:
      loadBalancer:
        dedicated: true
        ipSet: //ipset/example
    ```
  </Tab>

  <Tab title="JSON">
    ```json theme={null}
    {
      "kind": "gvc",
      "name": "example-gvc",
      "spec": {
        "loadBalancer": {
          "dedicated": true,
          "ipSet": "//ipset/example"
        }
      }
    }
    ```
  </Tab>
</Tabs>

<Note>The IP Set must be [configured](/reference/ipset#gvc) to reference this GVC.</Note>

## Endpoint Naming Format

Workload canonical endpoints in this GVC can be prefixed with the [org endpoint prefix](/reference/org#endpoint-prefix). This adds the prefix as a subdomain to `cpln.app`. To configure which endpoint prefix to use, set the endpointNamingFormat field:

```yaml theme={null}
spec:
  endpointNamingFormat: org # can be "org" or "default"
```

### Canonical Endpoint Formatting

* `default`: \{workloadName}-\{gvcAlias}.cpln.app
* `org`: \{workloadName}-\{gvcAlias}.\{orgEndpointPrefix}.cpln.app

## Tracing

OpenTelemetry traces are supported and can be configured with the native `Control Plane` tracing provider or sent to an OpenTelemetry collector endpoint by using the `OpenTelemetry` tracing provider.

### Control Plane Tracing Provider

The Control Plane tracing provider is the default method for collecting OpenTelemetry traces. They will be accessible for exploration using Grafana by accessing the `Traces` link from any workload in the Console.

To enable traces using the Console, navigate to your GVC, click on `Tracing`, and choose `Control Plane` as the metric provider. Then, configure the sampling percentage and, optionally, the Custom Tags.

When using the Control Plane tracing provider, workloads can forward additional Open Telemetry traces to the following endpoints:

GRPC: `tracing.controlplane:80`

HTTP: `tracing.controlplane:4318`

For each of these endpoints, mutual tls is added automatically for requests and any clients/libraries should be configured to send requests using plain text.

Here is an example of a GVC with tracing enabled for 10 percent of requests to be forwarded to the Control Plane tracing provider. Additionally, the tag `team`=`profile` will also be added to each trace.

```yaml YAML theme={null}
kind: gvc
name: online-boutique
spec:
...
  tracing:
    provider:
      controlplane: {}
    customTags: {
      team: profile
    }
    sampling: 10
```

### OpenTelemetry Tracing Provider

Similarly, traces can be sent to an OTEL collector endpoint using the `OpenTelemetry` tracing provider.

For details, see the [Online Boutique](https://github.com/controlplane-com/examples/blob/main/examples/online-boutique/README.md) example.

## Pull Secrets

Pull secrets are [secrets](/reference/secret) that are assigned to a GVC and used by [workloads](/concepts/workload) when authentication is required when pulling an image from a private registry.

Only [Docker](/reference/secret#docker), [Amazon ECR](/reference/secret#ecr), and [GCP](/reference/secret#google-cloud-platform-gcp) secrets types are supported for pull secrets.

<Tip>
  If the image was pushed to the Control Plane registry for the same [Org](/reference/org), no pull secret is required when a workload pulls from the image from the same Org.
</Tip>

Multiple pull secrets can be assigned to a GVC. A [workload's container](/reference/workload/containers) will use the appropriate secret when pulling the image from a private registry. If there are multiple secrets, the container will cycle through each one.

If authentication fails, the deployment will not be updated and the image pull will have an exponential backoff retry starting at 10 seconds and ending at 5 minutes (e.g., 10 seconds, 20 seconds, 40 seconds, etc.).

## Environment Variables

You may set environment variables at the GVC level, which can then be inherited by any of the GVC's workloads. To inherit GVC environment variables, a container must have its `inheritEnv` property set to true. For more information about how environment variables work in Control Plane, please see the environment variables section of the [workload reference](/reference/workload#environment-variables) page.

## Sticky Sessions

Add the following [tags](/core/misc#tags) and desired values to a GVC to enable sticky sessions for **ALL** [Workloads](/concepts/workload) within the GVC:

1. `cpln/sessionCookie`
   * The name of the session cookie.
2. `cpln/sessionDuration`
   * The Golang duration for the maximum session length (e.g., 300s, 30m, etc.).
   * Review this [link](https://pkg.go.dev/time#ParseDuration) for the proper Golang duration string format.

Once these tags are set, soft session affinity based on a cookie will consistently route requests to the same replica. The affinity to a particular replica will be lost if the replica restarts.

### How to add Tags using the UI

1. Browse to the [Console UI](https://console.cpln.io/) and select the desired GVC.
2. Click the `Tags` link in the middle context menu.
3. Click `Edit Tags`.
4. Enter the string `cpln/sessionCookie` in the `Tag Key` text box and enter the desired cookie name in the `Tag Value` text box. Click `Add Tag`.
5. Enter the string `cpln/sessionDuration` in the `Tag Key` text box and enter the desired duration in the `Tag Value` text box. Click `Add Tag`.
6. Click `Save`.

### How to add Tags using the CLI

Execute the following CLI command (substitute the GVC\_NAME, ORG\_NAME, COOKIE\_NAME, DURATION tokens) to add the requires Tags to a GVC:

```bash theme={null}
cpln gvc tag GVC_NAME --tag cpln/sessionCookie=COOKIE_NAME --tag cpln/sessionDuration=DURATION --org ORG_NAME
```

## Keda

In order to use Keda to scale workloads, you must first enable it on the GVC.
If the keda deployment requires network or cloud resources, you must attach a valid identity on the keda configuration here.

```yaml theme={null}
spec:
  keda:
    enabled: true
    identityLink: //identity/keda-identity # optional
    secrets: # optional
      - //secret/keda-secret-1
      - //secret/keda-secret-2
```

### Keda Configuration

* **`enabled`**: Enable KEDA for this GVC. KEDA is a Kubernetes-based event-driven autoscaler that allows you to scale workloads based on external events. When enabled, a keda operator will be deployed in the GVC and workloads in the GVC can use KEDA to scale based on external metrics.
* **`identityLink`**: A link to an Identity resource that will be used for KEDA. This will allow the keda operator to access cloud and network resources.
* **`secrets`**: A list of secrets to be used as TriggerAuthentication objects. The TriggerAuthentication object will be named after the secret and can be used by triggers on workloads in this GVC.

## Export GVC

Using the console UI, when a GVC is selected, an `Export GVC` link is available which will save (as a local multi-document YAML manifest file) the GVC and all associated resources ([Identities](/reference/identity), [Volume Sets](/reference/volumeset) and [Workloads](/concepts/workload)).

Links to other resources are relative within the exported file. This allows the file to be easily used to backup and restore an entire GVC. It can also be used when promoting to other [Orgs](/reference/org).

The export doesn't contain any referenced [Org](/reference/org) resources, such as, [Secrets](/reference/secret), [Cloud Accounts](/reference/cloudaccount), and [Agents](/reference/agent). These resources would need to be exported separately.

## Permissions

The permissions below are used to define [policies](/reference/policy) together with one or more of the four [principal types](/concepts/access-control):

| Permission | Description          | Implies                            |
| :--------- | :------------------- | :--------------------------------- |
| create     | Create new gvcs      |                                    |
| delete     | Delete existing gvcs |                                    |
| edit       | Modify existing gvcs | view                               |
| manage     | Full access          | create, delete, edit, manage, view |
| view       | Read-only access     |                                    |

## Access Report

Displays the permissions granted to principals for the GVC.

## CLI

To view the CLI documentation for GVCs, see the [GVC CLI reference](/cli-reference/commands/gvc).
