Link components
After you connect a cloud account, link resources to product components by setting cloud and a resource identifier on the component env. Ductape does the rest when you save.
The pattern
Every linked env follows the same shape:
- TypeScript
- Java
- Go
- .NET
{
slug: 'prd',
cloud: 'prod_aws', // connection tag — not a connection ID
// + resource-specific fields (instance, bucketName, queueName, …)
}
Map.of(
"slug", "prd",
"cloud", "prod_aws", // connection tag — not a connection ID
// + resource-specific fields (instance, bucketName, queueName, …)
)
{
"slug": "prd",
"cloud": "prod_aws", // connection tag — not a connection ID
// + resource-specific fields (instance, bucketName, queueName, …)
}
{
["slug"] = "prd",
["cloud"] = "prod_aws", // connection tag — not a connection ID
// + resource-specific fields (instance, bucketName, queueName, …)
}
On save, Ductape:
- Lists resources in the linked account (if needed)
- Imports the resource if it already exists, or provisions a new one
- Stores credentials as workspace secrets (
$Secret{...}) - Sets
authMode: 'cloud_connection'on the env
At runtime, connect(), upload(), produce(), etc. resolve secrets and refresh cloud credentials automatically.
Examples by component
Database (PostgreSQL)
- TypeScript
- Java
- Go
- .NET
await ductape.databases.create({
product: 'my-product',
tag: 'app-db',
name: 'App Database',
type: 'postgresql',
envs: [{
slug: 'prd',
cloud: 'prod_azure',
instance: 'my-pg-server',
region: 'eastus',
}],
});
ductape.databases.create(Map.of(
"product", "my-product",
"tag", "app-db",
"name", "App Database",
"type", "postgresql",
envs: [Map.of(
"slug", "prd",
"cloud", "prod_azure",
"instance", "my-pg-server",
"region", "eastus",
)],
));
client.databases.create({
"product": "my-product",
"tag": "app-db",
"name": "App Database",
"type": "postgresql",
envs: [{
"slug": "prd",
"cloud": "prod_azure",
"instance": "my-pg-server",
"region": "eastus",
}],
});
await ductape.databases.create({
["product"] = "my-product",
["tag"] = "app-db",
["name"] = "App Database",
["type"] = "postgresql",
envs: [{
["slug"] = "prd",
["cloud"] = "prod_azure",
["instance"] = "my-pg-server",
["region"] = "eastus",
}],
});
| Provider | Connection tag | Key fields |
|---|---|---|
| AWS RDS | prod_aws | instance, region, securityGroups (if customer-managed) |
| GCP Cloud SQL | prod_gcp | instance, region |
| Azure Flexible Server | prod_azure | instance, region |
| MongoDB Atlas | prod_atlas | instance (cluster name) |
AWS RDS: New instances are created on save (can take several minutes). Use the same instance across envs to share one RDS; use different names per env for separate instances. Importing existing RDS requires the master password — prefer provision for new databases. See AWS networking.
Storage
- TypeScript
- Java
- Go
- .NET
await ductape.storage.create({
product: 'my-product',
tag: 'app-storage',
name: 'App Storage',
envs: [{
slug: 'prd',
type: 'aws',
config: {
cloud: 'prod_aws',
bucketName: 'my-app-uploads',
region: 'us-east-1',
},
}],
});
ductape.storage.create(Map.of(
"product", "my-product",
"tag", "app-storage",
"name", "App Storage",
envs: [Map.of(
"slug", "prd",
"type", "aws",
config: Map.of(
"cloud", "prod_aws",
"bucketName", "my-app-uploads",
"region", "us-east-1",
),
)],
));
client.storage.create({
"product": "my-product",
"tag": "app-storage",
"name": "App Storage",
envs: [{
"slug": "prd",
"type": "aws",
config: {
"cloud": "prod_aws",
"bucketName": "my-app-uploads",
"region": "us-east-1",
},
}],
});
await ductape.storage.create({
["product"] = "my-product",
["tag"] = "app-storage",
["name"] = "App Storage",
envs: [{
["slug"] = "prd",
["type"] = "aws",
config: {
["cloud"] = "prod_aws",
["bucketName"] = "my-app-uploads",
["region"] = "us-east-1",
},
}],
});
| Provider | Config fields |
|---|---|
| AWS | cloud, bucketName, region |
| GCP | cloud, bucketName, location |
| Azure | cloud, containerName, region |
Message broker
- TypeScript
- Java
- Go
- .NET
await ductape.messaging.create({
product: 'my-product',
tag: 'order-events',
name: 'Order Events',
envs: [{
slug: 'prd',
type: 'aws_sqs',
config: {
cloud: 'prod_aws',
queueName: 'order-events',
region: 'us-east-1',
},
}],
});
ductape.messaging.create(Map.of(
"product", "my-product",
"tag", "order-events",
"name", "Order Events",
envs: [Map.of(
"slug", "prd",
"type", "aws_sqs",
config: Map.of(
"cloud", "prod_aws",
"queueName", "order-events",
"region", "us-east-1",
),
)],
));
client.messaging.create({
"product": "my-product",
"tag": "order-events",
"name": "Order Events",
envs: [{
"slug": "prd",
"type": "aws_sqs",
config: {
"cloud": "prod_aws",
"queueName": "order-events",
"region": "us-east-1",
},
}],
});
await ductape.messaging.create({
["product"] = "my-product",
["tag"] = "order-events",
["name"] = "Order Events",
envs: [{
["slug"] = "prd",
["type"] = "aws_sqs",
config: {
["cloud"] = "prod_aws",
["queueName"] = "order-events",
["region"] = "us-east-1",
},
}],
});
| Provider | Config fields |
|---|---|
| AWS SQS | cloud, queueName, region |
| GCP Pub/Sub | cloud, topicName, region |
| Azure Service Bus | cloud, queueName, region, namespaceName |
Graph
- TypeScript
- Java
- Go
- .NET
await ductape.graph.create({
product: 'my-product',
tag: 'social-graph',
name: 'Social Graph',
type: 'neptune',
envs: [{
slug: 'prd',
cloud: 'prod_aws',
instance: 'my-neptune-cluster',
region: 'us-east-1',
securityGroups: ['prod-rds'],
}],
});
ductape.graph.create(Map.of(
"product", "my-product",
"tag", "social-graph",
"name", "Social Graph",
"type", "neptune",
envs: [Map.of(
"slug", "prd",
"cloud", "prod_aws",
"instance", "my-neptune-cluster",
"region", "us-east-1",
securityGroups: ['prod-rds'],
)],
));
client.graph.create({
"product": "my-product",
"tag": "social-graph",
"name": "Social Graph",
"type": "neptune",
envs: [{
"slug": "prd",
"cloud": "prod_aws",
"instance": "my-neptune-cluster",
"region": "us-east-1",
securityGroups: ['prod-rds'],
}],
});
await ductape.graph.create({
["product"] = "my-product",
["tag"] = "social-graph",
["name"] = "Social Graph",
["type"] = "neptune",
envs: [{
["slug"] = "prd",
["cloud"] = "prod_aws",
["instance"] = "my-neptune-cluster",
["region"] = "us-east-1",
securityGroups: ['prod-rds'],
}],
});
Ductape resolves and stores connection_url as an encrypted secret. AWS Neptune requires VPC networking.
Vector
- TypeScript
- Java
- Go
- .NET
await ductape.vector.create({
product: 'my-product',
tag: 'product-vectors',
name: 'Embeddings',
type: 'opensearch',
dimensions: 1536,
envs: [{
slug: 'prd',
cloud: 'prod_aws',
instance: 'my-opensearch-domain',
region: 'us-east-1',
}],
});
ductape.vector.create(Map.of(
"product", "my-product",
"tag", "product-vectors",
"name", "Embeddings",
"type", "opensearch",
"dimensions", 1536,
envs: [Map.of(
"slug", "prd",
"cloud", "prod_aws",
"instance", "my-opensearch-domain",
"region", "us-east-1",
)],
));
client.vector.create({
"product": "my-product",
"tag": "product-vectors",
"name": "Embeddings",
"type": "opensearch",
"dimensions": 1536,
envs: [{
"slug": "prd",
"cloud": "prod_aws",
"instance": "my-opensearch-domain",
"region": "us-east-1",
}],
});
await ductape.vector.create({
["product"] = "my-product",
["tag"] = "product-vectors",
["name"] = "Embeddings",
["type"] = "opensearch",
["dimensions"] = 1536,
envs: [{
["slug"] = "prd",
["cloud"] = "prod_aws",
["instance"] = "my-opensearch-domain",
["region"] = "us-east-1",
}],
});
Ductape stores endpoint and apiKey from the link draft as encrypted secrets.
Import vs provision
| Situation | What happens |
|---|---|
| Resource name exists in the account | Import — link existing resource |
| Name omitted or resource not found | Provision — create with default template |
Component create / update via SDK | Materializer runs list → import or provision automatically |
You rarely call import/provision directly unless building custom tooling.
Low-level APIs
Use ductape.cloud.resources when you need explicit control:
- TypeScript
- Java
- Go
- .NET
// List what's in the account
const { resources } = await ductape.cloud.resources.list({
cloud: 'prod_aws',
service: 'postgresql',
region: 'us-east-1',
});
// Import an existing server
await ductape.cloud.resources.import({
cloud: 'prod_azure',
service: 'postgresql',
type: 'databases',
product: 'my-product',
component: 'app-db',
env: 'prd',
resource: 'my-pg-server',
});
// Provision a new topic
await ductape.cloud.resources.provision({
cloud: 'gcp_prod',
service: 'pubsub',
type: 'messageBrokers',
product: 'my-product',
component: 'order-events',
env: 'prd',
topicName: 'order-events',
region: 'us-central1',
});
// List what's in the account
Map<String, Object> Map.of( resources ) = ductape.cloud.resources.list(Map.of(
"cloud", "prod_aws",
"service", "postgresql",
"region", "us-east-1",
));
// Import an existing server
ductape.cloud.resources.import(Map.of(
"cloud", "prod_azure",
"service", "postgresql",
"type", "databases",
"product", "my-product",
"component", "app-db",
"env", "prd",
"resource", "my-pg-server",
));
// Provision a new topic
ductape.cloud.resources.provision(Map.of(
"cloud", "gcp_prod",
"service", "pubsub",
"type", "messageBrokers",
"product", "my-product",
"component", "order-events",
"env", "prd",
"topicName", "order-events",
"region", "us-central1",
));
// List what's in the account
const { resources } = client.cloud.resources.list({
"cloud": "prod_aws",
"service": "postgresql",
"region": "us-east-1",
});
// Import an existing server
client.cloud.resources.import({
"cloud": "prod_azure",
"service": "postgresql",
"type": "databases",
"product": "my-product",
"component": "app-db",
"env": "prd",
"resource": "my-pg-server",
});
// Provision a new topic
client.cloud.resources.provision({
"cloud": "gcp_prod",
"service": "pubsub",
"type": "messageBrokers",
"product": "my-product",
"component": "order-events",
"env": "prd",
"topicName": "order-events",
"region": "us-central1",
});
// List what's in the account
var { resources } = await ductape.cloud.resources.list({
["cloud"] = "prod_aws",
["service"] = "postgresql",
["region"] = "us-east-1",
});
// Import an existing server
await ductape.cloud.resources.import({
["cloud"] = "prod_azure",
["service"] = "postgresql",
["type"] = "databases",
["product"] = "my-product",
["component"] = "app-db",
["env"] = "prd",
["resource"] = "my-pg-server",
});
// Provision a new topic
await ductape.cloud.resources.provision({
["cloud"] = "gcp_prod",
["service"] = "pubsub",
["type"] = "messageBrokers",
["product"] = "my-product",
["component"] = "order-events",
["env"] = "prd",
["topicName"] = "order-events",
["region"] = "us-central1",
});
All cloud APIs take cloud (the connection tag).
Service reference
Component type | AWS service | GCP service | Azure service | Atlas / Aura |
|---|---|---|---|---|
storage | s3 | gcs | blob | — |
messageBrokers | sqs | pubsub | servicebus | — |
databases | rds | cloudsql | postgresql | atlas-cluster |
graphs | neptune | spanner-graph | cosmos-gremlin | aura-instance |
vectors | opensearch | vertex-vector-search | azure-search | — |
Workbench
When editing a component env:
- Pick a cloud connection (shown by tag)
- Select or type a resource name
- Save — import/provision runs in the background
The link panel lists all services for the selected provider.
See also
- Cloud overview — the full three-step flow
- Cloud connections — create, complete, validate
- AWS networking — RDS and Neptune security groups
- Provider guides — per-provider IAM and credentials
- CLI cloud commands