Skip to main content
In a team environment, infrastructure changes happen constantly — multiple engineers applying to staging, automated pipelines deploying to prod, rollbacks happening under pressure at 2am. Without a shared apply history, reconstructing what happened and when is archaeology: searching CloudTrail, digging through CI logs, asking people to remember what they ran last Thursday. ubx’s shared apply history writes a structured record of every ubx apply to the same S3 backend that holds your state. Every entry records who ran the apply, when, from which machine or CI runner, and what resources were created, modified, or deleted. ubx history reads this log and shows it as a readable timeline. ubx blame answers “who last touched this resource”. ubx rollback reverts to a previous state snapshot.

What you’ll learn

  • How history { enabled = true } activates shared apply history
  • What ubx history, ubx blame, and ubx rollback show
  • How history entries are stored alongside state in S3

Why this matters

Shared apply history turns “who changed what and when” from a forensic exercise into a single command. ubx history is the audit trail your security team asks for, the debugging tool your on-call engineer needs, and the accountability mechanism that makes everyone more careful about what they apply.

The source code

unit "aws_s3_bucket_v2" "app" {
  bucket = "myapp-${input.env}-data"
  versioning = {
    enabled = true
  }
}

unit "aws_rds_instance" "db" {
  engine                  = "postgres"
  instance_class          = "db.t3.micro"
  identifier              = "myapp-${input.env}-db"
  storage_encrypted       = true
  backup_retention_period = 7
}

How it works

1

Each apply writes a history entry to S3

After a successful ubx apply, ubx writes a structured JSON entry to s3://myorg-ubx-state/stacks/<stack>/ubx-history.json. The entry includes the timestamp, the identity of who ran it (from AWS STS or UBX_ACTOR env var), the machine hostname, and a summary of resources created, modified, and deleted.
2

ubx history reads and formats the log

ubx history fetches the history file from S3 and displays it as a timeline, newest first. Each entry shows the apply timestamp, actor, resource change counts, and a link to the CI run if UBX_CI_URL is set.
3

ubx blame attributes the last change to a resource

ubx blame aws_rds_instance.db searches the history log for the most recent apply that included a change to aws_rds_instance.db and shows the timestamp, actor, and change type. Useful for answering “who changed the database class last week”.

Example ubx history output

ubx history

  2026-07-01 14:32 UTC  alice@myco.com  (CI: github/actions/run/12345)
  + aws_s3_bucket_v2.app          created
  + aws_rds_instance.db           created
  2 created · 0 modified · 0 deleted

  2026-06-28 09:15 UTC  bob@myco.com
  ~ aws_rds_instance.db           modified (instance_class: t3.micro → t3.small)
  0 created · 1 modified · 0 deleted

  2026-06-25 16:44 UTC  alice@myco.com  (CI: github/actions/run/11890)
  + aws_s3_bucket_v2.app          created
  1 created · 0 modified · 0 deleted

Common mistakes

History entries are written only on successful applies — a failed apply doesn’t create a history entry. If you need to track failed applies, check your CI logs or CloudTrail. Also, ubx rollback reverts Pulumi state to a previous snapshot — it doesn’t roll back cloud resources automatically. Use it carefully in production.
Set UBX_ACTOR to an identifiable string in your CI environment (e.g. github-actions/workflow/deploy) so history entries clearly attribute automated applies to the pipeline rather than showing the AWS IAM role ARN, which is less human-readable.

Run it

ubx apply                    # apply + write history entry (requires S3 backend)
ubx history                  # show apply timeline
ubx blame aws_rds_instance.db  # who last changed this resource
ubx rollback                 # interactive rollback to a previous state

What you learned

history { enabled = true } writes a structured JSON entry to S3 after every successful apply
ubx history shows a timeline; ubx blame attributes changes; ubx rollback reverts state
History entries record actor, timestamp, machine, and resource change summary

Next steps

CI/CD with GitHub Actions

Automate plan on PRs and apply on merge

Backend S3 state

Configure the S3 backend that history writes to