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 import blocks for unmanaged resources

stategraph tenant gaps analyze

Run gap analysis to find cloud resources not managed by Terraform.

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

Output (JSON):

{
  "summary": {
    "total_aws_resources": 1500,
    "managed_by_stategraph": 1200,
    "unmanaged": 300
  },
  "unmanaged_resources": [
    {
      "arn": "arn:aws:s3:::orphaned-bucket",
      "service": "S3",
      "resource_type": "AWS::S3::Bucket",
      "region": "us-east-1",
      "owning_account_id": "123456789012"
    }
  ],
  "fetched_at": 1705312800,
  "from_cache": true
}

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,
  "has_aggregator": true,
  "aggregator_region": "us-east-1",
  "indexed_regions": ["us-east-1", "us-west-2", "eu-west-1"],
  "index_count": 1500,
  "warnings": []
}

stategraph tenant gaps import

Generate Terraform import blocks for unmanaged resources.

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 with resources to import

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:

stategraph tenant gaps import --tenant $TENANT_ID unmanaged.json

Output (JSON):

{
  "import_blocks": "import {\n  to = aws_s3_bucket.orphaned_bucket\n  id = \"orphaned-bucket\"\n}\n",
  "provider_hcl": "provider \"aws\" {\n  region = \"us-east-1\"\n}\n",
  "generated_hcl": "resource \"aws_s3_bucket\" \"orphaned_bucket\" {\n  bucket = \"orphaned-bucket\"\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