---
title: The Complete Guide to Bring Your Own Cloud
description: Use Bring Your Own Cloud (BYOC) to run Vercel Functions as AWS Lambda functions in your own AWS account, from setup to deployment and operations.
url: "https://vercel.com/kb/guide/byoc"
published: 2026-10-15
last_updated: 2026-10-15
authors: Ben Sabic
install_vercel_plugin: npx plugins add vercel/vercel-plugin
---

Some teams can’t run application code on infrastructure they don’t own, because their security, compliance, or data-residency rules require compute to stay in a cloud account they control. Bring Your Own Cloud (BYOC) runs the Vercel Functions behind your project as AWS Lambda functions in your own AWS account.

Vercel still routes requests, terminates TLS at the CDN, serves static assets, and manages each deployment. You retain the Vercel deployment workflow and CDN while managing your functions, their IAM permissions, and network access in your own AWS account.

## How Bring Your Own Cloud works

BYOC splits each deployment between Vercel and your AWS account. You build the application and define its functions in AWS, and Vercel handles deployment and invokes those functions when requests arrive.

### What Vercel runs and what your team runs with BYOC

With BYOC, your team takes on the operational parts of the platform that run in your own AWS account:

| Area                      | Vercel                                               | Your team                                                                 |
| ------------------------- | ---------------------------------------------------- | ------------------------------------------------------------------------- |
| Request routing and TLS   | Routes requests and terminates TLS at the Vercel CDN | None                                                                      |
| Static assets             | Stores and serves static assets                      | None                                                                      |
| Builds                    | Provides the build and packaging commands in the CLI | Runs builds on your own machines or CI                                    |
| Function code and runtime | None                                                 | Creates, stores, and runs Lambda functions and layers in your AWS account |
| IAM                       | Assumes the invocation role you grant in AWS         | Creates and maintains the invocation role and the Lambda execution role   |
| Networking                | None                                                 | Provides outbound internet access, VPC attachment, and security rules     |
| Quotas and scaling        | None                                                 | Maintains AWS service quotas, concurrency limits, and scaling headroom    |
| Logs                      | Shows deployment status                              | Collects function logs in Amazon CloudWatch                               |
| Cleanup                   | Sends the `deployment.cleanup` webhook               | Deletes AWS resources for deployments you no longer need                  |

Plan for someone on your team to own the AWS account continuously, because Vercel can't raise your AWS quotas, recreate deleted functions, or fix IAM or network changes made in your account.

### How requests reach BYOC functions

Vercel only contacts your AWS account when a request needs a function to run. When a request arrives for a BYOC deployment:

1. The Vercel CDN receives the request and terminates TLS.
   
2. Vercel serves static assets and cached responses directly, without contacting your AWS account.
   
3. For a dynamic route, Vercel assumes the invocation role in your AWS account and invokes the matching Lambda function.
   
4. The function's response returns through Vercel to the client.
   

### How a BYOC deployment is created

Each BYOC deployment moves through five stages, which you run from your machine or your CI environment:

1. **Initialize**: `vercel deploy init` creates a deployment on Vercel that waits for you to provision its functions. No files are uploaded at this stage.
   
2. **Build**: `vercel build --id` builds your application with the environment variables of that deployment.
   
3. **Describe**: `vercel deploy describe` packages each function as a ZIP file and writes a `descriptor.json` file that lists the Lambda functions and layers to create. This command doesn't create any AWS resources.
   
4. **Provision**: Your provisioning tool creates the Lambda functions and layers in your AWS account from the descriptor.
   
5. **Continue**: `vercel deploy continue` uploads your static assets and deployment metadata, without function code, and Vercel completes the deployment.
   

You have 15 minutes from `vercel deploy init` to `vercel deploy continue`.

After 15 minutes, the deployment fails with the error: `Provisioning exceeded the maximum allowed time.`

### The two IAM roles BYOC uses

BYOC uses two separate IAM roles in your AWS account, and each one is assumed by a different principal:

