# Configure AWS PrivateLink with the Cloud API

> For the complete documentation index, see [llms.txt](https://docs.redpanda.com/llms.txt). Component-specific: [cloud-data-platform-full.txt](https://docs.redpanda.com/cloud-data-platform-full.txt)

---
title: Configure AWS PrivateLink with the Cloud API
latest-operator-version: v26.1.4
latest-console-tag: v3.7.3
latest-connect-version: 4.93.0
latest-redpanda-tag: v26.1.9
docname: serverless/aws/privatelink-api
page-component-name: cloud-data-platform
page-version: master
page-component-version: master
page-component-title: Cloud
page-relative-src-path: serverless/aws/privatelink-api.adoc
page-edit-url: https://github.com/redpanda-data/cloud-docs/edit/main/modules/networking/pages/serverless/aws/privatelink-api.adoc
description: Set up AWS PrivateLink with the Cloud API for Serverless clusters.
page-git-created-date: "2026-02-02"
page-git-modified-date: "2026-03-02"
---

<!-- Source: https://docs.redpanda.com/cloud-data-platform/networking/serverless/aws/privatelink-api.md -->

The Redpanda AWS PrivateLink endpoint service provides secure access to Redpanda Cloud from your own VPC. Traffic over PrivateLink does not go through the public internet because a PrivateLink connection is treated as its own private AWS service. While your VPC has access to the Redpanda VPC, Redpanda cannot access your VPC.

Consider using the PrivateLink endpoint service if you have multiple VPCs and could benefit from a more simplified approach to network management. You can create a new Serverless cluster with PrivateLink enabled, or enable PrivateLink for existing clusters using either the Console or the API.

> 📝 **NOTE**
>
> -   Each client VPC can have one endpoint connected to the PrivateLink service.
>
> -   PrivateLink allows overlapping [CIDR ranges](https://docs.redpanda.com/cloud-data-platform/networking/cidr-ranges/) in VPC networks.
>
> -   PrivateLink does not add extra connection limits. However, VPC peering is limited to 125 connections. See [How scalable is AWS PrivateLink?](https://aws.amazon.com/privatelink/faqs/)
>
> -   You control which AWS principals are allowed to connect to the endpoint service.

After [getting an access token](#get-a-cloud-api-access-token), you can [enable PrivateLink when creating a new Serverless cluster](#create-new-cluster-with-privatelink-endpoint-service-enabled), or you can [enable PrivateLink for existing Serverless clusters](#enable-privatelink-endpoint-service-for-existing-clusters).

## [](#requirements)Requirements

-   Install `rpk`.

-   Your Redpanda Serverless cluster and [VPC](#create-client-vpc) must be in the same region.

-   This guide uses the [Redpanda Cloud API](https://docs.redpanda.com/api/doc/cloud-controlplane/topic/topic-cloud-api-overview) to enable the Redpanda endpoint service for your Serverless clusters. Follow the steps below to [get an access token](#get-an-access-token).

-   Use the [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html) to create a new client VPC or modify an existing one to use the PrivateLink endpoint.


> 💡 **TIP**
>
> In Kafka clients, set `connections.max.idle.ms` to a value less than 350 seconds (350000 ms).

> 📝 **NOTE**
>
> Enabling PrivateLink changes private DNS behavior for your cluster. Before configuring connections, review [DNS resolution with PrivateLink](#dns-resolution-with-privatelink).

## [](#get-a-cloud-api-access-token)Get a Cloud API access token

1.  Save the base URL of the Redpanda Cloud API in an environment variable:

    ```bash
    export PUBLIC_API_ENDPOINT="https://api.cloud.redpanda.com"
    ```

2.  In the Redpanda Cloud UI, go to the [**Organization IAM**](https://cloud.redpanda.com/organization-iam) page, and select the **Service account** tab. If you don’t have an existing service account, you can create a new one.

    Copy and store the client ID and secret.

    ```bash
    export CLOUD_CLIENT_ID=<client-id>
    export CLOUD_CLIENT_SECRET=<client-secret>
    ```

3.  Get an API token using the client ID and secret. You can click the **Request an API token** link to see code examples to generate the token.

    ```bash
    export AUTH_TOKEN=`curl -s --request POST \
        --url 'https://auth.prd.cloud.redpanda.com/oauth/token' \
        --header 'content-type: application/x-www-form-urlencoded' \
        --data grant_type=client_credentials \
        --data client_id="$CLOUD_CLIENT_ID" \
        --data client_secret="$CLOUD_CLIENT_SECRET" \
        --data audience=cloudv2-production.redpanda.cloud | jq -r .access_token`
    ```


You must send the API token in the `Authorization` header when making requests to the Cloud API.

## [](#create-a-privatelink-resource)Create a PrivateLink resource

Before you can create a Serverless cluster with PrivateLink enabled, you must first create a PrivateLink resource in your resource group.

1.  In the [Redpanda Cloud Console](https://cloud.redpanda.com/), go to **Resource groups** and select the resource group in which you want to create a PrivateLink resource.

    Copy and store the resource group ID (UUID) from the URL in the browser.

    ```bash
    export RESOURCE_GROUP_ID=<uuid>
    ```

2.  Set the Serverless region where you want to create the PrivateLink resource (for example, `us-east-1`).

    ```bash
    export SERVERLESS_REGION=<serverless_region>
    ```

3.  Create a new PrivateLink resource by calling [`POST /v1/serverless/private-links`](https://docs.redpanda.com/api/doc/cloud-controlplane/operation/operation-serverlessprivatelinkservice_createserverlessprivatelink).

    ```bash
    PL_POST_BODY=`cat << EOF
    {
        "serverless_private_link": {
            "name": "<private-link-name>",
            "resource_group_id": "$RESOURCE_GROUP_ID",
            "serverless_region": "$SERVERLESS_REGION",
            "cloudprovider": "CLOUD_PROVIDER_AWS",
            "aws_config": {
                "allowed_principals": [
                    "arn:aws:iam::<account-id>:root"
                ]
            }
        }
    }
    EOF`

    PL_ID=`curl -vv -X POST \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer $AUTH_TOKEN" \
        -d "$PL_POST_BODY" $PUBLIC_API_ENDPOINT/v1/serverless/private-links | jq -r .operation.metadata.serverless_private_link_id`

    echo $PL_ID
    ```

    You can also update private links to add or remove allowed principals.

    ```bash
    PL_PATCH_BODY=`cat << EOF
    {
            "aws_config": {
                "allowed_principals": [
                    "arn:aws:iam::<account-id>:root"
                ]
            }
    }
    EOF`

    curl -vv -X PATCH \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer $AUTH_TOKEN" \
        -d "$PL_PATCH_BODY" $PUBLIC_API_ENDPOINT/v1/serverless/private-links/$PL_ID
    ```

    Store the PrivateLink ID for use in the following steps.


## [](#create-new-cluster-with-privatelink-endpoint-service-enabled)Create new cluster with PrivateLink endpoint service enabled

Using the `RESOURCE_GROUP_ID` and `SERVERLESS_PRIVATE_LINK_ID` from the previous step, create a new Serverless cluster with the endpoint service enabled by calling [`POST /v1/serverless/clusters`](https://docs.redpanda.com/api/doc/cloud-controlplane/operation/operation-serverlessclusterservice_createserverlesscluster).

In the following example, make sure to set your own values for the following fields:

-   `name`

-   `serverless_region`: for example, `"us-east-1"`

-   `private_link_id`: The ID of the PrivateLink resource created in the previous step

-   `networking_config.private` and `networking_config.public`: Valid values are `STATE_ENABLED` or `STATE_DISABLED`. At least one must be enabled. If neither is specified, `public` defaults to `STATE_ENABLED`.


```bash
CLUSTER_POST_BODY=`cat << EOF
{
    "serverless_cluster": {
        "name": "<my-private-link-cluster>",
        "resource_group_id": "$RESOURCE_GROUP_ID",
        "serverless_region": "$SERVERLESS_REGION",
        "private_link_id": "$SERVERLESS_PRIVATE_LINK_ID",
        "networking_config": {
            "private": "STATE_ENABLED",
            "public": "STATE_ENABLED"
        }
    }
}
EOF`

CLUSTER_ID=`curl -vv -X POST \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $AUTH_TOKEN" \
    -d "$CLUSTER_POST_BODY" $PUBLIC_API_ENDPOINT/v1/serverless/clusters | jq -r .operation.metadata.cluster_id`

echo $CLUSTER_ID
```

## [](#enable-privatelink-endpoint-service-for-existing-clusters)Enable PrivateLink endpoint service for existing clusters

1.  In the Redpanda Cloud Console, go to the cluster Overview and copy the cluster ID from the **Details** section.

    ```bash
    CLUSTER_ID=<cluster_id>
    ```

2.  Get the PrivateLink ID from the cluster Overview page in the Redpanda Cloud Console.

    ```bash
    SERVERLESS_PRIVATE_LINK_ID=<private_link_id>
    ```

3.  Make a [`PATCH /v1/serverless/clusters/{cluster.id}`](https://docs.redpanda.com/api/doc/cloud-controlplane/operation/operation-serverlessclusterservice_updateserverlesscluster) request to update the cluster with the Redpanda PrivateLink Endpoint Service enabled.

    In the following example, make sure to set your own value for the following fields:

    -   `private_link_id`: The ID of an existing PrivateLink resource in the same resource group

    -   `networking_config.private`: Set to `STATE_ENABLED` to enable private access


    ```bash
    CLUSTER_PATCH_BODY=`cat << EOF
    {
      "networking_config": {
        "private": "STATE_ENABLED"
      },
      "private_link_id": "$SERVERLESS_PRIVATE_LINK_ID"
    }
    EOF`

    curl -vv -X PATCH \
      -H "Content-Type: application/json" \
      -H "Authorization: Bearer $AUTH_TOKEN" \
      -d "$CLUSTER_PATCH_BODY" $PUBLIC_API_ENDPOINT/v1/serverless/clusters/$CLUSTER_ID
    ```


## [](#dns-resolution-with-privatelink)DNS resolution with PrivateLink

PrivateLink changes how DNS resolution works for your cluster. When you query cluster hostnames outside the VPC that contains your PrivateLink endpoint, DNS may return private IP addresses that aren’t reachable from your location.

To resolve cluster hostnames from other VPCs or on-premise networks, set up DNS forwarding using [Route 53 Resolver](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resolver.html):

1.  In the VPC that contains your PrivateLink endpoint, create a Route 53 Resolver inbound endpoint.

    Ensure that the inbound endpoint’s security group allows inbound UDP/TCP port 53 from each VPC or on-prem network that will forward queries.

2.  In each other VPC that must resolve the cluster domain, create a Resolver outbound endpoint and a forwarding rule for `<cluster_domain>` that targets the inbound endpoint IPs from the previous step. Associate the rule to those VPCs.

    The cluster domain is the suffix after the seed hostname. For example, if your bootstrap server URL is: `cki01qgth38kk81ard3g.any.us-east-1.aw.priv.prd.cloud.redpanda.com:9092`, then `cluster_domain` is: `cki01qgth38kk81ard3g.any.us-east-1.aw.priv.prd.cloud.redpanda.com`.

3.  For on-premises DNS, create a conditional forwarder for `<cluster_domain>` that forwards to the inbound endpoint IPs from the earlier step (over VPN/Direct Connect).

    > ❗ **IMPORTANT**
    >
    > Do not configure forwarding rules to target the VPC’s Amazon-provided DNS resolver (VPC base CIDR + 2). Rules must target the IP addresses of Route 53 Resolver endpoints.


## [](#configure-privatelink-connection-to-redpanda-cloud)Configure PrivateLink connection to Redpanda Cloud

When you have a PrivateLink-enabled cluster, you can create an endpoint to connect your VPC and your cluster.

### [](#get-cluster-domain)Get cluster domain

Get the domain (`cluster_domain`) of the cluster from the cluster details in the Redpanda Cloud Console.

For example, if the bootstrap server URL is: `cki01qgth38kk81ard3g.any.us-east-1.aw.priv.prd.cloud.redpanda.com:9092`, then `cluster_domain` is: `cki01qgth38kk81ard3g.any.us-east-1.aw.priv.prd.cloud.redpanda.com`.

```bash
CLUSTER_DOMAIN=<cluster_domain>
```

> 📝 **NOTE**
>
> Use `<cluster_domain>` as the domain you target with your DNS conditional forward (optionally also `*.<cluster_domain>` if your DNS platform requires a wildcard).

### [](#get-name-of-privatelink-endpoint-service)Get name of PrivateLink endpoint service

The service name is required to [create VPC private endpoints](#create-vpc-endpoint). Run the following command to get the service name:

```bash
PL_SERVICE_NAME=`curl -X GET \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AUTH_TOKEN" \
  $PUBLIC_API_ENDPOINT/v1/serverless/private-links/$SERVERLESS_PRIVATE_LINK_ID | jq -r .serverless_private_link.status.aws.vpc_endpoint_service_name`
```

### [](#create-client-vpc)Create client VPC

If you are not using an existing VPC, you must create a new one.

The VPC region must be the same region where the Redpanda cluster is deployed. To create the VPC, run:

```bash
# See https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html for
# information on profiles and credential files
REGION=<aws-region>
PROFILE=<specific-profile-from-credential-file>

aws ec2 create-vpc --region $REGION --profile $PROFILE --cidr-block 10.0.0.0/20

# Store the client VPC ID from the command output
CLIENT_VPC_ID=<client_vpc_id>
```

You can also use an existing VPC. You need the VPC ID to [modify its DNS attributes](#modify-vpc-dns-attributes).

### [](#modify-vpc-dns-attributes)Modify VPC DNS attributes

To modify the VPC attributes, run:

```bash
aws ec2 modify-vpc-attribute --region $REGION --profile $PROFILE --vpc-id $CLIENT_VPC_ID \
    --enable-dns-hostnames "{\"Value\":true}"

aws ec2 modify-vpc-attribute --region $REGION --profile $PROFILE --vpc-id $CLIENT_VPC_ID \
    --enable-dns-support "{\"Value\":true}"
```

These commands enable DNS hostnames and resolution for instances in the VPC.

### [](#create-security-group)Create security group

You need the security group ID `security_group_id` from the command output to [add security group rules](#add-security-group-rules). To create a security group, run:

```bash
aws ec2 create-security-group --region $REGION --profile $PROFILE --vpc-id $CLIENT_VPC_ID \
    --description "Redpanda endpoint service client security group" \
    --group-name "${CLUSTER_ID}-sg"
SECURITY_GROUP_ID=<security_group_id>
```

### [](#add-security-group-rules)Add security group rules

The following example shows how to add security group rules to allow access to Redpanda services.

```bash
# Allow Kafka API bootstrap (seed)
aws ec2 authorize-security-group-ingress --region $REGION --profile $PROFILE \
  --group-id $SECURITY_GROUP_ID --protocol tcp --port 9092 --cidr 0.0.0.0/0

# Allow Kafka API broker 1
aws ec2 authorize-security-group-ingress --region $REGION --profile $PROFILE \
  --group-id $SECURITY_GROUP_ID --protocol tcp --port 9093 --cidr 0.0.0.0/0

# Allow Kafka API broker 2
aws ec2 authorize-security-group-ingress --region $REGION --profile $PROFILE \
  --group-id $SECURITY_GROUP_ID --protocol tcp --port 9094 --cidr 0.0.0.0/0

# Allow Kafka API broker 3
aws ec2 authorize-security-group-ingress --region $REGION --profile $PROFILE \
  --group-id $SECURITY_GROUP_ID --protocol tcp --port 9095 --cidr 0.0.0.0/0

# Allow Schema Registry
aws ec2 authorize-security-group-ingress --region $REGION --profile $PROFILE \
  --group-id $SECURITY_GROUP_ID --protocol tcp --port 8081 --cidr 0.0.0.0/0

# Allow Redpanda Cloud Data Plane API / Prometheus (if needed)
aws ec2 authorize-security-group-ingress --region $REGION --profile $PROFILE \
  --group-id $SECURITY_GROUP_ID --protocol tcp --port 443 --cidr 0.0.0.0/0
```

### [](#create-vpc-subnet)Create VPC subnet

You need the subnet ID `subnet_id` from the command output to [create a VPC endpoint](#create-vpc-endpoint). Run the following command, specifying the subnet Availability Zone name (for example, `us-west-2a`):

```bash
aws ec2 create-subnet --region $REGION --profile $PROFILE --vpc-id $CLIENT_VPC_ID \
    --availability-zone <zone> \
    --cidr-block 10.0.1.0/24
SUBNET_ID=<subnet_id>
```

### [](#create-vpc-endpoint)Create VPC endpoint

```bash
aws ec2 create-vpc-endpoint \
    --region $REGION --profile $PROFILE \
    --vpc-id $CLIENT_VPC_ID \
    --vpc-endpoint-type "Interface" \
    --ip-address-type "ipv4" \
    --service-name $PL_SERVICE_NAME \
    --subnet-ids $SUBNET_ID \
    --security-group-ids $SECURITY_GROUP_ID \
    --private-dns-enabled
```

## [](#access-redpanda-services-through-vpc-endpoint)Access Redpanda services through VPC endpoint

After you have enabled PrivateLink for your cluster, your connection URLs are available in the **How to Connect** section of the cluster overview in the Redpanda Cloud Console.

You can access Redpanda services such as the Kafka API and Schema Registry from the client VPC or virtual network; for example, from a compute instance in the VPC or network.

The bootstrap server hostname is unique to each cluster. The service attachment exposes a set of bootstrap ports for access to Redpanda services. These ports load balance requests among brokers. Make sure you use the following ports for initiating a connection from a consumer:

| Redpanda service | Default bootstrap port |
| --- | --- |
| Kafka API | 9092 |
| Schema Registry | 8081 |

### [](#access-kafka-api-seed-service)Access Kafka API seed service

Use port `9092` to access the Kafka API seed service.

```bash
export RPK_BROKERS='<kafka-api-bootstrap-server-hostname>:9092'
rpk cluster info -X tls.enabled=true -X user=<user> -X pass=<password>
```

When successful, the `rpk` output should look like the following:

```bash
CLUSTER
redpanda.rp-cki01qgth38kk81ard3g

BROKERS
ID    HOST                                                                          PORT   RACK
0*    cki01qgth38kk81ard3g-0.any.us-east-1.aw.priv.prd.cloud.redpanda.com           9093   use1-az1
1     cki01qgth38kk81ard3g-1.any.us-east-1.aw.priv.prd.cloud.redpanda.com           9094   use1-az1
2     cki01qgth38kk81ard3g-2.any.us-east-1.aw.priv.prd.cloud.redpanda.com           9095   use1-az1
```

### [](#access-schema-registry-seed-service)Access Schema Registry seed service

Use port `8081` to access the Schema Registry seed service.

```bash
curl -vv -u <user>:<password> -H "Content-Type: application/vnd.schemaregistry.v1+json" --sslv2 --http2 <schema-registry-bootstrap-server-hostname>:8081/subjects
```

## [](#test-the-connection)Test the connection

You can test the PrivateLink connection from any VM or container in the client VPC. If configuring a client isn’t possible right away, you can do these checks using `rpk` or cURL:

1.  Set the following environment variables.

    ```bash
    export RPK_BROKERS='<kafka-api-bootstrap-server-hostname>:9092'
    export RPK_TLS_ENABLED=true
    export RPK_SASL_MECHANISM="<SCRAM-SHA-256 or SCRAM-SHA-512>"
    export RPK_USER=<user>
    export RPK_PASS=<password>
    ```

2.  Create a test topic.

    ```bash
    rpk topic create test-topic
    ```

3.  Produce to the test topic.

    ```bash
    echo 'hello world' | rpk topic produce test-topic
    ```

4.  Consume from the test topic.

    ```bash
    rpk topic consume test-topic -n 1
    ```


> 📝 **NOTE**
>
> If both public and private access are enabled for your cluster, `rpk cloud cluster select` will prompt you to choose between public or private connectivity when you select the cluster.

## [](#suggested-reading)Suggested reading

-   [Configure AWS PrivateLink in the Cloud Console](https://docs.redpanda.com/cloud-data-platform/networking/serverless/aws/privatelink-ui/)

-   [Manage Redpanda Cloud with Terraform](https://docs.redpanda.com/cloud-data-platform/manage/terraform-provider/)