Resource Change History

View the complete change history of any resource. Every create, update, and destroy is recorded with timestamps, diffs, and key attributes.

Usage

oxid history <address> [flags]

The history command shows a timestamped log of every change made to a resource. Oxid records history automatically during every apply - no extra configuration needed.

Example Output

$ oxid history aws_instance.api

History for aws_instance.api (3 entries):

[1] 2025-01-15 14:23:01 (2 hours ago) - updated
    ID: i-0abcdef1234567890
    instance_type: t3.medium
    ami: ami-0fedcba9876543210
    tags:
      Name: api-server
      Environment: production
      Version: 2.4.1

    Changes from previous:
      ~ tags.Version: "2.3.0" => "2.4.1"
      ~ ami: "ami-0abcdef1234567890" => "ami-0fedcba9876543210"

[2] 2025-01-10 16:45:22 (5 days ago) - updated
    ID: i-0abcdef1234567890
    instance_type: t3.medium
    ami: ami-0abcdef1234567890
    tags:
      Name: api-server
      Environment: production
      Version: 2.3.0

    Changes from previous:
      ~ tags.Version: "2.2.0" => "2.3.0"

[3] 2024-12-01 09:30:15 (45 days ago) - created
    ID: i-0abcdef1234567890
    instance_type: t3.medium
    ami: ami-0abcdef1234567890
    tags:
      Name: api-server
      Environment: production
      Version: 2.2.0

What Gets Recorded

Each history entry includes:

  • Timestamp - When the change occurred, with relative time display
  • Action - created, updated, destroyed, or replaced
  • Resource ID - The provider-assigned identifier
  • Key attributes - Important attributes like cidr_block, instance_type, tags, etc.
  • Color-coded diffs - Attribute changes between consecutive entries, showing old and new values

Flags

FlagDescriptionDefault
-n <count>Limit the number of history entries displayed.all entries
--jsonOutput history in JSON format for scripting.false

JSON Output

$ oxid history aws_instance.api --json

[
  {
    "address": "aws_instance.api",
    "action": "updated",
    "timestamp": "2025-01-15T14:23:01Z",
    "resource_id": "i-0abcdef1234567890",
    "attributes": {
      "instance_type": "t3.medium",
      "ami": "ami-0fedcba9876543210",
      "tags": {
        "Name": "api-server",
        "Environment": "production",
        "Version": "2.4.1"
      }
    },
    "changes": {
      "tags.Version": {"old": "2.3.0", "new": "2.4.1"},
      "ami": {"old": "ami-0abcdef1234567890", "new": "ami-0fedcba9876543210"}
    }
  }
]

Tracking Tag Changes

History is especially useful for tracking tag changes over time:

$ oxid history aws_s3_bucket.data

History for aws_s3_bucket.data (4 entries):

[1] 2025-01-15 10:00:00 (3 hours ago) - updated
    ID: my-data-bucket
    tags:
      Environment: production
      Team: platform
      CostCenter: CC-1234

    Changes from previous:
      + tags.CostCenter: "CC-1234" (added)

[2] 2025-01-08 14:30:00 (7 days ago) - updated
    ID: my-data-bucket
    tags:
      Environment: production
      Team: platform

    Changes from previous:
      ~ tags.Team: "engineering" => "platform"

[3] 2024-12-15 09:00:00 (31 days ago) - updated
    ID: my-data-bucket
    tags:
      Environment: production
      Team: engineering

    Changes from previous:
      ~ tags.Environment: "staging" => "production"

[4] 2024-11-01 11:00:00 (75 days ago) - created
    ID: my-data-bucket
    tags:
      Environment: staging
      Team: engineering

resource_history Table Schema

History is stored in the resource_history table. You can query it directly with oxid query:

resource_history schema
-- Table schema
CREATE TABLE resource_history (
  id          INTEGER PRIMARY KEY,
  address     TEXT NOT NULL,
  action      TEXT NOT NULL,       -- created, updated, destroyed, replaced
  resource_id TEXT,
  attributes  TEXT,                -- JSON blob of resource attributes
  changes     TEXT,                -- JSON blob of attribute diffs
  created_at  TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

SQL Queries for History

All changes in the last 24 hours

oxid query "
  SELECT address, action, created_at
  FROM resource_history
  WHERE created_at > datetime('now', '-1 day')
  ORDER BY created_at DESC
"

Resources changed most frequently

oxid query "
  SELECT address, COUNT(*) as changes
  FROM resource_history
  GROUP BY address
  ORDER BY changes DESC
  LIMIT 10
"

All destroy operations

oxid query "
  SELECT address, resource_id, created_at
  FROM resource_history
  WHERE action = 'destroyed'
  ORDER BY created_at DESC
"

Changes to a specific resource type

oxid query "
  SELECT address, action, created_at
  FROM resource_history
  WHERE address LIKE 'aws_security_group%'
  ORDER BY created_at DESC
"

Use Cases

  • Incident investigation - Trace what changed and when after an outage
  • Compliance auditing - Maintain a complete record of infrastructure changes
  • Configuration drift tracking - Identify resources that change frequently
  • Change review - See the full evolution of a resource over time