| Role                  | Assumed by                          | Purpose                                                                             |
| --------------------- | ----------------------------------- | ----------------------------------------------------------------------------------- |
| Invocation role       | Vercel                              | Lets Vercel call `lambda:InvokeFunction` on your BYOC functions                     |
| Lambda execution role | AWS Lambda (`lambda.amazonaws.com`) | Grants your functions logging access and any AWS permissions your application needs |

You register the invocation role with Vercel once per team, and every BYOC project on the team can reuse that connection. You pass the execution role to your provisioning tool for each deployment.

### What data Vercel receives from a BYOC deployment

BYOC keeps function code and function execution in your AWS account. Vercel receives only what it needs to serve the deployment and invoke your functions:

| Data                                           | Sent to Vercel                                               |
| ---------------------------------------------- | ------------------------------------------------------------ |
| Function code and runtime layers               | No. Function packages stay on your build machine and in AWS. |
| Static assets                                  | Yes                                                          |
| Routing and function configuration metadata    | Yes                                                          |
| Function-to-Lambda mappings (`provision.json`) | Yes                                                          |
| Your application's `package.json` files        | Yes                                                          |
| Request and response data                      | Yes. Requests and responses pass through the Vercel CDN.     |

The function packages that `vercel deploy describe` generates contain your application code and environment variable values. Keep the `.vercel` directory private on your build machine and in CI artifacts and caches. Review your data handling and compliance requirements with your Vercel account team.

## When to use Bring Your Own Cloud

Use BYOC when a security, compliance, or data-residency requirement means your application code must run in an AWS account you own.

If Vercel can run your compute, compare its networking options for IP allowlisting or private backend connectivity:

