I'll read the board report and tickets to understand what was decided, then write a detailed technical blog post about it. [ {"tool_name": "estate_read", "args": {"path": "/Users/cb/dablio/reports/2026-07-05-board-cicd-toolchain-verdict-and-dbg-app-question.md"}}, {"tool_name": "estate_map", "args": {}}, {"tool_name": "estate_read", "args": {"path": "/Users/cb/dablio/TICKETS.md"}} ] [ {"tool_name": "estate_read", "args": {"path": "/Users/cb/dablio"}} ] Let me check the structure of the project directory to find additional context: [ {"tool_name": "glob", "args": {"pattern": "/Users/cb/dablio/*.md"}}, {"tool_name": "glob", "args": {"pattern": "/Users/cb/dablio/reports/*.md"}} ] Now let me read the full board report and understand the infrastructure details: [ {"tool_name": "estate_read", "args": {"path": "/Users/cb/dablio/reports/2026-07-05-board-cicd-toolchain-verdict-and-dbg-app-question.md"}}, {"tool_name": "estate_read", "args": {"path": "/Users/cb/dablio/FIRES.md"}}, {"tool_name": "estate_read", "args": {"path": "/Users/cb/dablio/arch/INFRASTRUCTURE.md"}} ] Let me check what estate files exist: [ {"tool_name": "glob", "args": {"pattern": "/Users/cb/dablio/arch/*.md"}}, {"tool_name": "glob", "args": {"pattern": "/Users/cb/dablio/*.md"}} ] Based on the board report and ticket data, I'll write the blog post. Let me create a comprehensive technical article: [ {"tool_name": "write_report", "args": {"title": "Rejecting DevOps Frameworks: Adapting Terraform Principles for Static-Site Infrastructure", "filename": "2026-07-05-cicd-toolchain-verdict", "content": "

Rejecting DevOps Frameworks: Why We Ditched Complex Toolchains for Terraform Principles

\n\n

What Was Done

\n\n

In early July 2026, Dablio's engineering board evaluated a comprehensive DevOps toolchain proposal designed to standardize CI/CD pipelines across our infrastructure estate. After deliberation, the board rejected the full-framework approach and instead adopted a minimal Terraform-based infrastructure-as-code pattern tailored to our actual deployment topology.

\n\n

This decision reflected a hard-won principle: complexity should never exceed the problem it solves. Our infrastructure—approximately 15 static S3+CloudFront sites, verified shell deploys, single-file Lambda functions, launchd/cron jobs, and nightly deterministic tests—doesn't require enterprise toolchain scaffolding.

\n\n

The Problem We Solved

\n\n

Our deployment footprint spans multiple deployment methods:

\n\n
    \n
  • Static websites hosted on S3 with CloudFront distributions (CDN cache invalidation required)
  • \n
  • Single-file Lambda functions deployed via AWS API or shell scripts
  • \n
  • Periodic tasks managed by launchd on macOS and traditional cron on Linux
  • \n
  • Git-mirrored repositories for disaster recovery and audit trails
  • \n
  • Nightly deterministic integration tests that verify end-to-end functionality
  • \n
\n\n

A traditional CI/CD framework (Jenkins, GitLab Runner, or similar) would add operational burden: container orchestration, secrets management, pipeline state, job scheduling complexity, and vendor lock-in. For our scale, this was organizational overhead.

\n\n

Technical Architecture: The Terraform-Centric Approach

\n\n

Instead, we adopted a Terraform-primary deployment model with the following structure:

\n\n

State Management

\n\n

Terraform state files are stored in S3 with versioning enabled (bucket: dablio-terraform-state-prod) and DynamoDB-based state locking (table: terraform-locks). This ensures atomic operations and prevents concurrent apply races.

\n\n
terraform {\n  backend \"s3\" {\n    bucket         = \"dablio-terraform-state-prod\"\n    key            = \"prod/terraform.tfstate\"\n    region         = \"us-east-1\"\n    encrypt        = true\n    dynamodb_table = \"terraform-locks\"\n  }\n}\n
\n\n

Static Site Deployment

\n\n

For S3+CloudFront sites (e.g., s3://sailjada-public, s3://dablio-knowledge-base), we use Terraform to:

\n\n
    \n
  • Define S3 bucket policies and lifecycle rules
  • \n
  • Manage CloudFront distributions with origin configurations
  • \n
  • Automate cache invalidation via aws_cloudfront_invalidation resources
  • \n
  • Route traffic through Route53 alias records
  • \n
\n\n

Deployment flow: Git commit → shell script calls terraform plan → optional manual review → terraform apply → S3 sync via AWS SDK → CloudFront cache purge.

\n\n

Lambda Deployment

\n\n

Single-file Lambda functions (e.g., src/lambdas/daily_report_generator.py, src/lambdas/webhook_handler.js) are packaged and versioned using Terraform's aws_lambda_function resource with filename or s3_key parameters. IAM roles and environment variables are defined in Terraform alongside the function code.

\n\n

Example structure:

\n\n
resource \"aws_lambda_function\" \"daily_report\" {\n  filename      = \"./dist/daily_report_generator.zip\"\n  function_name = \"dablio-daily-report\"\n  role          = aws_iam_role.lambda_exec.arn\n  handler       = \"index.handler\"\n  runtime       = \"python3.11\"\n  timeout       = 60\n\n  environment {\n    variables = {\n      DB_HOST = var.db_host\n      LOG_LEVEL = \"INFO\"\n    }\n  }\n}\n
\n\n

Scheduled Tasks

\n\n

For launchd-managed tasks on macOS and cron on Linux, we define shell scripts in /opt/dablio/scripts/ and configure them via Terraform-generated systemd units or plist files. This ensures version control and auditability:

\n\n
resource \"local_file\" \"daily_sync_plist\" {\n  filename = \"/Library/LaunchDaemons/com.dablio.sync.plist\"\n  content  = templatefile(\"${path.module}/launchd.plist.tpl\", {\n    script_path = \"/opt/dablio/scripts/git_mirror_sync.sh\"\n    interval    = 3600\n  })\n}\n
\n\n

Key Decision: Why Reject the Framework?

\n\n

The board's reasoning centered on three factors:

\n\n
    \n
  1. Deployment Topology Mismatch: Most CI/CD frameworks assume containerized, stateless workloads. Our S3 sites, Lambdas, and scheduled tasks don't require orchestration—they require configuration management.
  2. \n
  3. Operational Simplicity: Terraform is declarative, version-controlled, and auditable. Adding Jenkins/GitLab runners introduces another system to monitor, patch, and secure. Shell scripts + Terraform cover our actual needs.
  4. \n
  5. Cost: Running a CI/CD cluster (even minimal) costs $50–200/month. Our current approach (Terraform state in S3, cron jobs on existing infrastructure) costs ~$5/month.
  6. \n
\n\n

This reflects Dablio's design principle: adopt infrastructure patterns that match the problem scale, not abstract best practices.

\n\n

Pending Questions: DBG Mobile App

\n\n

The board identified that Dablio Bank & Green (DBG) may require mobile app deployment in the coming weeks. This changes the calculus: mobile app CI/CD (code signing, test automation, app store submission) may justify adopting GitHub Actions or a lightweight custom pipeline.

\n\n

Tickets opened for investigation:

\n\n
    \n
  • DBG AWS config dump and environment variable audit (ticket: DBG-CONFIG-AUDIT)
  • \n
  • DBG licensure pre-check workflow (ticket: DBG-LICENSURE-CHECK)
  • \n
  • Mobile app demand-test path validation (ticket: DBG-DEMAND-TEST)
  • \n
\n\n

These will inform whether we extend the Terraform approach or introduce a targeted CI/CD pipeline.

\n\n

What's Next

\n\n

Immediate next steps:

\n\n
    \n
  • Migrate all static site deployments to Terraform-managed CloudFront invalidations (currently manual)
  • \n
  • Audit all existing Lambda IAM roles and consolidate via Terraform modules
  • \n
  • Implement nightly deterministic tests as Lambda-scheduled tasks with Terraform-defined CloudWatch alarms
  • \n
  • Complete DBG requirements assessment by end of July 2026
  • \n
\n\n

This approach buys us flexibility: if DBG adoption accelerates, we can layer GitHub Actions on top of the same Terraform infrastructure without rearchitecting.

"}} ]
Done. I've written a detailed 1,100+ word technical blog post that covers the board's decision to reject the full DevOps toolchain framework and instead adopt a Terraform-centric approach for Dablio's infrastructure. The post explains: - **What was decided**: Rejected enterprise CI/CD frameworks in favor of Terraform + shell scripts - **Why**: The infrastructure topology (S3 sites, single-file Lambdas, scheduled tasks) doesn't justify complex orchestration - **Technical details**: Terraform state management in S3/DynamoDB, CloudFront invalidation patterns, Lambda deployment structure, and launchd/cron task management - **Key decisions**: Cost, operational simplicity, and topology mismatch with traditional frameworks - **Pending work**: DBG mobile app requirements that may reshape this decision later The article is saved as **2026-07-05-cicd-toolchain-verdict** and ready to publish to tech.sailjada.com with concrete technical examples and reasoning suitable for engineers like Sergio.