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 with a specific ID that your code references
resource "aws_vpc" "shared" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "shared-services"
"simfra:VpcId" = "vpc-0abc123def456789a"
}
}
# 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"
"simfra:SubnetId" = "subnet-0aaaa00000000000a"
}
}
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"
"simfra:SubnetId" = "subnet-0bbbb00000000000b"
}
}
# KMS key your encryption config references
resource "aws_kms_key" "app" {
description = "Application encryption key"
tags = {
"simfra:KeyId" = "12345678-1234-1234-1234-123456789012"
}
}
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)
- Add
simfra:override tags where 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. Use simfra: override tags to create resources with exact IDs.
See Resource ID Overrides for the complete tag reference and examples.
Example: Match a Specific VPC and All Associated Resources
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
"simfra:VpcId" = "vpc-0abc123def456789a"
"simfra:DefaultSecurityGroupId" = "sg-0abc123def456789a"
"simfra:MainRouteTableId" = "rtb-0abc123def456789a"
"simfra:DefaultNetworkAclId" = "acl-0abc123def456789a"
}
}
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