Tenant Commands
The stategraph tenant command group provides tenant-level operations, including gap analysis for finding unmanaged cloud resources.
Commands
| Command | Description |
|---|---|
stategraph tenant gaps analyze |
Run gap analysis |
stategraph tenant gaps config |
Get gap analysis configuration |
stategraph tenant gaps import |
Generate Terraform import blocks for unmanaged resources |
stategraph tenant gaps analyze
Run gap analysis to find cloud resources not managed by Terraform. stategraph gaps is a top-level alias for the same command.
stategraph tenant gaps analyze --tenant <tenant-id> --provider <provider> [options]
Options
| Option | Required | Description |
|---|---|---|
--tenant |
Yes | Tenant ID (UUID) |
--provider |
Yes | Cloud provider (e.g., aws) |
--source |
No | Data source: cache (default) or no-cache |
Example
stategraph tenant gaps analyze \
--tenant 550e8400-e29b-41d4-a716-446655440000 \
--provider aws
Gap analysis runs asynchronously: the first call for a provider starts a background scan and returns {"status": "running", "started_at": <ts>}. Re-run the command to retrieve the result once the scan finishes (subsequent calls are served from cache). See Gap Analysis for the full flow.
Output (JSON):
{
"summary": {
"total_aws_resources": 1500,
"managed_by_stategraph": 1200,
"unmanaged": 300,
"phantom_filtered": 8
},
"unmanaged_resources": [
{
"arn": "arn:aws:s3:::orphaned-bucket",
"service": "s3",
"resource_type": "s3:bucket",
"region": "us-east-1",
"owning_account_id": "123456789012"
}
],
"fetched_at": 1705312800
}
Force Fresh Scan
stategraph tenant gaps analyze \
--tenant 550e8400-e29b-41d4-a716-446655440000 \
--provider aws \
--source no-cache
stategraph tenant gaps config
Get gap analysis configuration status.
stategraph tenant gaps config --tenant <tenant-id> --provider <provider>
Options
| Option | Required | Description |
|---|---|---|
--tenant |
Yes | Tenant ID (UUID) |
--provider |
Yes | Cloud provider (e.g., aws) |
Example
stategraph tenant gaps config \
--tenant 550e8400-e29b-41d4-a716-446655440000 \
--provider aws
Output (JSON):
{
"status": "ready",
"ready_for_gap_analysis": true,
"ready_for_terraform_import": true,
"has_aggregator": true,
"aggregator_region": "us-east-1",
"indexed_regions": ["us-east-1", "us-west-2", "eu-west-1"],
"index_count": 3,
"warnings": []
}
stategraph tenant gaps import
Generate Terraform import blocks and resource configuration for unmanaged resources. Pass a JSON file of resources (the unmanaged_resources array from gaps analyze) and Stategraph returns ready-to-use import blocks plus generated HCL.
stategraph tenant gaps import --tenant <tenant-id> [--provider <provider>] <resources-file>
Options
| Option | Required | Description |
|---|---|---|
--tenant |
Yes | Tenant ID (UUID) |
--provider |
No | Cloud provider (default: aws) |
Arguments
| Argument | Required | Description |
|---|---|---|
<resources-file> |
Yes | JSON file containing an array of resources to import (the unmanaged_resources from gaps analyze) |
Example
First, save unmanaged resources to a file:
stategraph tenant gaps analyze --tenant $TENANT_ID --provider aws | \
jq '.unmanaged_resources' > unmanaged.json
Then generate import blocks and configuration:
stategraph tenant gaps import --tenant $TENANT_ID unmanaged.json
Output (JSON):
{
"import_blocks": "import {\n provider = aws.us_east_1\n to = aws_s3_bucket.imported_orphaned_bucket\n id = \"orphaned-bucket\"\n}",
"provider_hcl": "terraform {\n required_providers {\n aws = {\n source = \"hashicorp/aws\"\n version = \"~> 5.0\"\n }\n }\n}\n",
"generated_hcl": "resource \"aws_s3_bucket\" \"imported_orphaned_bucket\" {\n bucket = \"orphaned-bucket\"\n # ... generated attributes\n}\n",
"supported_count": 1,
"unsupported_count": 0,
"unsupported_resources": []
}
Scripting Examples
Weekly Gap Analysis Report
#!/bin/bash
TENANT_ID="550e8400-e29b-41d4-a716-446655440000"
echo "Gap Analysis Report - $(date)"
echo "================================"
echo ""
result=$(stategraph tenant gaps analyze --tenant $TENANT_ID --provider aws --source no-cache)
total=$(echo $result | jq '.summary.total_aws_resources')
managed=$(echo $result | jq '.summary.managed_by_stategraph')
unmanaged=$(echo $result | jq '.summary.unmanaged')
echo "Total AWS resources: $total"
echo "Managed by Terraform: $managed"
echo "Unmanaged: $unmanaged"
echo ""
echo "Coverage: $(echo "scale=2; $managed * 100 / $total" | bc)%"
echo ""
echo "Top unmanaged resource types:"
echo $result | jq -r '.unmanaged_resources | group_by(.service) | map({service: .[0].service, count: length}) | sort_by(-.count) | .[:5][] | " \(.service): \(.count)"'
Find and Import S3 Buckets
#!/bin/bash
TENANT_ID="550e8400-e29b-41d4-a716-446655440000"
# Get unmanaged S3 buckets
stategraph tenant gaps analyze --tenant $TENANT_ID --provider aws | \
jq '[.unmanaged_resources[] | select(.service == "s3")]' > s3_unmanaged.json
# Generate import blocks
stategraph tenant gaps import --tenant $TENANT_ID s3_unmanaged.json | \
jq -r '.import_blocks' > import.tf
echo "Generated import.tf with $(jq length s3_unmanaged.json) S3 bucket imports"
Monitor Gap Trend
#!/bin/bash
TENANT_ID="550e8400-e29b-41d4-a716-446655440000"
LOG_FILE="gap_history.csv"
# Add header if file doesn't exist
if [ ! -f $LOG_FILE ]; then
echo "date,total,managed,unmanaged,coverage" > $LOG_FILE
fi
result=$(stategraph tenant gaps analyze --tenant $TENANT_ID --provider aws)
total=$(echo $result | jq '.summary.total_aws_resources')
managed=$(echo $result | jq '.summary.managed_by_stategraph')
unmanaged=$(echo $result | jq '.summary.unmanaged')
coverage=$(echo "scale=4; $managed / $total" | bc)
echo "$(date -I),$total,$managed,$unmanaged,$coverage" >> $LOG_FILE
Next Steps
- Gap Analysis - Full gap analysis documentation
- States - State management commands
- Troubleshooting - Common issues