Byoc infrastructure
Skill streamnative/streamnative-agent-skills/skills/byoc-infrastructure
Set up BYOC (Bring Your Own Cloud) substrate for StreamNative Cloud — cloud connections (AWS/GCP/Azure account linkage), cloud environments (region/VPC/CIDR), tiered-storage volumes, and pool members. Use when the user mentions BYOC, their own AWS/GCP/Azure account, `cloudconnection`, `cloudenvironment`, pool members, networking CIDRs, IAM role ARNs, or tiered-storage S3 volumes. Does NOT cover serverless/dedicated deployments or Pulsar cluster lifecycle — use pulsar-clusters for those.From its SKILL.md
npx -y skills add streamnative/streamnative-agent-skills --skill byoc-infrastructureAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its file declares
Copied from the file, not written here
The file declares its own license as Apache-2.0. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
11.3 KB, as published. Nobody here has run it
byoc-infrastructure
When to use this skill
- User mentions "BYOC", "Bring Your Own Cloud", "my AWS account", "my GCP project", or "my Azure subscription".
- User asks about
cloudconnection,cloudenvironment,volume, or pool members. - User references a CIDR block, VPC, IAM role ARN, or S3 bucket for Pulsar tiered storage.
Execution base
Prefer StreamNative Cloud remote MCP when available: use sncloud_byoc_read / sncloud_byoc_write for CloudConnection, CloudEnvironment, and Volume; use sncloud_resource_catalog / sncloud_resource_schema before writes. See ../cloud-core/references/remote-mcp.md. Use snctl fallback when MCP tools are unavailable or for CLI-specific examples below.
Prerequisites check
Remote MCP route: start with sncloud_context_whoami, then catalog/schema for BYOC domain. snctl route: run snctl version --client, snctl auth whoami, snctl config get. Defer failures to cloud-core. Additionally:
- The user must have admin access to the target cloud account to create the IAM role / service account / managed identity that backs the cloud connection.
CLI conventions (snctl v1.6.x)
- Organization scope: pass
-O <org>(e.g.-O o-booja). Do NOT use-n/--namespace— it's not a top-level flag for these resource types. - Manifest namespace: when using
snctl apply -f, the manifest'smetadata.namespacemust match-O <org>, otherwise apply rejects it. - Dry-run:
snctl applydoes NOT support--dry-run. To validate a schema, usesnctl create <kind> ... --dry-run -o yaml.snctl deletedoes support--dry-run=server|client.
Mental model
BYOC substrate is a three-layer stack:
- CloudConnection — a handle to the user's cloud account (AWS account ID, GCP project, Azure subscription). For AWS, the StreamNative-managed primary IAM role must already exist in the customer account (deployed via the CloudFormation template offered in the Console). If the role exists from a prior org or a CFN run, the CloudConnection reaches
Readyimmediately on create; otherwise it stays not-Ready until the user runs the template. - CloudEnvironment — a regional/network slice within a CloudConnection: picks the region, zone (for zonal), VPC CIDR, and optional customer-managed DNS. The server auto-generates the resource name as
<cloud>-<region>-<env-type>-<suffix>(e.g.aws-use2-production-8aokv); any positional NAME passed tosnctl create cloudenvironmentis ignored. - Volume — an object-storage target (S3 bucket + IAM role ARN) used by Pulsar for tiered offload. Referenced from a
PulsarCluster's offload config. The direct CLI (snctl create volume) currently exposes AWS-shaped flags only.
A PoolMember is the concrete pool object that a BYOC PulsarInstance references. It's produced by StreamNative's BYOC operator after a CloudEnvironment reaches Ready; it's not created directly by the user.
Primary workflows
For remote MCP writes, compose JSON-string manifests and call sncloud_byoc_write with operation=apply, dry_run=true; only repeat with dry_run=false after validation. Use sncloud_byoc_read for list/get. Never use generic sncloud_resources_*.
W1. AWS BYOC substrate end-to-end
Prefer the direct CLI form — it's a single command and avoids manifest namespace mismatches.
# 1. Create the cloud connection
snctl create cloudconnection my-aws-connection -O my-org \
--type aws --account-id 123456789012
# 2. Wait for Ready (immediate if the StreamNative IAM role already exists in the AWS account;
# otherwise the user runs the CloudFormation template offered in the Console).
snctl describe cloudconnection my-aws-connection -O my-org
# Look for: Type: Ready, Status: True
# Note: AWSPrimaryPolicyUpToDate may report NotReady (CFN policy version drift) without
# blocking overall Ready=True. The user can refresh the CFN stack later if desired.
# 3. Create the cloud environment (server picks the name)
snctl create cloudenvironment -O my-org \
--cloud-connection-name my-aws-connection \
--region us-east-2 \
--network-cidr 10.20.0.0/16
# Capture the generated name from the output, e.g. aws-use2-production-8aokv
snctl describe cloudenvironment <generated-name> -O my-org
# Wait for Ready (DNS, Buckets, etc. provision asynchronously — typically 20–40 min)
# 4. (Optional) Tiered-storage volume — see W6
Manifest-based form (alternative, useful for GitOps):
# Edit assets/manifests/cloudconnection-aws.yaml so metadata.namespace == your org, then:
snctl apply -f ${CLAUDE_PLUGIN_ROOT}/skills/byoc-infrastructure/assets/manifests/cloudconnection-aws.yaml -O my-org
W2. GCP BYOC substrate
Same sequence using --type gcp --project-id <gcp-project> (or cloudconnection-gcp.yaml). Region codes use GCP format (e.g. us-central1, europe-west4).
W3. Azure BYOC substrate
Use snctl create cloudconnection ... --type azure --subscription-id <sub> --tenant-id <tenant> --client-id <client> --support-client-id <support-client>. --support-client-id is required — omitting it returns error: must specify supportClient id. Region for Azure is the resource group name passed via --region.
W4. List / describe / delete
snctl get cloudconnection -O my-org
snctl get cloudenvironment -O my-org -o yaml
snctl describe volume my-tiered-volume -O my-org
# Delete child-first: volume → cloudenvironment → cloudconnection
# Use --wait=false so the CLI returns immediately; cloud-side teardown runs asynchronously.
snctl delete volume my-tiered-volume -O my-org --wait=false
snctl delete cloudenvironment <generated-name> -O my-org --wait=false
snctl delete cloudconnection my-aws-connection -O my-org --wait=false
Destroy protection (production environments)
Production-tier
CloudEnvironmentresources carry the annotationcloud.streamnative.io/destroy-protected=trueand rejectsnctl deletewithForbidden: the CloudEnvironment set destroy protected. Treat this as a deliberate safety gate.Before doing anything: surface the annotation to the user — name it, show its value, and explain that disabling it is a separate destructive step from the delete itself. Then ask for explicit approval to set it to
false. Only after explicit approval, fetch the resource, set the annotation,snctl applyit, then issue the delete:# AFTER explicit user approval to disable destroy protection: snctl get cloudenvironment <name> -O my-org -o yaml > /tmp/ce.yaml # Edit /tmp/ce.yaml: add metadata.annotations["cloud.streamnative.io/destroy-protected"] = "false" # and remove the status block. snctl apply -f /tmp/ce.yaml -O my-org snctl delete cloudenvironment <name> -O my-org --wait=falseThe user's earlier approval to delete the resource is not the same as approval to disable the protection — re-confirm every time.
W5. Find the auto-generated pool member
snctl get poolmember -O my-org -o name
The output is the value passed to snctl create pulsarcluster --pool-member-name <name> or set as spec.poolMemberRef.name in a BYOC cluster manifest.
W6. Create a volume via the direct CLI (alternative to apply)
snctl create volume my-tiered-volume -O my-org \
--region us-east-1 \
--role-arn arn:aws:iam::123456789012:role/streamnative-volume-role \
--bucket my-tiered-storage-bucket \
--path /pulsar-offload
The CLI is AWS-shaped (no --type flag). For non-AWS volumes, edit assets/manifests/volume.yaml and snctl apply it.
Reference index
- references/cloud-connections.md — AWS/GCP/Azure setup, required cloud-side IAM.
- references/cloud-environments.md — spec fields, regional vs zonal, CIDR sizing.
- references/volumes.md — tiered-storage volumes, bucket/role requirements.
- references/networking.md — VPC CIDRs, peering, DNS, egress.
Pitfalls and gotchas
- Remote MCP manifest format:
sncloud_byoc_writemanifestis JSON string, not YAML/object. Omitstatusand read-only metadata copied from read output. - CloudConnection Ready timing: when the StreamNative primary IAM role does not exist in the AWS account yet, the connection stays not-Ready until the user runs the CloudFormation template offered in the Console. Do NOT create a
CloudEnvironmentuntil describe/read reports Ready=True. AWSPrimaryPolicyUpToDatecan beNotReady("Expected version X but have version Unknown") while overallReady=True. This is policy-version drift, not a blocker. Refresh the CFN stack when convenient.- CIDR ranges cannot overlap with existing VPCs in the target cloud account; ask the user for their existing CIDR layout before picking a value.
spec.type, notspec.connectionType: older skill manifests usedconnectionType— the API rejects this with a strict-decoding error.- Manifest schema:
CloudConnection.spec.type,CloudEnvironment.spec.cloudConnectionName/region/networkCidr,Volume.spec.type+spec.aws.{region,roleArn}+spec.{bucket,path}. - Server-generated CloudEnvironment names: any positional NAME passed to
snctl create cloudenvironmentis ignored. Capture the name from the create output and use that for subsequentdescribe/delete. - IAM roles for
Volumeneeds3:GetObject,s3:PutObject,s3:DeleteObjecton the bucket. This skill does NOT generate IAM policies — direct the user to the public StreamNative BYOC docs. - Deletion order matters: Pulsar clusters that reference the volume/environment must be deleted first.
PoolMemberis not directly user-creatable; ifsnctl get poolmemberreturns nothing, theCloudEnvironmentis not yet Ready.- BYOC Pro uses the same three kinds but selects a different
cloudenvironmentspec (customer-managed DNS fields via--dns-id/--dns-name); the deployment type is chosen on thePulsarInstance, not here. snctl deletedefaults to--wait=trueand can block for many minutes while cloud-side infrastructure (VPC peering, IAM, buckets) is torn down. Pass--wait=falsefor a fast, non-blocking delete, then poll withsnctl get ... --ignore-not-foundto confirm.snctl applyhas no--dry-runin v1.6.x. Validate schemas withsnctl create <kind> ... --dry-run -o yaml.- Destroy protection on production CEs: never auto-bypass
cloud.streamnative.io/destroy-protected. Surface the annotation, request a separate explicit approval to set it tofalse, then proceed. See W4.