StrataCI — the execution plane

StrataCI is the small, one-time execution plane that StrataCTL stands up inside your own AWS account. It is the infrastructure that installs, updates, and removes StrataBI modules and the platform itself — an S3 bucket, a few DynamoDB tables, a CodeBuild-based ephemeral runner, and the IAM roles that tie them together. Shaleio holds no credentials here: you run StrataCTL with your own AWS identity, and every deploy executes in your account, against state stored in your account.

You provision it once per account/region with stratactl bootstrap, and everything StrataCTL does afterward — install, update, uninstall, dev install, install-stratabi — runs through it.

Why it exists

Installing StrataBI means running OpenTofu against your account. Rather than run that from your workstation (and scatter state and credentials around), StrataCI runs it in an ephemeral, least-privilege runner in your account. The runner fetches a verified bundle, runs OpenTofu against your own S3 state backend, records status, and exits. The result: deployment state and logs live in your account end to end, and the human operator only ever needs their own IAM identity.

stratactl bootstrap

bootstrap provisions (or tears down) the StrataCI plane. It is safe by default — with no flags it prints what it would do and stops; it only touches AWS with --run, and only applies with --run --yes.

bash
stratactl --profile <profile> --region <region> bootstrap              # dry run — describe only
stratactl --profile <profile> --region <region> bootstrap --run        # init + plan
stratactl --profile <profile> --region <region> bootstrap --run --yes  # init + plan + apply
stratactl --profile <profile> --region <region> bootstrap --destroy    # tear the plane down

It runs once per account/region. --profile/--region may appear anywhere in the command.

What the template provisions — exactly

The bootstrap Terraform (name_prefix defaults to strataci) creates:

ResourceNamePurpose
S3 bucketstrataci-<account>-<region> (or bucket_name)Artifact cache, OpenTofu state, and logs. Versioned, KMS-encrypted (bucket keys on), full public-access block, prevent_destroy.
DynamoDB — install registry<prefix>_install_registryThe record of what's installed (hash key module_id), with point-in-time recovery and prevent_destroy.
DynamoDB — jobs<prefix>_jobsRunner job records (hash key job_id).
DynamoDB — state lock<prefix>_tf_locksOpenTofu state lock (hash key LockID).
CloudWatch log group/<prefix>/runnerRunner logs (30-day retention).
CodeBuild project<prefix>-runnerThe ephemeral runner (see below).
Runner IAM role<prefix>-runner-roleAssumed by CodeBuild; scoped to the bucket, the three tables, its logs, and sts:AssumeRole on the deploy role only.
Deploy IAM role<prefix>-deploy-roleBroad-by-design role the runner assumes with a module-scoped session policy (see the security model).
Operator IAM policy<prefix>-operatorYou attach this to your own engineer identity — it's how a human drives StrataCTL.

All resource names derive from name_prefix, so a second, isolated plane is just a second prefix. Everything billable is serverless/on-demand (PAY_PER_REQUEST tables, CodeBuild per build, S3/logs usage).

tofu output emits ready-to-use values, including a paste-ready [customer] block for ~/.stratactl/config.toml (bucket + table names + project) so StrataCTL resolves the plane with no manual config. The Developer Edition install records these automatically — see Dashboards as code for how stratactl dashboards reuses them.

The ephemeral runner

The CodeBuild project is the runner. It uses no source and an inline buildspec; the per-job spec (action, module, artifact reference, state backend, table names) is injected as environment overrides at StartBuild time. On each run it:

  1. Ensures OpenTofu is present (installs the pinned tofu_version, default 1.8.5,

unless the image is prebaked).

  1. Ensures the strata runner package is present (from an s3:// wheel or a pip spec

via STRATA_PKG — the CLI passes the launching version so the runner tracks it).

  1. Ensures cryptography is present for offline bundle-signature verification.
  2. Runs python3 -m strata.runner, which verifies the bundle, runs OpenTofu, and records

status/outputs.

It runs on a standard AWS CodeBuild image by default (runner_image), or on a prebaked ECR image where tofu + strata already exist, so cold builds stay fast.

OpenTofu state on an S3 backend

State durability is the whole point, and it works at two layers.

Module and platform installs. When the runner deploys a bundle, it runs OpenTofu against your S3 backend — if the bundle declares no backend, the runner injects backend "s3" {} and initializes it with your plane's values:

text
-backend-config=bucket=<your strataci bucket>
-backend-config=key=<module state key>
-backend-config=region=<region>
-backend-config=dynamodb_table=<prefix>_tf_locks   # state lock
-backend-config=encrypt=true

State is pulled from S3 on init and pushed on apply, with the tf_locks table providing concurrency safety. Nothing lives on the runner after it exits; update and uninstall reuse the same remote state, so the lifecycle is fully reproducible from your bucket.

StrataCI's own state. The plane can't sit its backend inside the very bucket it is creating, so bootstrap applies with local state and then uploads that state file to s3://<bucket>/bootstrap/terraform.tfstate. That makes teardown durable and machine-independent: bootstrap --destroy pulls the state back from S3 (so you can tear down from any machine, not just the one that installed it), writes a lifecycle override that disables prevent_destroy and sets force_destroy so the plane can delete itself, and runs tofu destroy. Enable S3 versioning (the bucket already has it) as a backstop.

Delivery: how bundles reach the runner

The runner never pulls arbitrary source at deploy time — it runs a signed bundle whose OpenTofu, manifest, and defaults travel together and are verified offline against Shaleio's signing key before anything executes. Where that bundle comes from depends on the edition:

bucket, or the conventional bucket key; no StrataHQ contact and no license contract. See Developer Edition.

runtime/module bundle, resolved from your configuration; the runner verifies its signature before running OpenTofu. See Container image & supply chain and Delivery & teardown.

Delivery mode controls what's left behind: local (the default, and always the mode for the platform) caches the verified bundle into your bucket so later update/uninstall run with no outbound contact — including in air-gapped environments; managed leaves nothing behind and re-fetches at teardown. Full detail in Delivery & teardown.

Security model

Two IAM roles, deliberately split:

group — plus assume the deploy role. It holds no broad deploy permissions.

or the platform can provision — VPC, ECS, ALB, Cognito, the AWS security services, and so on). The runner assumes it with a session policy derived from the bundle's declared permissions, so the effective permissions are deploy role ∩ what the module asked for. A module can never deploy beyond what its manifest declares.

The operator policy is what a human attaches to their own identity; StrataCTL acts as you, so what you can deploy is bounded by your own IAM. Shaleio never receives credentials. See Security posture.

Teardown

bash
stratactl --profile <profile> --region <region> bootstrap --destroy

Because the state is stored in your bucket and pulled back on destroy, teardown does not depend on the machine that ran the install. Uninstall your modules and platform first (stratactl uninstall <module>, stratactl dev uninstall), then destroy the plane. See the Installation Guide and the FAQ.