DRFT Examples
This document contains practical examples of using DRFT to manage various types of resources, from cloud infrastructure to project configuration and application setup.
Basic Example: Single VM
import 'package:drft/drft.dart';
void main() async {
final stack = DrftStack(
name: 'simple-vm',
providers: [
AwsProvider(region: 'us-east-1'),
],
resources: [
VirtualMachine(
name: 'my-server',
image: 'ubuntu-22.04',
size: 'medium',
),
],
);
// Plan changes
final plan = await stack.plan();
print(plan);
// Apply changes
await stack.apply(plan);
}
Web Application Stack
import 'package:drft/drft.dart';
void main() async {
final stack = DrftStack(
name: 'web-app',
providers: [
AwsProvider(region: 'us-east-1'),
],
resources: [
// Network Infrastructure
Vpc(
name: 'main-vpc',
cidr: '10.0.0.0/16',
tags: {'Name': 'main-vpc', 'Environment': 'production'},
),
Subnet(
name: 'public-subnet-1a',
vpcId: vpc.id,
cidr: '10.0.1.0/24',
availabilityZone: 'us-east-1a',
),
Subnet(
name: 'public-subnet-1b',
vpcId: vpc.id,
cidr: '10.0.2.0/24',
availabilityZone: 'us-east-1b',
),
Subnet(
name: 'private-subnet-1a',
vpcId: vpc.id,
cidr: '10.0.10.0/24',
availabilityZone: 'us-east-1a',
),
Subnet(
name: 'private-subnet-1b',
vpcId: vpc.id,
cidr: '10.0.11.0/24',
availabilityZone: 'us-east-1b',
),
// Internet Gateway
InternetGateway(
name: 'main-igw',
vpcId: vpc.id,
),
// Route Tables
RouteTable(
name: 'public-rt',
vpcId: vpc.id,
routes: [
Route(destination: '0.0.0.0/0', gatewayId: igw.id),
],
subnets: [publicSubnet1a.id, publicSubnet1b.id],
),
// Security Groups
SecurityGroup(
name: 'web-sg',
vpcId: vpc.id,
description: 'Security group for web servers',
ingressRules: [
IngressRule(port: 80, protocol: 'tcp', source: '0.0.0.0/0'),
IngressRule(port: 443, protocol: 'tcp', source: '0.0.0.0/0'),
IngressRule(port: 22, protocol: 'tcp', source: '10.0.0.0/16'),
],
egressRules: [
EgressRule(port: 0, protocol: '-1', destination: '0.0.0.0/0'),
],
),
SecurityGroup(
name: 'db-sg',
vpcId: vpc.id,
description: 'Security group for database',
ingressRules: [
IngressRule(port: 5432, protocol: 'tcp', source: '10.0.0.0/16'),
],
),
// Application Load Balancer
LoadBalancer(
name: 'web-alb',
type: 'application',
subnets: [publicSubnet1a.id, publicSubnet1b.id],
securityGroups: [webSg.id],
listeners: [
Listener(
port: 80,
protocol: 'http',
defaultAction: RedirectAction(port: 443, protocol: 'https'),
),
Listener(
port: 443,
protocol: 'https',
certificate: 'arn:aws:acm:us-east-1:123456789012:certificate/...',
defaultAction: ForwardAction(targetGroup: webTargetGroup.id),
),
],
tags: {'Name': 'web-alb'},
),
TargetGroup(
name: 'web-tg',
protocol: 'http',
port: 80,
vpcId: vpc.id,
healthCheck: HealthCheck(
path: '/health',
interval: 30,
timeout: 5,
healthyThreshold: 2,
unhealthyThreshold: 3,
),
),
// Auto Scaling Group
AutoScalingGroup(
name: 'web-asg',
minSize: 2,
maxSize: 10,
desiredCapacity: 2,
subnets: [privateSubnet1a.id, privateSubnet1b.id],
securityGroups: [webSg.id],
launchTemplate: LaunchTemplate(
imageId: 'ami-0c55b159cbfafe1f0',
instanceType: 't3.medium',
userData: '''
#!/bin/bash
apt-get update
apt-get install -y nginx
systemctl start nginx
systemctl enable nginx
''',
),
targetGroups: [webTargetGroup.id],
tags: {'Name': 'web-server'},
),
// RDS Database
DatabaseSubnetGroup(
name: 'db-subnet-group',
subnets: [privateSubnet1a.id, privateSubnet1b.id],
description: 'Subnet group for RDS database',
),
Database(
name: 'app-db',
engine: 'postgresql',
version: '14',
instanceClass: 'db.t3.medium',
allocatedStorage: 100,
storageType: 'gp3',
backupRetentionPeriod: 7,
multiAz: true,
publiclyAccessible: false,
subnetGroup: dbSubnetGroup.id,
securityGroups: [dbSg.id],
masterUsername: 'admin',
masterPassword: Secret.fromEnvironment('DB_PASSWORD'),
tags: {'Name': 'app-db'},
),
],
);
final plan = await stack.plan();
await stack.apply(plan);
}
Kubernetes Deployment
import 'package:drft/drft.dart';
void main() async {
final stack = DrftStack(
name: 'k8s-app',
providers: [
KubernetesProvider(
kubeconfig: '~/.kube/config',
namespace: 'production',
),
],
resources: [
// Namespace
KubernetesNamespace(name: 'production'),
// ConfigMap
KubernetesConfigMap(
name: 'app-config',
namespace: 'production',
data: {
'database_url': 'postgresql://db:5432/app',
'redis_url': 'redis://redis:6379',
'log_level': 'info',
},
),
// Secret
KubernetesSecret(
name: 'app-secrets',
namespace: 'production',
type: 'Opaque',
data: {
'api_key': Secret.fromEnvironment('API_KEY'),
'db_password': Secret.fromEnvironment('DB_PASSWORD'),
},
),
// Deployment
KubernetesDeployment(
name: 'web-app',
namespace: 'production',
replicas: 3,
selector: {'app': 'web-app'},
template: PodTemplate(
labels: {'app': 'web-app'},
containers: [
Container(
name: 'web',
image: 'myregistry/web-app:latest',
ports: [ContainerPort(containerPort: 8080)],
env: [
EnvVar(name: 'DATABASE_URL', valueFrom: ConfigMapKeyRef('app-config', 'database_url')),
EnvVar(name: 'API_KEY', valueFrom: SecretKeyRef('app-secrets', 'api_key')),
],
resources: ResourceRequirements(
requests: {'cpu': '100m', 'memory': '128Mi'},
limits: {'cpu': '500m', 'memory': '512Mi'},
),
),
],
),
),
// Service
KubernetesService(
name: 'web-service',
namespace: 'production',
type: 'LoadBalancer',
selector: {'app': 'web-app'},
ports: [
ServicePort(port: 80, targetPort: 8080, protocol: 'TCP'),
],
),
// Ingress
KubernetesIngress(
name: 'web-ingress',
namespace: 'production',
rules: [
IngressRule(
host: 'example.com',
http: IngressHttp(
paths: [
IngressPath(
path: '/',
pathType: 'Prefix',
backend: IngressBackend(
serviceName: 'web-service',
servicePort: 80,
),
),
],
),
),
],
tls: [
IngressTLS(
hosts: ['example.com'],
secretName: 'tls-secret',
),
],
),
],
);
final plan = await stack.plan();
await stack.apply(plan);
}
Multi-Cloud Example
import 'package:drft/drft.dart';
void main() async {
final stack = DrftStack(
name: 'multi-cloud',
providers: [
AwsProvider(region: 'us-east-1'),
GcpProvider(project: 'my-project', region: 'us-central1'),
],
resources: [
// AWS Resources
AwsS3Bucket(
name: 'backup-bucket',
versioning: true,
encryption: 'AES256',
tags: {'Provider': 'AWS'},
),
// GCP Resources
GcpStorageBucket(
name: 'archive-bucket',
location: 'US',
storageClass: 'STANDARD',
versioning: true,
labels: {'provider': 'GCP'},
),
// Cross-cloud resource (DNS)
DnsRecord(
name: 'api.example.com',
type: 'A',
values: [
AwsLoadBalancer(name: 'aws-lb').dnsName,
GcpLoadBalancer(name: 'gcp-lb').dnsName,
],
ttl: 300,
),
],
);
final plan = await stack.plan();
await stack.apply(plan);
}
Using Variables and Functions
import 'package:drft/drft.dart';
// Configuration
const environment = 'production';
const region = 'us-east-1';
const instanceCount = 3;
// Helper function
List<Subnet> createSubnets(Vpc vpc, List<String> azs, String cidrBase) {
return azs.asMap().entries.map((entry) {
final index = entry.key;
final az = entry.value;
final subnetCidr = cidrBase.replaceRange(
cidrBase.lastIndexOf('.'),
cidrBase.length,
'${index + 1}.0/24',
);
return Subnet(
name: 'subnet-$az',
vpcId: vpc.id,
cidr: subnetCidr,
)..availabilityZone = az;
}).toList();
}
void main() async {
final stack = DrftStack(
name: 'scalable-app',
providers: [
AwsProvider(region: region),
],
resources: [
// Network
Vpc(
name: 'main-vpc',
cidr: '10.0.0.0/16',
tags: {'Environment': environment},
),
// Create subnets dynamically
...createSubnets(
vpc,
['us-east-1a', 'us-east-1b', 'us-east-1c'],
'10.0.0.0/16',
),
// Create multiple VMs
...List.generate(instanceCount, (index) {
return VirtualMachine(
name: 'web-${index + 1}',
image: 'ubuntu-22.04',
size: 'medium',
subnetId: subnets[index % subnets.length].id,
tags: {
'Environment': environment,
'Index': '${index + 1}',
},
);
}),
],
);
final plan = await stack.plan();
await stack.apply(plan);
}
Conditional Resources
import 'package:drft/drft.dart';
void main() async {
const enableMonitoring = true;
const enableBackup = true;
final stack = DrftStack(
name: 'conditional-resources',
providers: [
AwsProvider(region: 'us-east-1'),
],
resources: [
VirtualMachine(name: 'app-server', image: 'ubuntu-22.04', size: 'medium'),
// Conditional monitoring
if (enableMonitoring) ...[
CloudWatchAlarm(
name: 'cpu-alarm',
metricName: 'CPUUtilization',
threshold: 80,
comparisonOperator: 'GreaterThanThreshold',
evaluationPeriods: 2,
),
SnsTopic(
name: 'alerts-topic',
subscriptions: [
SnsSubscription(
protocol: 'email',
endpoint: 'admin@example.com',
),
],
),
],
// Conditional backup
if (enableBackup) ...[
BackupPlan(
name: 'daily-backup',
rules: [
BackupRule(
name: 'daily',
schedule: 'cron(0 2 * * ? *)', // 2 AM daily
targetBackupVault: backupVault.id,
lifecycle: BackupLifecycle(
deleteAfter: 30, // days
moveToColdStorageAfter: 7, // days
),
),
],
),
],
],
);
final plan = await stack.plan();
await stack.apply(plan);
}
Using Modules/Reusable Components
import 'package:drft/drft.dart';
// Reusable network module
DrftStack createNetworkStack({
required String name,
required String cidr,
required List<String> availabilityZones,
}) {
return DrftStack(
name: name,
providers: [AwsProvider(region: 'us-east-1')],
resources: [
Vpc(name: '$name-vpc', cidr: cidr),
...availabilityZones.map((az) {
final index = availabilityZones.indexOf(az);
return Subnet(
name: '$name-subnet-$az',
vpcId: vpc.id,
cidr: _calculateSubnetCidr(cidr, index),
availabilityZone: az,
);
}),
],
);
}
String _calculateSubnetCidr(String vpcCidr, int index) {
// Calculate subnet CIDR based on VPC CIDR and index
// Implementation details...
return '10.0.${index + 1}.0/24';
}
void main() async {
// Use the module
final networkStack = createNetworkStack(
name: 'production',
cidr: '10.0.0.0/16',
availabilityZones: ['us-east-1a', 'us-east-1b'],
);
final plan = await networkStack.plan();
await networkStack.apply(plan);
}
Application Configuration Example
DRFT isn't limited to cloud infrastructure. Here's an example managing application configuration resources:
import 'package:drft/drft.dart';
import 'package:drft_firebase/drft_firebase.dart';
void main() async {
final stack = DrftStack(
name: 'app-configuration',
providers: [
FirebaseProvider(),
AppStoreProvider(),
],
resources: [
// Firebase Project (data source - must exist externally)
FirebaseProject(
id: 'project',
projectId: 'my-firebase-project',
displayName: 'My Firebase Project',
),
// Firebase Apps
FirebaseApp(
id: 'ios-app',
projectId: 'my-firebase-project',
platform: FirebaseAppPlatform.ios,
displayName: 'My iOS App',
bundleId: 'com.example.app',
),
FirebaseApp(
id: 'android-app',
projectId: 'my-firebase-project',
platform: FirebaseAppPlatform.android,
displayName: 'My Android App',
packageName: 'com.example.app',
),
// App Store Connect App
AppStoreApp(
id: 'app-store-app',
name: 'My App',
bundleId: 'com.example.app',
primaryLocale: 'en-US',
sku: 'APP-SKU-001',
),
],
);
final plan = await stack.plan();
await stack.apply(plan);
}
Project Setup Example
You can also use DRFT to manage project setup and development environment configuration:
import 'package:drft/drft.dart';
void main() async {
final stack = DrftStack(
name: 'dev-environment',
providers: [
LocalFileProvider(), // Hypothetical provider for local file management
DockerProvider(), // Hypothetical provider for Docker containers
],
resources: [
// Development configuration files
ConfigFile(
path: '.env.example',
content: '''
DATABASE_URL=postgresql://localhost:5432/dev
API_KEY=your-api-key-here
DEBUG=true
''',
),
// Docker development environment
DockerContainer(
name: 'postgres-dev',
image: 'postgres:14',
ports: {'5432': '5432'},
environment: {
'POSTGRES_DB': 'dev',
'POSTGRES_USER': 'dev',
'POSTGRES_PASSWORD': 'dev',
},
),
DockerContainer(
name: 'redis-dev',
image: 'redis:7',
ports: {'6379': '6379'},
),
],
);
final plan = await stack.plan();
await stack.apply(plan);
}