Skip to content
Docs

Deploying with BYOC Using the Edgenivo CLI

Bring Your Own Cloud is available on Enterprise plans and is set up through your Edgenivo account team. Contact your account team to request access.

Create a Bring Your Own Cloud (BYOC) deployment from your machine or CI with the Edgenivo CLI. You initialize a deployment, build it, generate its AWS resource descriptor, provision the functions in your AWS account, and then tell Edgenivo to complete the deployment.

  • An AWS account connected to your Edgenivo team with the Active status.
  • The ARN of a Lambda execution role in that account.
  • macOS or Linux with Node.js 20 or later. vercel deploy describe doesn't run on Windows.
  • Edgenivo CLI 63.1.2 or later. Install the latest version with npm i -g vercel@latest.
  • The AWS CLI v2 and jq.
  • AWS credentials for an identity with the provisioning permissions.
  • A Edgenivo project with its build settings and environment variables configured for the target environment.

The Edgenivo CLI generates the AWS resources to create, but doesn't create them. You need a provisioning tool that reads descriptor.json and creates the Lambda layers and functions in your account. Choose one of these options:

  • Generate a script with the BYOC agent skill: Install the BYOC skill in your application repository, then ask your coding agent to create a provisioning script.
  • Use your own tooling: Build provisioning into your existing infrastructure tooling, such as Terraform or the AWS SDK, following the BYOC provisioning reference.

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

Terminal
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:

Prompt
Using the BYOC skill, create `pnpm byoc:provision <deployment-id>` using the execution role arn:aws:iam::<AWS_ACCOUNT_ID>: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.

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

You have 15 minutes from vercel deploy init to vercel deploy continue. Finish linking the project, authenticating, and setting up your provisioning tool before you initialize the deployment.

  1. 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:

    Terminal
    team_id="<TEAM_ID>"
    project_name="my-app"
    target="preview"
    aws_account_id="<AWS_ACCOUNT_ID>"

    Authenticate the Edgenivo CLI with vercel login, and make sure your AWS credentials point to the intended account:

    Terminal
    aws sts get-caller-identity

    Check: The Account value in the output matches aws_account_id.

  2. Link your application to the Edgenivo project, then pull the project settings for the target environment:

    Terminal
    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.

  3. Create a deployment on Edgenivo and save its ID. vercel deploy init uploads no files. The deployment waits for you to provision its functions:

    Terminal
    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 above handles both.

    Check: The printed target is production for a production deployment, or null for a preview deployment. A new project's first deployment is assigned to production even when you request preview. If the target is wrong, mark the deployment as failed and initialize another.

  4. Build the application with the environment variables of the deployment you initialized:

    Terminal
    vercel build --id "$deployment_id" --target "$target" --yes

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

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

    Terminal
    vercel deploy describe --id "$deployment_id" --aws-account-id "$aws_account_id"

    vercel deploy describe uses the team in .vercel/project.json, and fails if --scope or VERCEL_ORG_ID names a different team. It doesn't create any AWS resources.

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

    PathContents
    descriptor.jsonThe 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

    It 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 version.

    The function ZIP files contain your application code and environment variable values. Keep the .vercel directory private and keep the workspace until the deployment completes. For field-level details, see the BYOC provisioning reference.

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

    Terminal
    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.

    Check: Every function in descriptor.json exists in AWS with the Active state. To list the functions and regions the descriptor expects, run:

    Terminal
    jq -r '.functions[] | "\(.region) \(.configuration.FunctionName)"' ".vercel/$deployment_id/descriptor.json"
  7. Tell Edgenivo the functions are ready. vercel deploy continue uploads the code-free output and provision.json, then waits for the deployment to finish:

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

    Check: vercel inspect reports the READY status.

  8. Request a dynamic route through the exact deployment. Replace /api/hello with a route in your application that runs a function:

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

    A static or cached response doesn't prove that BYOC is working. Confirm that the function ran in your account by checking its Amazon CloudWatch logs, using a function name and region from the descriptor:

    Terminal
    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.

You can change how your provisioning tool creates functions, for example to attach functions to a VPC or add Lambda layers. Keep the generated function names, handlers, runtimes, memory, timeouts, environment variables, and tags exactly as they appear in the descriptor. Edgenivo invokes each function by its generated name, so renaming a function causes requests to it to fail. For the full list of values to preserve, see Values to keep as generated.

If you attach functions to a VPC, route the subnets through a NAT gateway or equivalent egress so functions keep outbound internet access, and check your security group rules and DNS resolution.

For function packages larger than 50 MB, upload the ZIP files to a private Amazon S3 bucket in the same region as the function, and create the function from the bucket. See Function package size.

SymptomCauseFix
Deployment dpl_... was not found, or manual provisioning is not enabled for this team.BYOC isn't enabled for the team, or the deployment ID belongs to a different teamConfirm the deployment ID and linked team. Ask your Edgenivo account team to confirm BYOC is enabled.
vercel deploy describe reports a scope or project mismatch--scope, VERCEL_ORG_ID, or VERCEL_PROJECT_ID doesn't match .vercel/project.jsonRemove the conflicting value or relink the project.
vercel deploy describe rejects the build as unsupportedThe build includes functions using the Edge runtime or the container runtime, or ServicesMove those functions to the Node.js or Python runtime, and remove Services from the project. See BYOC limitations.
No prebuilt output found in ".vercel/output"vercel deploy continue ran from a different directory, or before vercel deploy describeRun every command from the application's directory, in order.
Provisioning exceeded the maximum allowed time.More than 15 minutes passed between vercel deploy init and vercel deploy continueStart a new deployment. See Failures and retries.
The deployment is READY, but dynamic routes failThe invocation role can't invoke the functions, or the account credentials are ExpiredCheck the invocation role's permissions policy and the account status in Connect AWS Account.

Was this helpful?

supported.