> ## Documentation Index
> Fetch the complete documentation index at: https://controlplanecorporation-majid-docs-content-expansion.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 1. Deploy your first workload

> Create a GVC, deploy the official NGINX image as a workload across two cloud providers, and open it on a globally load-balanced TLS endpoint.

## Overview

Everything on Control Plane starts with a Global Virtual Cloud ([GVC](/concepts/gvc)), the set of [locations](/concepts/location) your applications run in, and a [workload](/concepts/workload), one application that Control Plane runs in every one of those locations. This part creates a GVC that spans an AWS region and a GCP region, and one workload that runs in both, with a [replica](/concepts/replica) in each location. The workload's endpoint terminates TLS, sends each request to the [nearest healthy location](/reference/gvc#location-routing-options), and routes around a location that fails, so one workload definition gives you a multi-cloud deployment that survives the loss of a region or a provider.

**What you'll build:**

* A GVC spanning AWS and GCP locations.
* A public workload serving the NGINX welcome page from both locations.
* A TLS-secured [global endpoint](/reference/workload/general#canonical-endpoint-global) that routes each request to the nearest healthy location.

<img src="https://mintcdn.com/controlplanecorporation-majid-docs-content-expansion/6V8SaiZLWK_iHnrB/images/quickstart/first-workload.svg?fit=max&auto=format&n=6V8SaiZLWK_iHnrB&q=85&s=e681598bfc22fc70645e8a913b79eff6" alt="The workload web is created in the GVC quickstart-gvc, and the GVC spans two locations, aws-us-west-2 on AWS and gcp-us-east1 on Google Cloud. One workload, created once, running in two clouds behind one endpoint." style={{maxWidth:'720px',width:'100%',margin:'1.75rem auto',display:'block'}} width="720" height="222" data-path="images/quickstart/first-workload.svg" />

<Tabs>
  <Tab title="Console" icon="display">
    ## Prerequisites

    * An [org](/reference/org) to deploy into. If you don't have one yet, [sign up](https://console.cpln.io/signup) for Control Plane: the Console walks you through creating a [billing account](/concepts/billing) and your first org.

    ## Step 1: Log in to the Console

    Navigate to [console.cpln.io](https://console.cpln.io) and sign in with your SSO provider. Your organization's dashboard opens.

    ## Step 2: Create a GVC

    A GVC defines where your workloads run across cloud providers and regions.

    <Steps>
      <Step title="Open the Create GVC form">
        Click the `Create` dropdown in the upper right corner and select `GVC`.
      </Step>

      <Step title="Name the GVC">
        Enter `quickstart-gvc` as the name.
      </Step>

      <Step title="Select locations">
        Click `Locations`, then click `Add Location`. Select `aws-us-west-2` and `gcp-us-east1` to deploy across both AWS and GCP, then click `OK`.
      </Step>

      <Step title="Create the GVC">
        Click `Create`. When the Console asks `Set as Current Context?`, click `Yes, Set Context` to browse this GVC's workloads, identities, and volume sets from the sidebar.
      </Step>
    </Steps>

    ## Step 3: Create a workload

    A workload is your application running on Control Plane.

    <Steps>
      <Step title="Navigate to Workloads">
        Click `Workloads` in the left menu, then click `New`.
      </Step>

      <Step title="Configure basic settings">
        Enter `web` as the name and confirm the GVC dropdown under the description field shows `quickstart-gvc`.
      </Step>

      <Step title="Configure the container">
        Click `Containers`. For the image source, select `External`, then enter:

        ```text theme={null}
        nginx:alpine
        ```

        Under `Ports`, set the number to `80` and keep the protocol `http`.
      </Step>

      <Step title="Make the workload public">
        Click `Firewall`, then click `Make Public` to allow external access.
      </Step>

      <Step title="Create the workload">
        Click `Create`. The workload summary page opens.
      </Step>
    </Steps>

    ## Step 4: Open the welcome page

    <Steps>
      <Step title="Wait for deployment">
        The workload health shows `Ready` once the first deployment completes.
      </Step>

      <Step title="Open the canonical endpoint">
        In the summary, under `Endpoints`, click the link next to `Canonical Endpoint (Global)`. The NGINX welcome page opens in a new window, served from the location nearest to you.
      </Step>

      <Step title="View individual deployments">
        Click `Deployments` in the left pane. Each location lists its own endpoint; click the link icon next to it to open that specific deployment.
      </Step>
    </Steps>
  </Tab>

  <Tab title="CLI" icon="terminal">
    ## Prerequisites

    * An [org](/reference/org) to deploy into. If you don't have one yet, [sign up](https://console.cpln.io/signup) for Control Plane: the Console walks you through creating a [billing account](/concepts/billing) and your first org.

    ## Step 1: Install the CLI

    <Tabs>
      <Tab title="npm">
        ```bash theme={null}
        npm install -g @controlplane/cli
        ```

        <Note>Requires [Node.js](https://nodejs.org/en/download/) version 18 or later (an active LTS release is recommended).</Note>
      </Tab>

      <Tab title="Homebrew">
        ```bash theme={null}
        brew tap controlplane-com/cpln && brew install cpln
        ```
      </Tab>

      <Tab title="Binary">
        <Card title="Download the binary" icon="download" href="/cli-reference/installation#binary" horizontal>
          Pick your platform on the installation page.
        </Card>
      </Tab>
    </Tabs>

    Confirm the installation:

    ```bash theme={null}
    cpln --version
    ```

    The CLI version number prints.

    ## Step 2: Authenticate

    Log in to Control Plane:

    ```bash theme={null}
    cpln login
    ```

    The CLI prints a login URL and a six-digit confirmation code, then waits. Open the URL in a browser on any device, sign in, and enter the code. After the CLI confirms the login, set your default org (replace `my-org` with your org name):

    ```bash theme={null}
    cpln profile update default --org my-org
    ```

    ## Step 3: Create a GVC

    Create a GVC with locations in AWS and GCP:

    ```bash theme={null}
    cpln gvc create --name quickstart-gvc \
      --location aws-us-west-2 \
      --location gcp-us-east1
    ```

    Set it as your default GVC:

    ```bash theme={null}
    cpln profile update default --gvc quickstart-gvc
    ```

    ## Step 4: Create the workload

    Create a public workload running the official NGINX image:

    ```bash theme={null}
    cpln workload create --name web \
      --image nginx:alpine \
      --port 80 \
      --public
    ```

    ## Step 5: Open the welcome page

    Wait for the workload to become ready:

    ```bash theme={null}
    cpln workload get web
    ```

    When the `READY` column shows `true`, open the welcome page in your browser:

    ```bash theme={null}
    cpln workload open web
    ```

    <Tip>
      The output of `cpln workload get` also shows the workload's global endpoint URL.
    </Tip>

    Check the deployment in each location:

    ```bash theme={null}
    cpln workload get-deployments web
    ```
  </Tab>

  <Tab title="Terraform" icon="https://mintcdn.com/controlplanecorporation-majid-docs-content-expansion/Ry1Mkgc7uPHC-gur/icons/terraform.svg?fit=max&auto=format&n=Ry1Mkgc7uPHC-gur&q=85&s=19deabd5e978d39905a6c83ea1f7904d" width="256" height="291" data-path="icons/terraform.svg">
    ## Prerequisites

    * An [org](/reference/org) to deploy into. If you don't have one yet, [sign up](https://console.cpln.io/signup) for Control Plane: the Console walks you through creating a [billing account](/concepts/billing) and your first org.

    - [Terraform](https://www.terraform.io/downloads.html) installed.

    ## Step 1: Authenticate

    The provider needs credentials for Control Plane. Choose one of the following methods:

    <Tabs>
      <Tab title="CLI Profile">
        With the [Control Plane CLI](/cli-reference/installation) installed, log in:

        ```bash theme={null}
        cpln login
        ```

        This creates a profile named `default` with your credentials, which the provider configuration references.
      </Tab>

      <Tab title="Service Account Token">
        For CI/CD pipelines or environments without the CLI, create a service account token:

        <Steps>
          <Step title="Create the service account">
            In the [Console](https://console.cpln.io), click `Service Accounts` in the left menu, then `New`. Enter a name, select `superusers` from the `Assign to Group` dropdown, and click `Create`.
          </Step>

          <Step title="Create a key">
            Click `Keys`, add a description, and click `Add`. Copy the generated key; it is not shown again.
          </Step>

          <Step title="Export the token">
            ```bash theme={null}
            export CPLN_TOKEN=your-service-account-key
            ```
          </Step>
        </Steps>
      </Tab>
    </Tabs>

    ## Step 2: Configure the provider

    Create a new directory and add `main.tf` with the provider configuration:

    <Tabs>
      <Tab title="CLI Profile">
        ```hcl theme={null}
        terraform {
          required_providers {
            cpln = {
              source = "controlplane-com/cpln"
            }
          }
        }

        provider "cpln" {
          org     = "my-org"
          profile = "default"
        }
        ```
      </Tab>

      <Tab title="Service Account Token">
        ```hcl theme={null}
        terraform {
          required_providers {
            cpln = {
              source = "controlplane-com/cpln"
            }
          }
        }

        provider "cpln" {
          org = "my-org"
          # Token is read from the CPLN_TOKEN environment variable
        }
        ```
      </Tab>
    </Tabs>

    Replace `my-org` with your org name, then initialize Terraform:

    ```bash theme={null}
    terraform init
    ```

    More authentication options: [Terraform provider](/iac/terraform).

    ## Step 3: Define the GVC

    Add the GVC resource to `main.tf`:

    ```hcl theme={null}
    resource "cpln_gvc" "quickstart" {
      name        = "quickstart-gvc"
      description = "Quickstart GVC"

      locations = [
        "aws-us-west-2",
        "gcp-us-east1"
      ]
    }
    ```

    ## Step 4: Define the workload

    Add the workload resource to `main.tf`:

    ```hcl theme={null}
    resource "cpln_workload" "web" {
      gvc  = cpln_gvc.quickstart.name
      name = "web"
      type = "standard"

      container {
        name   = "web"
        image  = "nginx:alpine"
        cpu    = "50m"
        memory = "128Mi"

        ports {
          number   = 80
          protocol = "http"
        }
      }

      options {
        capacity_ai     = true
        timeout_seconds = 5

        autoscaling {
          metric      = "disabled"
          target      = 95
          min_scale   = 1
          max_scale   = 1
        }
      }

      firewall_spec {
        external {
          inbound_allow_cidr = ["0.0.0.0/0"]
        }
      }
    }

    output "canonical_endpoint" {
      value = cpln_workload.web.status[0].canonical_endpoint
    }
    ```

    ## Step 5: Deploy

    Review the plan:

    ```bash theme={null}
    terraform plan
    ```

    Apply the configuration:

    ```bash theme={null}
    terraform apply
    ```

    Type `yes` when prompted. After deployment completes, the canonical endpoint URL prints.

    ## Step 6: Open the welcome page

    Open the canonical endpoint URL in your browser. To print it again:

    ```bash theme={null}
    terraform output
    ```

    <Tip>
      The [Terraform Registry documentation](https://registry.terraform.io/providers/controlplane-com/cpln/latest/docs/resources/workload) lists every workload option.
    </Tip>
  </Tab>

  <Tab title="Pulumi" icon="https://mintcdn.com/controlplanecorporation-majid-docs-content-expansion/Ry1Mkgc7uPHC-gur/icons/pulumi.svg?fit=max&auto=format&n=Ry1Mkgc7uPHC-gur&q=85&s=7a7f4b9390dfa8fecf6223c88c658dcd" width="256" height="271" data-path="icons/pulumi.svg">
    ## Prerequisites

    * An [org](/reference/org) to deploy into. If you don't have one yet, [sign up](https://console.cpln.io/signup) for Control Plane: the Console walks you through creating a [billing account](/concepts/billing) and your first org.

    - [Pulumi CLI](https://www.pulumi.com/docs/iac/download-install/) installed.

    ## Step 1: Authenticate

    The provider needs credentials for Control Plane. Choose one of the following methods:

    <Tabs>
      <Tab title="CLI Profile">
        With the [Control Plane CLI](/cli-reference/installation) installed, log in:

        ```bash theme={null}
        cpln login
        ```

        This creates a profile named `default` with your credentials, which the provider configuration references.
      </Tab>

      <Tab title="Service Account Token">
        For CI/CD pipelines or environments without the CLI, create a service account token:

        <Steps>
          <Step title="Create the service account">
            In the [Console](https://console.cpln.io), click `Service Accounts` in the left menu, then `New`. Enter a name, select `superusers` from the `Assign to Group` dropdown, and click `Create`.
          </Step>

          <Step title="Create a key">
            Click `Keys`, add a description, and click `Add`. Copy the generated key; it is not shown again.
          </Step>

          <Step title="Export the token">
            ```bash theme={null}
            export CPLN_TOKEN=your-service-account-key
            ```
          </Step>
        </Steps>
      </Tab>
    </Tabs>

    ## Step 2: Create a new project

    Create a new directory and initialize a Pulumi project:

    <Tabs>
      <Tab title="TypeScript">
        ```bash theme={null}
        mkdir cpln-quickstart && cd cpln-quickstart
        pulumi new typescript
        ```

        Follow the prompts in the terminal to complete project setup. Then install the Control Plane provider:

        <Tabs>
          <Tab title="npm">
            ```bash theme={null}
            npm install @pulumiverse/cpln
            ```
          </Tab>

          <Tab title="pnpm">
            ```bash theme={null}
            pnpm add @pulumiverse/cpln
            ```
          </Tab>

          <Tab title="yarn">
            ```bash theme={null}
            yarn add @pulumiverse/cpln
            ```
          </Tab>

          <Tab title="bun">
            ```bash theme={null}
            bun add @pulumiverse/cpln
            ```
          </Tab>
        </Tabs>
      </Tab>

      <Tab title="Python">
        ```bash theme={null}
        mkdir cpln-quickstart && cd cpln-quickstart
        pulumi new python
        ```

        Follow the prompts in the terminal to complete project setup. Activate the virtual environment and install the Control Plane provider:

        <Tabs>
          <Tab title="pip">
            ```bash theme={null}
            source venv/bin/activate
            pip install pulumiverse-cpln
            ```
          </Tab>

          <Tab title="poetry">
            ```bash theme={null}
            poetry add pulumiverse-cpln
            ```
          </Tab>

          <Tab title="uv">
            ```bash theme={null}
            source .venv/bin/activate
            uv add pulumiverse-cpln
            ```
          </Tab>
        </Tabs>
      </Tab>

      <Tab title="Go">
        ```bash theme={null}
        mkdir cpln-quickstart && cd cpln-quickstart
        pulumi new go
        ```

        Follow the prompts in the terminal to complete project setup. Then install the Control Plane provider:

        ```bash theme={null}
        go get github.com/pulumiverse/pulumi-cpln/sdk/go/cpln
        ```
      </Tab>

      <Tab title="C#">
        ```bash theme={null}
        mkdir cpln-quickstart && cd cpln-quickstart
        pulumi new csharp
        ```

        Follow the prompts in the terminal to complete project setup. Then install the Control Plane provider:

        ```bash theme={null}
        dotnet add package Pulumiverse.Cpln --version 0.0.89
        ```
      </Tab>
    </Tabs>

    ## Step 3: Configure the provider

    Set your org (replace `my-org` with your org name) and authentication method:

    <Tabs>
      <Tab title="CLI Profile">
        ```bash theme={null}
        pulumi config set cpln:org my-org
        pulumi config set cpln:profile default
        ```
      </Tab>

      <Tab title="Service Account Token">
        ```bash theme={null}
        pulumi config set cpln:org my-org
        pulumi config set --secret cpln:token $CPLN_TOKEN
        ```

        Or paste the token directly:

        ```bash theme={null}
        pulumi config set cpln:org my-org
        pulumi config set --secret cpln:token your-service-account-key
        ```
      </Tab>
    </Tabs>

    ## Step 4: Define the infrastructure

    <Tabs>
      <Tab title="TypeScript">
        Replace `index.ts` with:

        ```typescript theme={null}
        import * as cpln from "@pulumiverse/cpln";

        // Create a GVC
        const gvc = new cpln.Gvc("quickstart-gvc", {
          name: "quickstart-gvc",
          description: "Quickstart GVC",
          locations: ["aws-us-west-2", "gcp-us-east1"],
        });

        // Create the workload
        const web = new cpln.Workload("web", {
          gvc: gvc.name,
          name: "web",
          type: "standard",
          containers: [
            {
              name: "web",
              image: "nginx:alpine",
              cpu: "50m",
              memory: "128Mi",
              ports: [
                {
                  number: 80,
                  protocol: "http",
                },
              ],
            },
          ],
          options: {
            capacityAi: true,
            timeoutSeconds: 5,
            autoscaling: {
              metric: "disabled",
              target: 95,
              minScale: 1,
              maxScale: 1,
            },
          },
          firewallSpec: {
            external: {
              inboundAllowCidrs: ["0.0.0.0/0"],
            },
          },
        });

        // Export the canonical endpoint
        export const canonical_endpoint = web.statuses.apply(
          (s) => s?.[0]?.canonicalEndpoint
        );
        ```
      </Tab>

      <Tab title="Python">
        Replace `__main__.py` with:

        ```python theme={null}
        import pulumiverse_cpln as cpln
        import pulumi

        # Create a GVC
        gvc = cpln.Gvc("quickstart-gvc",
            name="quickstart-gvc",
            description="Quickstart GVC",
            locations=["aws-us-west-2", "gcp-us-east1"])

        # Create the workload
        web = cpln.Workload("web",
            gvc=gvc.name,
            name="web",
            type="standard",
            containers=[cpln.WorkloadContainerArgs(
                name="web",
                image="nginx:alpine",
                cpu="50m",
                memory="128Mi",
                ports=[cpln.WorkloadContainerPortArgs(
                    number=80,
                    protocol="http",
                )],
            )],
            options=cpln.WorkloadOptionsArgs(
                capacity_ai=True,
                timeout_seconds=5,
                autoscaling=cpln.WorkloadOptionsAutoscalingArgs(
                    metric="disabled",
                    target=95,
                    min_scale=1,
                    max_scale=1,
                ),
            ),
            firewall_spec=cpln.WorkloadFirewallSpecArgs(
                external=cpln.WorkloadFirewallSpecExternalArgs(
                    inbound_allow_cidrs=["0.0.0.0/0"],
                ),
            ))

        # Export the canonical endpoint
        pulumi.export("canonical_endpoint", web.statuses.apply(
            lambda s: s[0].canonical_endpoint if s else None
        ))
        ```
      </Tab>

      <Tab title="Go">
        Replace `main.go` with:

        ```go theme={null}
        package main

        import (
        	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
        	"github.com/pulumiverse/pulumi-cpln/sdk/go/cpln"
        )

        func main() {
        	pulumi.Run(func(ctx *pulumi.Context) error {
        		// Create a GVC
        		gvc, err := cpln.NewGvc(ctx, "quickstart-gvc", &cpln.GvcArgs{
        			Name:        pulumi.String("quickstart-gvc"),
        			Description: pulumi.String("Quickstart GVC"),
        			Locations: pulumi.StringArray{
        				pulumi.String("aws-us-west-2"),
        				pulumi.String("gcp-us-east1"),
        			},
        		})
        		if err != nil {
        			return err
        		}

        		// Create the workload
        		web, err := cpln.NewWorkload(ctx, "web", &cpln.WorkloadArgs{
        			Gvc:  gvc.Name,
        			Name: pulumi.String("web"),
        			Type: pulumi.String("standard"),
        			Containers: cpln.WorkloadContainerArray{
        				&cpln.WorkloadContainerArgs{
        					Name:   pulumi.String("web"),
        					Image:  pulumi.String("nginx:alpine"),
        					Cpu:    pulumi.String("50m"),
        					Memory: pulumi.String("128Mi"),
        					Ports: cpln.WorkloadContainerPortArray{
        						&cpln.WorkloadContainerPortArgs{
        							Number:   pulumi.Int(80),
        							Protocol: pulumi.String("http"),
        						},
        					},
        				},
        			},
        			Options: &cpln.WorkloadOptionsArgs{
        				CapacityAi:     pulumi.Bool(true),
        				TimeoutSeconds: pulumi.Int(5),
        				Autoscaling: &cpln.WorkloadOptionsAutoscalingArgs{
        					Metric:   pulumi.String("disabled"),
        					Target:   pulumi.Int(95),
        					MinScale: pulumi.Int(1),
        					MaxScale: pulumi.Int(1),
        				},
        			},
        			FirewallSpec: &cpln.WorkloadFirewallSpecArgs{
        				External: &cpln.WorkloadFirewallSpecExternalArgs{
        					InboundAllowCidrs: pulumi.StringArray{pulumi.String("0.0.0.0/0")},
        				},
        			},
        		})
        		if err != nil {
        			return err
        		}

        		// Export the canonical endpoint
        		ctx.Export("canonical_endpoint", web.Statuses.Index(pulumi.Int(0)).CanonicalEndpoint())
        		return nil
        	})
        }
        ```
      </Tab>

      <Tab title="C#">
        Replace `Program.cs` with:

        ```csharp theme={null}
        using Pulumi;
        using Pulumiverse.Cpln;
        using Pulumiverse.Cpln.Inputs;
        using System.Collections.Generic;

        return await Deployment.RunAsync(() =>
        {
            // Create a GVC
            var gvc = new Gvc("quickstart-gvc", new GvcArgs
            {
                Name = "quickstart-gvc",
                Description = "Quickstart GVC",
                Locations = new[] { "aws-us-west-2", "gcp-us-east1" }
            });

            // Create the workload
            var web = new Workload("web", new WorkloadArgs
            {
                Gvc = gvc.Name,
                Name = "web",
                Type = "standard",
                Containers = new[]
                {
                    new WorkloadContainerArgs
                    {
                        Name = "web",
                        Image = "nginx:alpine",
                        Cpu = "50m",
                        Memory = "128Mi",
                        Ports = new[]
                        {
                            new WorkloadContainerPortArgs
                            {
                                Number = 80,
                                Protocol = "http"
                            }
                        }
                    }
                },
                Options = new WorkloadOptionsArgs
                {
                    CapacityAi = true,
                    TimeoutSeconds = 5,
                    Autoscaling = new WorkloadOptionsAutoscalingArgs
                    {
                        Metric = "disabled",
                        Target = 95,
                        MinScale = 1,
                        MaxScale = 1
                    }
                },
                FirewallSpec = new WorkloadFirewallSpecArgs
                {
                    External = new WorkloadFirewallSpecExternalArgs
                    {
                        InboundAllowCidrs = new[] { "0.0.0.0/0" }
                    }
                }
            });

            // Export the canonical endpoint
            return new Dictionary<string, object?>
            {
                ["canonical_endpoint"] = web.Statuses.Apply(s => s[0].CanonicalEndpoint)
            };
        });
        ```
      </Tab>
    </Tabs>

    ## Step 5: Deploy

    Preview the changes:

    ```bash theme={null}
    pulumi preview
    ```

    Deploy the infrastructure:

    ```bash theme={null}
    pulumi up
    ```

    Select `yes` when prompted. After deployment, the canonical endpoint URL prints, unless Control Plane had not published it yet; step 6 covers that case.

    ## Step 6: Open the welcome page

    Open the canonical endpoint URL in your browser. To print it again:

    ```bash theme={null}
    pulumi stack output
    ```

    <Note>
      If the canonical endpoint doesn't appear, the workload was created before Control Plane published it. Run `pulumi refresh` to read the current status, then `pulumi up` to re-evaluate the output. A second `pulumi up` on its own finds nothing to change and leaves the output empty.
    </Note>

    The [Pulumi Registry documentation](https://www.pulumi.com/registry/packages/cpln/) lists every resource the provider supports.
  </Tab>

  <Tab title="AI Agent" icon="sparkles">
    ## Prerequisites

    * An [org](/reference/org) to deploy into. If you don't have one yet, [sign up](https://console.cpln.io/signup) for Control Plane: the Console walks you through creating a [billing account](/concepts/billing) and your first org.

    - An AI agent that supports MCP servers, whether a chat app such as Claude Desktop, an IDE such as Cursor, or a terminal agent such as Claude Code. Every [compatible tool](/ai/mcp#compatible-tools) has a setup page.

    ## Step 1: Connect your AI agent

    Your AI agent operates Control Plane through the [MCP server](/ai/mcp), whether it runs in a chat app, an IDE, or a terminal. Pick the path for your tool:

    <CardGroup cols={2}>
      <Card title="MCP Server" icon="https://mintcdn.com/controlplanecorporation-majid-docs-content-expansion/rKGH-n6tu4yQ_WHQ/icons/mcp.svg?fit=max&auto=format&n=rKGH-n6tu4yQ_WHQ&q=85&s=56240710075f155f61d45cb6d03295a2" href="/ai/mcp" width="24" height="24" data-path="icons/mcp.svg">
        Works with every MCP client, such as Claude Desktop, Claude Web, Cursor, VS Code, Antigravity IDE, Amp, or OpenCode. Point it at the endpoint and sign in.
      </Card>

      <Card title="AI Plugin" icon="puzzle-piece" href="/ai/plugin">
        If your tool is Claude Code, Codex, or Antigravity CLI, install the plugin instead. It bundles the MCP server and adds Control Plane skills, agents, slash commands, and guardrails.
      </Card>
    </CardGroup>

    Your tool opens Control Plane in the browser: sign in, pick the orgs the agent may access, including the org you deploy into, and click `Authorize`. Then continue with Step 2.

    ## Step 2: Set the org

    Every prompt below runs in the same conversation, so name your org once (replace `my-org` with your org name):

    ```text theme={null}
    Use org "my-org" for this conversation and list its GVCs.
    ```

    The agent lists the org's GVCs, or reports that there are none yet. If it answers that it has no Control Plane tools or is not signed in, finish the setup page for your tool first.

    ## Step 3: Create a GVC

    ```text theme={null}
    Create a GVC called "quickstart-gvc" with the locations
    aws-us-west-2 and gcp-us-east1.
    ```

    The agent creates the GVC and confirms its two locations.

    ## Step 4: Create the workload

    ```text theme={null}
    Create a public workload called "web" in that GVC from the
    image nginx:alpine on port 80, with one replica per location
    and the container named "web". Keep everything else at its
    default.
    ```

    The agent creates the workload, follows its deployments until both locations report ready, and reports the canonical endpoint.

    ## Step 5: Open the welcome page

    Ask for the endpoint of each location. The prompt also returns the canonical endpoint, in case the agent stopped before reporting it:

    ```text theme={null}
    Once it is ready in both locations, give me the endpoint of
    each location and its canonical endpoint.
    ```

    Open the canonical endpoint in your browser. The NGINX welcome page opens, served from the location nearest to you. Then open each location's endpoint to confirm the workload responds from AWS and from GCP.
  </Tab>
</Tabs>

## Verify

Whichever interface you used: once the workload reports `Ready`, its canonical endpoint serves the NGINX welcome page:

```text theme={null}
Welcome to nginx!
If you see this page, the nginx web server is successfully installed and working.
```

Each location also serves its own endpoint: open both from the `Deployments` page in the Console (or the `cpln workload get-deployments web` output) to confirm the workload responds from AWS and GCP.

<Check>
  Your workload runs on AWS and GCP behind one TLS-secured endpoint, geo-routed to the nearest healthy location.
</Check>

## What you've learned

* **One definition, every location**: a workload runs in each location of its GVC, and a location added to the GVC later runs it too.
* **Availability by placement**: two locations on two providers, with the endpoint routing around an unhealthy one, is what keeps the application reachable when a region or a provider fails.
* **The endpoint comes with the workload**: TLS termination, the certificate, and geo-routing are part of every public workload.
* **Five interfaces, one result**: the Console, the CLI, Terraform, Pulumi, and an AI agent create the same GVC and workload.

## Next steps

<Card title="2. Deploy your own application" icon="rocket" href="/quickstart/deploy-application" horizontal>
  Build and deploy your own containerized application to Control Plane.
</Card>

## Clean up

To remove everything this part created:

<Tabs>
  <Tab title="Console" icon="display">
    Open `quickstart-gvc`, click `Actions`, then `Delete`. Type the GVC name to confirm and click `Delete`. Deleting the GVC removes its workloads with it.
  </Tab>

  <Tab title="CLI" icon="terminal">
    ```bash theme={null}
    cpln gvc delete quickstart-gvc
    ```
  </Tab>

  <Tab title="Terraform" icon="https://mintcdn.com/controlplanecorporation-majid-docs-content-expansion/Ry1Mkgc7uPHC-gur/icons/terraform.svg?fit=max&auto=format&n=Ry1Mkgc7uPHC-gur&q=85&s=19deabd5e978d39905a6c83ea1f7904d" width="256" height="291" data-path="icons/terraform.svg">
    ```bash theme={null}
    terraform destroy
    ```
  </Tab>

  <Tab title="Pulumi" icon="https://mintcdn.com/controlplanecorporation-majid-docs-content-expansion/Ry1Mkgc7uPHC-gur/icons/pulumi.svg?fit=max&auto=format&n=Ry1Mkgc7uPHC-gur&q=85&s=7a7f4b9390dfa8fecf6223c88c658dcd" width="256" height="271" data-path="icons/pulumi.svg">
    ```bash theme={null}
    pulumi destroy
    ```
  </Tab>

  <Tab title="AI Agent" icon="sparkles">
    ```text theme={null}
    Delete the GVC "quickstart-gvc".
    ```

    The agent reads the GVC, tells you that deleting it removes the workload `web` with it, and asks you to confirm. Your AI tool may also ask you to approve the call. Answer yes, and the GVC and its workload are gone.
  </Tab>
</Tabs>