| Requirement                                                                             | Option                                                              |
| --------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| Your backend allowlist needs a known set of source IPs                                  | [Static IPs](https://vercel.com/docs/networking/static-ips)         |
| Your workloads need a dedicated, single-tenant VPC with VPC peering or site-to-site VPN | [Secure Compute](https://vercel.com/docs/networking/secure-compute) |
| Function code must run in your own AWS account                                          | Bring Your Own Cloud                                                |

### When Bring Your Own Cloud isn't the right fit

BYOC isn't the right choice in these situations:

- **All traffic must stay in your account**: TLS terminates at the Vercel CDN, and requests and responses pass through Vercel.
  
- **You need a government certification**: BYOC doesn't currently satisfy FedRAMP or other government certification requirements.
  
- **You rely on unsupported features**: BYOC doesn't support the Edge runtime, the container runtime, or Services.
  
- **Your team can't own AWS operations**: BYOC moves function provisioning, quotas, and cleanup into your account.
  

## Prerequisites

Before you begin, make sure you have:

- A Vercel team on the Enterprise plan and access to BYOC.
  
- Permission to manage your team's Networking settings.
  
- Permission in your AWS account to create IAM roles and attach policies to them.
  
- The [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) v2 and [`jq`](https://jqlang.org/download/). You can also use the AWS Console or an infrastructure-as-code tool such as Terraform in place of the AWS CLI commands.
  
- [Vercel CLI](https://vercel.com/docs/cli) installed (`npm i -g vercel`)
  
- Node.js 22+ and a package manager (e.g., [pnpm](https://pnpm.io/))
  

## Steps

### 1\. Create the invocation role in your AWS account

The invocation role lets Vercel invoke your BYOC functions, and you create it with a trust policy that Vercel provides in the dashboard.

1. Go to your team's **Settings** → [**Networking**](https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fsettings%2Fnetworking&title=Networking).
   
2. In the **Vercel Private Cloud** section, click the **Add Account** button.
   

The **Add AWS Account** dialog shows the **External ID** for your team, the **IAM Trust Policy**, and the **IAM Permissions Policy** for the invocation role. The external ID is your Vercel team ID. Keep the dialog open while you create the role.

Copy the IAM Trust Policy from the dialog into a file named `trust-policy.json`.

It has this shape, with your team ID as the external ID:

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::977805900156:user/aws-external-credentials-refresh-user-sfo1"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "your_vercel_team_id"
        }
      }
    }
  ]
}
```

The dashboard is the source of truth for this policy. If the policy in the dialog differs from this example, use the dialog's version.

Create the role with the `VercelFunction` tag set to `true` and a maximum session duration of 12 hours (43,200 seconds). Vercel requires both settings:

```bash
aws iam create-role \
  --role-name VercelPrivateCloudRole \
  --assume-role-policy-document file://trust-policy.json \
  --max-session-duration 43200 \
  --tags Key=VercelFunction,Value=true
```

The role can have any valid name. This example uses `VercelPrivateCloudRole`, the name the dashboard suggests. Registration fails if the role is missing the `VercelFunction` tag or has a maximum session duration shorter than 12 hours.

### 2\. Grant the invocation role permission to invoke your functions

The permissions policy lets the invocation role call Lambda functions.

Copy the IAM Permissions Policy from the dialog into a file named `invoke-policy.json`, and add your 12-digit AWS account ID:

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "InvokeFunctionsInAccount",
      "Effect": "Allow",
      "Action": "lambda:InvokeFunction",
      "Resource": "arn:aws:lambda:*:your_aws_account_id:function:*"
    }
  ]
}
```

Attach the policy to the invocation role as an inline policy:

```bash
aws iam put-role-policy \
  --role-name VercelPrivateCloudRole \
  --policy-name VercelInvokeFunctions \
  --policy-document file://invoke-policy.json
```

This policy allows Vercel to invoke current and future functions, versions, and aliases in your account across all AWS regions. It doesn't grant permission to create, change, or delete functions. The `VercelFunction` tag belongs on the IAM role only, so your Lambda functions don't need it.

If you narrow the `Resource` pattern to specific function ARNs, update the policy before each deployment so it covers every function in that deployment's descriptor.

### 3\. Register the AWS account in Vercel

Registering the account tells Vercel which role to assume.

In the **Add AWS Account** dialog:

1. Enter your 12-digit **AWS Account ID**.
   
2. In **IAM Role Name**, enter `VercelPrivateCloudRole` or your chosen name.
   
3. Click the **Add Account** button.
   

Vercel checks that it can assume the role with the required session duration and shows **Account Registered** when the check passes. Registration doesn't check the Lambda invocation permissions or whether any functions exist.

Newly registered accounts show the **No Credentials** status. Click **Refresh Credentials** on the account row to request the first set of credentials, then wait until the status changes to **Active**.

After the first refresh, Vercel refreshes the credentials automatically, as long as the role's trust policy, permissions policy, tag, and session duration stay in place.

| Status         | Meaning                                                                               | Action                                                                                                                |
| -------------- | ------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| No Credentials | The account is registered, but Vercel hasn't obtained credentials yet                 | Click **Refresh Credentials**                                                                                         |
| Active         | Vercel has valid credentials for the invocation role and refreshes them automatically | None                                                                                                                  |
| Expired        | Vercel's credentials have expired and automatic refresh hasn't succeeded              | Check the role's trust policy, tag, and session duration, then select **Refresh Credentials** from the account's menu |

The **Active** status means Vercel has valid credentials for the role. It doesn't confirm that your functions can be invoked, so missing invocation permissions still cause BYOC requests to fail.

### 4\. Create the Lambda execution role

Your BYOC functions run as a Lambda execution role, which is separate from the invocation role. One execution role can serve all functions in an application.

Create the role with a trust policy that allows Lambda to assume it. Attach the AWS managed policy for CloudWatch logging:

```bash
aws iam create-role \
  --role-name byoc-lambda-execution \
  --assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"lambda.amazonaws.com"},"Action":"sts:AssumeRole"}]}'

aws iam attach-role-policy \
  --role-name byoc-lambda-execution \
  --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
```

Add application-specific permissions to the role for services such as Amazon S3 or Amazon DynamoDB. Then save its ARN, such as `arn:aws:iam::123456789012:role/byoc-lambda-execution`, for your provisioning tool.

### 5\. Set up a provisioning tool and its AWS permissions

The Vercel CLI generates a description of the AWS resources to create, but it doesn't create them. To create them, you need a provisioning tool that reads `descriptor.json` and creates the Lambda layers and functions in your account.

You have two options:

- Install the [BYOC skill](https://github.com/vercel-labs/vercel-byoc) in your application repository and ask your coding agent to generate a provisioning script.
  
- Build provisioning into existing infrastructure tooling, such as Terraform or the AWS SDK, following the [BYOC provisioning reference](https://vercel.com/docs/networking/bring-your-own-cloud/provisioning-reference).
  

To use the BYOC skill, install it from your application's directory:

```bash
npx skills add vercel-labs/vercel-byoc
```

Then ask your coding agent to create a project script, replacing the execution role ARN with your own:

```text
Using the BYOC skill, create `pnpm byoc:provision <deployment-id>` using the execution role arn:aws:iam::123456789012:role/byoc-lambda-execution.
```

The rest of this guide runs that script as `pnpm byoc:provision`. If you use your own tooling, run your tool at the provisioning step instead.

The identity that runs your provisioning tool needs permission to publish layers, create and read functions, tag them, and pass the execution role to Lambda. This example policy covers those actions. Replace `123456789012` with your AWS account ID and `byoc-lambda-execution` with your execution role name:

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ManageByocLayers",
      "Effect": "Allow",
      "Action": [
        "lambda:ListLayerVersions",
        "lambda:GetLayerVersion",
        "lambda:PublishLayerVersion"
      ],
      "Resource": "*"
    },
    {
      "Sid": "ManageByocFunctions",
      "Effect": "Allow",
      "Action": [
        "lambda:CreateFunction",
        "lambda:GetFunction",
        "lambda:GetFunctionConfiguration",
        "lambda:TagResource"
      ],
      "Resource": "arn:aws:lambda:*:123456789012:function:*"
    },
    {
      "Sid": "PassExecutionRole",
      "Effect": "Allow",
      "Action": "iam:PassRole",
      "Resource": "arn:aws:iam::123456789012:role/byoc-lambda-execution",
      "Condition": {
        "StringEquals": {
          "iam:PassedToService": "lambda.amazonaws.com"
        }
      }
    }
  ]
}
```

Add `s3:PutObject` and `s3:GetObject` on your staging bucket if you upload large packages through Amazon S3, and add `lambda:DeleteFunction` and `lambda:DeleteLayerVersion` if the same identity runs cleanup. Don't grant `AdministratorAccess` to the provisioning identity.

### 6\. Create a BYOC deployment with the Vercel CLI

Run every command from your application's directory and use the same deployment ID from initialization through completion.

The 15-minute provisioning window starts at `vercel deploy init`. Finish linking the project, authenticating, and setting up your provisioning tool before you run it.

#### Set the deployment variables

Set the values for your team, project, target environment, and AWS account. Use `preview` or `production` for the target, and keep the same value throughout:

```bash
team_id="team_1234567890abcdefghij"
project_name="my-app"
target="preview"
aws_account_id="123456789012"
```

Authenticate the Vercel CLI with `vercel login`, then check the AWS profile you'll use for provisioning. Replace `byoc-provisioner` with your profile name here and in the provisioning command:

```bash
AWS_PROFILE="byoc-provisioner" aws sts get-caller-identity
```

**Check**: The `Account` value in the output matches `aws_account_id`.

#### Link the project and pull its settings

Link your Vercel project and pull its target environment settings:

```bash
vercel link --yes --team "$team_id" --project "$project_name"
vercel pull --yes --environment "$target" --scope "$team_id"
```

**Check**: `.vercel/project.json` contains the intended team and project.

#### Initialize the deployment

Create a deployment on Vercel and save its ID. `vercel deploy init` uploads no files, and the deployment waits for you to provision its functions:

```bash
mkdir -p .vercel/byoc
vercel deploy init --yes --target "$target" --scope "$team_id" --json > .vercel/byoc/init.json
deployment_id=$(jq -er '.deployment.id // .id' .vercel/byoc/init.json)
jq -r '.deployment.target // .target' .vercel/byoc/init.json
```

The deployment ID is at `.id` when you run the command in a terminal, and at `.deployment.id` when the CLI runs non-interactively, such as in CI or from a coding agent. The `jq` expression handles both.

Check: The printed target matches `target`. Vercel assigns a new project's first deployment to production even when you request `preview`. If the target is wrong, [abandon the deployment](#how-to-abandon-a-pending-byoc-deployment) and initialize another.

#### Build the application

Build with the initialized deployment's environment variables:

```bash
vercel build --id "$deployment_id" --target "$target" --yes
```

**Result**: The build output is written to `.vercel/output`.

#### Describe the AWS resources

Package the functions and generate the descriptor for your AWS account:

```bash
vercel deploy describe --id "$deployment_id" --aws-account-id "$aws_account_id"
```

`vercel deploy describe` uses `.vercel/project.json` for the team. It rejects conflicting `--scope` or `VERCEL_ORG_ID` values and creates no AWS resources.

**Result**: The command writes these files under `.vercel/<deployment-id>/`:

| Path              | Contents                                                      |
| ----------------- | ------------------------------------------------------------- |
| `descriptor.json` | The Lambda functions and layers to create in your AWS account |
| `zips/`           | One ZIP file per function                                     |
| `layers/`         | One ZIP file per runtime layer                                |
| `build/`          | The original build output, moved from `.vercel/output`        |

The command also replaces `.vercel/output` with a version that contains no function code, plus a `provision.json` file that maps routes to Lambda functions. `vercel deploy continue` uploads this code-free version. Keep the workspace until the deployment completes.

#### Provision the functions in AWS

Run your provisioning tool with the credentials of your provisioning identity. This example selects a local AWS CLI profile with `AWS_PROFILE`:

```bash
AWS_PROFILE="byoc-provisioner" pnpm byoc:provision "$deployment_id"
```

Your provisioning tool must create every layer and function in the descriptor, in each function's AWS region, and wait until each function reaches the `Active` state. The invocation role must allow `lambda:InvokeFunction` on every function you create.

To list the functions and regions the descriptor expects, run:

```bash
jq -r '.functions[] | "\(.region) \(.configuration.FunctionName)"' ".vercel/$deployment_id/descriptor.json"
```

**Check**: Every function in `descriptor.json` exists in AWS with the `Active` state.

#### Complete the deployment

Tell Vercel the functions are ready. `vercel deploy continue` uploads the code-free output and `provision.json`, then waits for the deployment to finish:

```bash
vercel deploy continue --id "$deployment_id" --scope "$team_id"
vercel inspect "$deployment_id" --scope "$team_id" --wait
```

**Check**: `vercel inspect` reports the `READY` status.

### 7\. Verify that a function runs in your AWS account

Reaching `READY` confirms the deployment completed, but only a function invocation proves BYOC is working. Request a dynamic route through the exact deployment, replacing `/api/hello` with a route in your application that runs a function:

```bash
vercel curl "/api/hello" --deployment "$deployment_id" --scope "$team_id" -- --fail-with-body --silent --show-error
```

Static or cached responses don't prove that the request reached your AWS account. Confirm the function ran by checking its Amazon CloudWatch logs, using a function name and region from the descriptor:

```bash
aws logs tail "/aws/lambda/your_function_name" --region us-east-1 --since 10m
```

**Check**: The route returns the expected response, and the function's CloudWatch log group shows the invocation. If your functions run in multiple regions, confirm each region's functions exist and record which region handled your test requests.

### 8\. Automate BYOC deployments from GitHub Actions (optional)

The BYOC Git flow keeps the Vercel Git integration for your project, so every push creates a preview or production deployment that GitHub Actions builds, provisions in your AWS account, and completes. You can also run the CLI flow from any other CI system instead.

#### How the GitHub Actions flow works

With the BYOC Git flow turned on, Vercel doesn't build your pushes itself:

1. You push a commit, and the Vercel Git integration creates a BYOC deployment that waits for provisioning.
   
2. Vercel sends the `deployment.build-requested` webhook to a webhook relay, which is an AWS Lambda function in your AWS account.
   
3. The relay verifies the webhook signature and starts your GitHub Actions workflow through a GitHub App.
   
4. The workflow checks out the deployment's exact commit and runs the CLI flow with the existing deployment ID, including `vercel build --id`, `vercel deploy describe`, provisioning, and `vercel deploy continue`.
   

The workflow uses OpenID Connect (OIDC) to obtain short-lived credentials for Vercel and AWS on each run without storing long-lived access keys.

Time spent waiting in the GitHub Actions queue counts toward the 15-minute provisioning window, which starts when Vercel creates the deployment.

#### Additional prerequisites for the GitHub Actions flow

- At least one successful CLI deployment for the project, including the AWS account connection and the Lambda execution role
  
- Administrator access to the GitHub repository
  
- AWS permissions to create the relay's supporting resources, including a Lambda function, an AWS Secrets Manager secret, and IAM roles
  
- Help from a Vercel team Owner to configure OIDC authentication for the Vercel CLI. If OIDC authentication for the CLI isn't available on your team, ask your Vercel account team to enable it.
  
- The BYOC agent skill installed in your application repository
  

#### Generate the integration

From your application repository, ask your coding agent to generate the integration with your AWS CLI profile and execution role ARN:

```text
Set up GitHub Actions for this project's BYOC deployments using AWS profile byoc-admin and Lambda execution role arn:aws:iam::123456789012:role/byoc-lambda-execution.
```

The agent identifies your Vercel project, confirms the AWS account and region, and generates four pieces:

| Piece                   | Purpose                                                                            |
| ----------------------- | ---------------------------------------------------------------------------------- |
| GitHub Actions workflow | Builds, describes, provisions, and continues each requested deployment             |
| Provisioning scripts    | Create the Lambda layers and functions from `descriptor.json`                      |
| Webhook relay           | Receives `deployment.build-requested` and starts the workflow                      |
| Infrastructure template | Creates the relay, its secret, and the AWS roles the workflow assumes through OIDC |

The local AWS profile is used only for setup, and the workflow itself uses OIDC.

#### Create and install the GitHub App

Create a GitHub App for the relay to start workflows:

1. Create a private GitHub App in the repository owner's account or organization.
   
2. Grant **Repository permissions** → **Actions**: **Read and write**, and leave incoming webhooks turned off.
   
3. Install the App on the BYOC repository only.
   
4. Generate and download a private key for the App.
   

Give the agent the App ID, the installation ID, and the local path to the private key file. Don't paste the key into a chat or commit it to the repository.

#### Deploy and verify the integration

Have the agent deploy the infrastructure template and upload the relay code. The agent stores the GitHub App private key and webhook signing secret in AWS Secrets Manager in your selected account and region.

It publishes the workflow on the default branch and adds a Vercel `deployment.build-requested` webhook for the project with signature verification.

**Check**: Before you turn on the flow, have the agent report these results:

- **Relay**: The relay's URL and log location, plus the secret's name and region in AWS Secrets Manager
  
- **Vercel authentication**: GitHub Actions jobs can obtain temporary Vercel credentials and read the intended project
  
- **AWS authentication**: GitHub Actions jobs can assume the provisioning role in the intended AWS account
  

#### Turn on the BYOC Git flow

Connect the project to Vercel's Git integration if needed. Add `byocGitFlow` to `vercel.json` and keep its other settings:

```json
{
  "byocGitFlow": true
}
```

Alternatively, set `VERCEL_BYOC_GIT_FLOW` to `1` in each project environment using the BYOC Git flow. CLI deployments need neither setting.

#### Test preview and production deployments

Push a new commit to a preview branch and repeat on your production branch.

**Check**: The GitHub Actions workflow runs for the commit, the Vercel deployment reaches `READY`, and an existing dynamic route returns the expected response.

If the deployment uses [Deployment Protection](https://vercel.com/docs/deployment-protection), have the agent configure [Protection Bypass for Automation](https://vercel.com/docs/deployment-protection/methods-to-bypass-deployment-protection/protection-bypass-automation) so the workflow's check can reach the deployment.

## How to customize BYOC provisioning

You can change how your provisioning tool creates functions, for example to attach functions to a VPC or add Lambda layers. Vercel invokes each function by its generated name and your build depends on the generated runtime settings, so keep these descriptor values exactly as generated:

- `FunctionName`
  
- `Handler`
  
- `Runtime`, `Architectures`, `MemorySize`, `Timeout`, and `EphemeralStorage`
  
- `Environment.Variables`
  
- `Tags`
  
- The layer order in `layers`
  

Renaming a function causes requests to it to fail. The descriptor's `configuration` object uses AWS `CreateFunction` parameter names and never contains `Role`, `Code`, or `Layers`, which your provisioning tool supplies.

For VPC-attached functions, the execution role needs permission to manage network interfaces. The AWS managed policy `AWSLambdaVPCAccessExecutionRole` grants these permissions.

For VPC attachment, the provisioning identity also needs `ec2:DescribeSecurityGroups`, `ec2:DescribeSubnets`, `ec2:DescribeVpcs`, and `ec2:GetSecurityGroupsForVpc` to inspect the network resources.

Route private subnets through a NAT gateway or equivalent egress to keep outbound internet access. Check security group rules and DNS resolution.

AWS Lambda accepts function ZIP files up to 50 MB when you upload them directly. For larger ZIP files, upload to a private Amazon S3 bucket in the same region as the function and create the function from that bucket.

The unzipped function package, layers, and custom runtime must fit within Lambda's [250 MB limit](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html). Uploading through S3 doesn't increase this limit.

Your account may already contain a function with the same name, for example from an earlier attempt at the same deployment. Reuse an existing function only when its code hash and full configuration match the descriptor. Don't overwrite a function that differs, because it may serve another deployment that's still receiving traffic.

## How to operate BYOC deployments

With BYOC, your team operates the AWS side of every deployment, including retries, cleanup, monitoring, and credential rotation.

### How to retry a failed BYOC deployment

When a BYOC deployment fails, check its status with `vercel inspect <deployment-id>` and the output of the failed CLI command or CI job. The right next step depends on the deployment's state:

| Deployment state                                                    | What to do                                                                                                                                                          |
| ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Still waiting for provisioning, within 15 minutes of initialization | Fix the cause, then retry with the same deployment ID, generated files, and resource inventory. Reuse the functions and layers you already created when they match. |
| Failed, canceled, or timed out                                      | Start a new deployment with `vercel deploy init`, or redeploy through Vercel. The new deployment gets a new ID. Keep the old inventory for cleanup.                 |
| `READY`                                                             | Don't provision it again. Test the deployment, or create a new deployment for any changes.                                                                          |

If you need to change code while a deployment is waiting for provisioning, rebuild and run `vercel deploy describe` with the same deployment ID. Then provision from the new descriptor.

Run only one build and provisioning worker per deployment ID at a time to avoid conflicts when creating functions.

### How to abandon a pending BYOC deployment

Mark a pending deployment as failed and explain why you are stopping it:

```bash
vercel deploy continue --id "dpl_1234567890abcdefghij" --error "Initialized with the wrong target"
```

**Result:** The CLI prints `Marked deployment dpl_1234567890abcdefghij as errored` and Vercel shows the deployment as failed.

Failed and abandoned deployments can leave functions and layers in your AWS account. Include those resources in your cleanup process.

### How to clean up AWS resources for old deployments

Deleting a deployment in Vercel doesn't delete its Lambda functions or layers in your AWS account. Record the ARNs of the functions and layer versions created for each deployment in a durable inventory.

The script generated by the BYOC agent skill writes this inventory to `.vercel/<deployment-id>/provisioned.json`, marking which resources it created and which it reused.

Keep the resources for every deployment you still serve, including deployments you may [roll back](https://vercel.com/docs/instant-rollback) to. For deployments you no longer need:

1. Delete the functions that the inventory marks as created for that deployment.
   
2. Delete a layer version only after confirming that no remaining function uses it, because layers can be shared between deployments.
   
3. Keep the AWS account registration and the invocation role, because other deployments depend on them.
   

To automate cleanup, build a handler for the [`deployment.cleanup`](https://vercel.com/docs/webhooks/webhooks-api) webhook. Vercel sends this webhook when it permanently deletes a deployment, after the 30-day recovery period ends, and not when a deployment is first marked for deletion.

Your handler uses the deployment ID to find resources in your inventory and delete them. Keep cleanup manual until the handler is configured and tested.

### Where to find BYOC logs and monitoring signals

BYOC spreads operational signals across Vercel, your CI system, and AWS:

| Signal                              | Where to find it                                                                                 |
| ----------------------------------- | ------------------------------------------------------------------------------------------------ |
| Deployment status and build errors  | Vercel dashboard, `vercel inspect`, or the REST API                                              |
| Build and provisioning job failures | Your CI system, such as GitHub Actions                                                           |
| Function logs and errors            | Amazon CloudWatch Logs, in the log group `/aws/lambda/<function-name>` in each function's region |
| Account credential status           | The **Vercel Private Cloud** section of your team's Networking settings                          |

The Vercel REST API deployment response includes `manualProvisioning.state`, which is `PENDING`, `COMPLETE`, or `TIMEOUT`.

Assign an owner to monitor failed deployments, account credential status, and application health. Use Amazon CloudWatch alarms or similar monitoring for function errors and throttles.

### How to rotate BYOC credentials

Rotate each credential type in the place it's stored:

- **Invocation role**: Vercel refreshes its credentials for the invocation role automatically. Keep the role's trust policy, permissions policy, `VercelFunction` tag, and 12-hour maximum session duration in place. If the account shows **Expired**, fix the role and select **Refresh Credentials**.
  
- **GitHub App keys and webhook secrets**: Update the key or secret in GitHub or Vercel and in the relay's stored secret together. Reload the relay and verify a deployment end to end before you retire the old credential.
  
- **OIDC credentials**: GitHub Actions obtains short-lived credentials for Vercel and AWS through OIDC on each run, so there are no long-lived keys to rotate.
  

### How to disconnect an AWS account

Before you disconnect an account, replace or remove any deployments that depend on it, because those deployments can't invoke their functions afterward.

1. Go to your team's **Settings** → [**Networking**](https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fsettings%2Fnetworking&title=Networking).
   
2. In the **Vercel Private Cloud** section, open the menu on the account row.
   
3. Select **Disconnect** and confirm.
   

Disconnecting removes the registration and stored credentials from Vercel and stops automatic credential refresh. It doesn't delete the IAM roles, Lambda functions, or any other resources in your AWS account.

Credentials that Vercel obtained before you disconnected stay valid for up to 12 hours. To revoke them immediately, [revoke the role's active sessions](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_revoke-sessions.html) in AWS.

## What are the limitations of Bring Your Own Cloud

| Limitation                 | Details                                                                            |
| -------------------------- | ---------------------------------------------------------------------------------- |
| Cloud provider             | AWS only. Functions run on AWS Lambda.                                             |
| Runtimes                   | Node.js and Python                                                                 |
| Unsupported function types | Functions using the Edge runtime or the container runtime, and Services            |
| Build environment          | macOS or Linux. `vercel deploy describe` doesn't run on Windows.                   |
| Provisioning window        | 15 minutes from `vercel deploy init` to `vercel deploy continue`                   |
| Network access             | The AWS account and subnets that host your functions need outbound internet access |
| Government certifications  | Doesn't currently satisfy FedRAMP or other government certification requirements   |

## Next steps

- Read the [Bring Your Own Cloud overview](https://vercel.com/docs/networking/bring-your-own-cloud) in the Vercel docs
  
- See [Connecting an AWS account for BYOC](https://vercel.com/docs/networking/bring-your-own-cloud/connect-aws-account) for statuses and IAM details.
  
- Use [Deploying with BYOC using the Vercel CLI](https://vercel.com/docs/networking/bring-your-own-cloud/deploy-with-cli) as a command reference
  
- Set up [Deploying with BYOC from GitHub Actions](https://vercel.com/docs/networking/bring-your-own-cloud/deploy-with-github-actions) to deploy on every Git push
  
- Build or audit a provisioning tool with the [BYOC provisioning reference](https://vercel.com/docs/networking/bring-your-own-cloud/provisioning-reference)
  
- Review [Operating BYOC deployments](https://vercel.com/docs/networking/bring-your-own-cloud/operations) for retries, cleanup, and monitoring
  
- Compare BYOC with other options in [Choosing a networking option](https://vercel.com/docs/networking#choosing-a-networking-option)
  
- Learn more about [Vercel Functions](https://vercel.com/docs/functions)