Bootstrapping Your Account
Real AWS accounts come pre-provisioned with default VPCs, KMS keys, and service-linked roles. Terraform modules often assume these resources exist. Simfra provides several ways to replicate this starting state.
Prerequisites
- Simfra running on
localhost:4599(see Installation) - For custom Terraform bootstrap: Terraform 1.6+ installed
The Problem
Your Terraform code might reference:
- A default VPC and its subnets (data sources like
data "aws_vpc" "default") - AWS-managed KMS keys (
alias/aws/s3,alias/aws/rds) - IAM service-linked roles
- Specific resource IDs that are hardcoded in variables or remote state
Without these resources, terraform plan fails with "not found" errors.
Solution 1: Standard Bootstrap
Set SIMFRA_BOOTSTRAP=standard to create the same default resources that a real AWS account has:
export SIMFRA_BOOTSTRAP=standard
This creates 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) with 6 subnets, internet gateway, main route table, default security group, default network ACL, and DHCP options set
- AWS-managed KMS keys with aliases:
alias/aws/dynamodb,alias/aws/ebs,alias/aws/s3,alias/aws/sns,alias/aws/sqs,alias/aws/lambda,alias/aws/rds,alias/aws/logs,alias/aws/ssm,alias/aws/cloudwatch
Global (once):
- IAM service-linked roles:
AWSServiceRoleForSupport,AWSServiceRoleForTrustedAdvisor
Standard bootstrap is idempotent. When persistence is enabled (SIMFRA_DATA_DIR), it is skipped on restart if persisted state already exists.
Solution 2: Custom Terraform Bootstrap
Point SIMFRA_BOOTSTRAP at a directory containing .tf files that mirror your account's starting state:
export SIMFRA_BOOTSTRAP=/path/to/my/bootstrap
Simfra runs terraform init and terraform apply -auto-approve against itself at startup.
Example: Bootstrap Specific Resources
# /path/to/my/bootstrap/main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
}
}
}
provider "aws" {
region = "us-east-1"
}
# Create a VPC that your code references
resource "aws_vpc" "shared" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "shared-services"
}
}
# Subnets your modules expect
resource "aws_subnet" "private_a" {
vpc_id = aws_vpc.shared.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-east-1a"
tags = {
Name = "private-a"
}
}
resource "aws_subnet" "private_b" {
vpc_id = aws_vpc.shared.id
cidr_block = "10.0.2.0/24"
availability_zone = "us-east-1b"
tags = {
Name = "private-b"
}
}
# KMS key your encryption config references
resource "aws_kms_key" "app" {
description = "Application encryption key"
}
resource "aws_kms_alias" "app" {
name = "alias/app-key"
target_key_id = aws_kms_key.app.id
}
# IAM role your Lambda functions assume
resource "aws_iam_role" "lambda_exec" {
name = "lambda-execution-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Service = "lambda.amazonaws.com" }
Action = "sts:AssumeRole"
}]
})
}
resource "aws_iam_role_policy_attachment" "lambda_basic" {
role = aws_iam_role.lambda_exec.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}
Terraform State Persistence
When SIMFRA_DATA_DIR is set, the bootstrap working directory is $SIMFRA_DATA_DIR/bootstrap/. The Terraform state file survives restarts, so terraform apply on subsequent starts only creates or updates resources that changed.
When SIMFRA_DATA_DIR is not set, a temporary directory is used and state is discarded on exit.
Timeout
Terraform bootstrap has a 5-minute timeout. If terraform apply does not complete within this window, Simfra exits with an error.
Solution 3: Replay Existing State
If you already manage your account's baseline resources with Terraform, you can replay the same configuration against Simfra:
- Copy your baseline
.tffiles to a bootstrap directory - Remove any remote backend configuration (Simfra uses local state)
- Use resource ID overrides (
simfra:tags or the Simfra Terraform provider) if you need specific resource IDs - Point
SIMFRA_BOOTSTRAPat the directory
cp -r infra/baseline/ simfra-bootstrap/
# Remove backend config - Simfra uses local state
rm simfra-bootstrap/backend.tf
export SIMFRA_BOOTSTRAP=./simfra-bootstrap
Pinning Resource IDs
Your code may reference specific resource IDs — a VPC ID in a variables file, a KMS key ARN in a config map, a Route53 zone ID in a DNS module. Use simfra: tags for resources that accept tags, and the Simfra Terraform provider for resources that don't.
See Resource ID Overrides for supported resources and examples.
Example: Pin a VPC ID with Tags
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
"simfra:VpcId" = "vpc-0abc123def456789ab"
}
}
Example: Pin a Route53 Zone with the Simfra Provider
Route53 hosted zones don't accept tags at creation time, so use the Simfra provider:
resource "simfra_route53_zone" "main" {
id = "Z0393724IIOWJEG34GXQ2"
name = "example.com"
}
Combining Bootstrap Modes
You can use SIMFRA_BOOTSTRAP=standard for the default VPC and KMS keys, then apply additional Terraform after Simfra starts to add project-specific resources. The admin API also supports per-account bootstrap:
# Start with standard defaults
SIMFRA_BOOTSTRAP=standard ./bin/simfra &
# Wait for healthy
curl --retry 10 --retry-connrefused http://localhost:4599/_simfra/health
# Apply project-specific resources
cd my-bootstrap && terraform apply -auto-approve
Next Steps
- Resource ID Overrides - pin resources to specific IDs using
simfra:tags - Provider Configuration - the canonical Terraform provider setup
- Testing Patterns - patterns for testing Terraform modules against Simfra