Adding a Static Dataset
September 7, 2026 ยท View on GitHub
Use this guide when a new static IaC rule needs normalized Terraform or CloudFormation inputs from the SDK.
See docs/architecture/sdk.md for the full static scan engine flow. Before creating a new dataset, check whether the service already has one you can reuse or extend (see step 2 in adding-a-rule.md).
1. Pick a Dataset Key
Define a dataset key in @cloudburn/rules metadata that represents one normalized static resource collection.
Use dataset-oriented keys, not parser-specific buckets:
aws-rds-instancesaws-s3-bucket-analysesaws-ec2-load-balancers
2. Add the Rule-Facing Type
Add or reuse a normalized static model in packages/rules/src/shared/metadata.ts.
export type AwsStaticEc2VpcEndpoint = {
resourceId: string;
serviceName: string | null;
vpcEndpointType: string | null;
location?: SourceLocation;
};
Register the key in StaticDatasetKey and its shape in StaticDatasetMap in
metadata.ts. For a concept shared with discovery, use SharedDatasetKey
(which StaticDatasetKey includes), and register live support separately in DiscoveryDatasetKey and DiscoveryDatasetMap.
Export new normalized types through the rules package entry point for SDK consumers.
The map entry looks like:
export type StaticDatasetMap = {
'aws-ec2-vpc-endpoints': AwsStaticEc2VpcEndpoint[];
};
If the service also has a live discovery dataset for the same concept, prefer a shared base type for the common fields and keep the mode-specific identity fields separate.
3. Add a Dataset Loader
Update packages/sdk/src/providers/aws/static-registry.ts with a dataset definition that declares:
datasetKey- required
sourceKinds - source-native
resourceTypes loadfunction
Dataset loaders should:
- receive only IaC resources matched for the dataset
- own Terraform and CloudFormation type strings
- normalize computed or unresolved values into explicit
nullor defaulted states - precompute
resourceIdand preferred sourcelocation - preserve existing classification semantics when refactoring loader logic into shared helpers
'aws-ec2-vpc-endpoints': {
datasetKey: 'aws-ec2-vpc-endpoints',
sourceKinds: ['terraform', 'cloudformation'],
resourceTypes: ['aws_vpc_endpoint', 'AWS::EC2::VPCEndpoint'],
load: loadStaticEc2VpcEndpoints,
}
Do not add service-specific branching to runStaticScan or rule files.
4. Write or Update Rules
In @cloudburn/rules, consume the dataset key:
staticDependencies: ['aws-ec2-vpc-endpoints'],
evaluateStatic: ({ resources }) => {
const findings = resources
.get('aws-ec2-vpc-endpoints')
.filter((endpoint) => endpoint.serviceName?.endsWith('.s3') && endpoint.vpcEndpointType === 'interface')
.map((endpoint) => ({
resourceId: endpoint.resourceId,
location: endpoint.location,
}));
return createFinding(rule, 'iac', findings);
};
5. Verify
pnpm verify