Gothic Framework G symbol

Custom Infrastructure

Gothic provisions your app with OpenTofu, and you can extend that same stack with your own AWS resources — a DynamoDB table, an SQS queue, an extra S3 bucket, whatever you need. Just drop .tf or .tf.json files into an infra/ folder at your project root. Gothic merges them into the same module and state as its own stack, so they are created, updated, and destroyed together with your app — no separate tooling, no separate tofu apply.

To wire your resources to the app, reference Gothic's stack through the stable local.gothic_* contract — names like local.gothic_lambda_role_name, local.gothic_lambda_function_arn, local.gothic_s3_bucket_name, and local.gothic_cloudfront_distribution_id. Here we add a table and grant the Lambda role access to it:

# infra/dynamodb.tf
resource "aws_dynamodb_table" "todos" {
  name         = "todos"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "id"
  attribute {
    name = "id"
    type = "S"
  }
}

# Grant the Gothic Lambda role access via the stable local.gothic_* contract:
resource "aws_iam_role_policy" "todos_access" {
  role   = local.gothic_lambda_role_name
  policy = jsonencode({
    Version = "2012-10-17",
    Statement = [{
      Effect   = "Allow",
      Action   = ["dynamodb:*"],
      Resource = aws_dynamodb_table.todos.arn
    }]
  })
}

Pass the table name to your app as a stage ENV var and read it with os.Getenv — the same pattern works for SQS, SNS, extra buckets, and more.

Note: only top-level *.tf / *.tf.json files in infra/ are merged, and a file whose name collides with a Gothic-generated one is rejected rather than silently overwritten. This drop-in replaces the old v2 SAM template editing entirely.

Infrastructure done. Let's give your app a custom domain!