Bootstrapping
Real AWS accounts come pre-provisioned with default VPCs, KMS keys, and service-linked roles. The SIMFRA_BOOTSTRAP environment variable replicates this setup in Simfra.
Standard Bootstrap
export SIMFRA_BOOTSTRAP=standard
This runs a native bootstrap that creates the following resources in 16 AWS regions (us-east-1, us-east-2, us-west-1, us-west-2, eu-west-1, eu-west-2, eu-west-3, eu-central-1, eu-north-1, ap-southeast-1, ap-southeast-2, ap-northeast-1, ap-northeast-2, ap-south-1, sa-east-1, ca-central-1):
Per Region
Default VPC (172.31.0.0/16) and associated resources:
- 6 subnets (one per AZ, /20 CIDR blocks)
- Internet gateway attached to the VPC
- Main route table with a route to the IGW
- Default security group
- Default network ACL
- DHCP options set
AWS-managed KMS keys (alias/aws/*) for:
- DynamoDB, EBS, S3, SNS, SQS, Lambda, RDS, CloudWatch Logs, SSM, CloudWatch
Global (Once)
IAM service-linked roles:
AWSServiceRoleForSupport(support.amazonaws.com)AWSServiceRoleForTrustedAdvisor(trustedadvisor.amazonaws.com)
Idempotency
When persistence is enabled (SIMFRA_DATA_DIR), standard bootstrap is skipped on restart if any persisted state was found. This prevents duplicate resource creation.
Terraform Bootstrap
Point SIMFRA_BOOTSTRAP at a directory containing .tf files:
export SIMFRA_BOOTSTRAP=/path/to/my/terraform
Simfra runs terraform init and terraform apply against itself using the default account credentials. The Terraform provider is configured automatically via AWS_ENDPOINT_URL.
How It Works
- Simfra copies all files from the blueprint directory to a working directory
- Sets
AWS_ENDPOINT_URLtohttp://localhost:<port>, plusAWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEYfrom the root account - Runs
terraform initfollowed byterraform apply -auto-approve - Collects Terraform outputs and logs the result
Simfra looks for terraform or tofu (OpenTofu) in PATH. The Docker image bundles Terraform.
Terraform State Persistence
When SIMFRA_DATA_DIR is set, the Terraform working directory is $SIMFRA_DATA_DIR/bootstrap/, so the state file survives restarts. Terraform handles its own idempotency - terraform apply on subsequent starts only creates/updates resources that changed.
When SIMFRA_DATA_DIR is not set, a temporary directory is used and state is lost on exit.
Example Blueprint
A minimal bootstrap that creates an S3 bucket and a DynamoDB table:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
}
}
}
provider "aws" {
region = "us-east-1"
}
resource "aws_s3_bucket" "data" {
bucket = "my-data-bucket"
}
resource "aws_dynamodb_table" "locks" {
name = "terraform-locks"
billing_mode = "PAY_PER_REQUEST"
hash_key = "LockID"
attribute {
name = "LockID"
type = "S"
}
}
output "bucket_name" {
value = aws_s3_bucket.data.id
}
Timeout
Terraform bootstrap has a 5-minute timeout. If terraform apply does not complete within this window, bootstrap fails and Simfra exits.
Bootstrap vs Implicit Resource Creation
Bootstrap creates account-level default resources that AWS pre-provisions. This is separate from implicit resource creation, where individual API calls create dependent resources as side effects.
For example:
- Bootstrap creates the default VPC with its subnets, IGW, route table, security group, and NACL
- CreateVpc (EC2 API) implicitly creates a main route table, default security group, and default NACL for the new VPC
Both behaviors are simulated. Bootstrap runs once at startup; implicit creation happens on every relevant API call.
No Bootstrap
When SIMFRA_BOOTSTRAP is empty (the default), Simfra starts with no pre-existing resources. Every resource must be created explicitly via API calls, Terraform, or the admin API. This is useful for testing from a clean slate.