DEV Community

Cover image for I Got Tired of Wrestling with YAML, So I Built a DevOps Helper in Rust πŸš€
Alex Holmberg
Alex Holmberg

Posted on

I Got Tired of Wrestling with YAML, So I Built a DevOps Helper in Rust πŸš€

We've all been there. You spend all of Monday crafting that piece of brilliant code, only to spend the rest of the week trying to get it to play nice with Docker, Kubernetes, and a dozen environment variables. I found myself spending more time configuring infrastructure than actually writing the code that solved problems. It felt like the tools built to support development had become more complex than the development itself.

After one too many Fridays spent rolling back a deployment because of a forgotten config value, I thought, "What if there was a simple tool that could just look at my code and tell me what I need?"

That's how the idea for the Syncable CLI startedβ€”a small, open-source tool I've been building in Rust to try and bring a bit of clarity to the chaos of modern deployment pipelines.

What is Syncable CLI and Who is it for?

Syncable CLI is a command-line tool that scans your project, figures out what technologies you're using, and helps you spot common issues. Think of it as a friendly assistant who's pretty good with DevOps and security, ready to give your project a quick look-over.

It’s perfect for:

  • Developers who'd rather be coding than writing YAML.
  • Small teams that don't have a dedicated DevOps expert.
  • Anyone who has ever googled "Kubernetes vs Docker Compose" and just wanted a straight answer for their specific project.
  • Beginners who are intimidated by the wall of configuration needed to get a project live.

You can install it with Cargo and run it on any project.

# Install once
cargo install syncable-cli

# Get a quick overview of your project
sync-ctl analyze .
Enter fullscreen mode Exit fullscreen mode

How I'm trying to make it different (and hopefully cool 😎)

I know there are a million DevOps tools out there. Many of them are incredible, but I wanted to build something that felt less like another system to learn, and more like a helpful companion.

A Quick Project Overview

My first goal was to create something that could give me an instant "birds-eye view" of a repository. Instead of digging through package.json files and source code, you can just run analyze .

$ sync-ctl analyze ./my-express-app
═══════════════════════════════════════════════════════════════════════════════
πŸ“Š PROJECT ANALYSIS DASHBOARD
═══════════════════════════════════════════════════════════════════════════════
β”Œβ”€ Architecture Overview ────────────────────────────────────────────────────┐
β”‚ Type:                                                   Single Project     β”‚
β”‚ Pattern:                                                     Fullstack     β”‚
β”‚ Full-stack app with frontend/backend separation                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”Œβ”€ Technology Stack ─────────────────────────────────────────────────────────┐
β”‚ Languages:                                     JavaScript, TypeScript      β”‚
β”‚ Frameworks:                              Express, React, Tailwind CSS      β”‚
β”‚ Databases:                                          PostgreSQL, Redis      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Enter fullscreen mode Exit fullscreen mode

The tool does its best to figure out your architecture (like monolithic vs. microservices), identify your frameworks, and even map out which ports your services might need. It’s not magic, but it’s a nice starting point.

A Built-in Security Conscience

Let's be honest, most of us aren't security experts. I wanted a simple way to catch common mistakes without having to be a pro. The security and vulnerabilities commands are my attempt at that.

# Scan for outdated dependencies with known vulnerabilities
sync-ctl vulnerabilities

# Look for common security mistakes in your code
sync-ctl security
Enter fullscreen mode Exit fullscreen mode

These commands check for things like:

Outdated packages with known CVEs.

  • Secrets accidentally left in config files or code.
  • Missing security headers or insecure Dockerfile patterns.
  • It helps me catch silly mistakes before they become real problems, prioritizing the most critical issues first so I know where to focus.

AI-Generated Infrastructure (The Dream)

This is where I want to take the project. The analysis is cool, but what if the tool could use that information to write the deployment files for you?

# This is the goal for v2.0!
sync-ctl generate dockerfile
sync-ctl generate compose
Enter fullscreen mode Exit fullscreen mode

The vision is for these generated files to be more than just generic templates. They should be tailored to your project, with things like multi-stage Dockerfiles that are optimized for your specific stack. It's a big goal, but I think it could save a lot of time.

The Tech Behind It

I chose Rust for this project because I wanted it to be fast and reliable. As a CLI tool, performance is key! πŸ¦€

It's built using a few libraries that I've really come to love:

  • Clap: For parsing command-line arguments. It makes creating a professional-feeling CLI incredibly easy.
  • Serde: For handling all the configuration file parsing (package.json, Cargo.toml, etc.). It's a lifesaver.
  • Regex: For the core of the technology and secret detection. It's powerful, but as I learned, it's only half the story.
  • A custom-built graph logic to understand how different projects in a monorepo might relate to each other.

The security scanner is a core part of the CLI. For something like JavaScript, it's not enough to just look for keys. You have to understand the context to avoid false positives. I wrote a JavaScriptSecurityAnalyzer that uses a list of known patterns, complete with context clues and indicators that might suggest a false positive.

Here’s a peek at how some of those patterns are defined. It's no "magic AI" but pure logic and some carefully curated list of rules.

// from javascript.rs

/// Initialize JavaScript-specific secret patterns
fn initialize_js_patterns() -> Result<Vec<JavaScriptSecretPattern>, SecurityError> {
    let patterns = vec![
        // Firebase config object
        JavaScriptSecretPattern {
            id: "js-firebase-config".to_string(),
            name: "Firebase Configuration Object".to_string(),
            pattern: Regex::new(r#"(?i)firebaseConfig\s*[=:]\s*\{[^}]*apiKey\s*:\s*["']([^"']+)["'][^}]*\}"#)?,
            severity: SecuritySeverity::Medium,
            description: "Firebase configuration object with API key detected".to_string(),
            context_indicators: vec!["initializeApp".to_string(), "firebase".to_string()],
            false_positive_indicators: vec!["example".to_string(), "placeholder".to_string()],
        },

        // Generic API key in object assignment
        JavaScriptSecretPattern {
            id: "js-api-key-object".to_string(),
            name: "API Key in Object Assignment".to_string(),
            pattern: Regex::new(r#"(?i)(?:apiKey|api_key|clientSecret|secretKey)\s*:\s*["']([A-Za-z0-9_-]{20,})["']"#)?,
            severity: SecuritySeverity::High,
            description: "API key or secret assigned in object literal".to_string(),
            context_indicators: vec!["fetch".to_string(), "axios".to_string(), "headers".to_string()],
            false_positive_indicators: vec!["process.env".to_string(), "placeholder".to_string()],
        },
    ];

    Ok(patterns)
}
Enter fullscreen mode Exit fullscreen mode

Another tricky part was making sure not to flag secrets in files that are supposed to have them, like .env files. But what if an .env file is accidentally checked into git? To handle this, I built a gitignore-aware scanner. Its main job is to figure out if a file is being ignored correctly.

The core logic is a simple state machine that assesses the risk of a file based on whether it should be ignored, if it is ignored, and if it's currently being tracked by git.

// from gitignore.rs

#[derive(Debug, Clone, PartialEq)]
pub enum GitIgnoreRisk {
    Safe,      // Properly ignored, no secrets detected
    Protected, // Contains secrets but is properly ignored
    Exposed,   // Contains secrets and is NOT ignored
    Tracked,   // Contains secrets, is not ignored, AND is tracked by git
}

/// Assess the risk level for a file
fn assess_risk(&self, is_ignored: bool, is_tracked: bool, should_be_ignored: bool) -> GitIgnoreRisk {
    match (should_be_ignored, is_ignored, is_tracked) {
        // File contains secrets...
        (true, true, _) => GitIgnoreRisk::Protected,      // and is ignored (good).
        (true, false, true) => GitIgnoreRisk::Tracked,    // and is NOT ignored AND tracked (critical!).
        (true, false, false) => GitIgnoreRisk::Exposed,   // and is NOT ignored but not yet tracked (high risk).

        // File does not appear to contain secrets.
        (false, _, _) => GitIgnoreRisk::Safe,
    }
}
Enter fullscreen mode Exit fullscreen mode

Struggles I've Faced

This has been a passion project, and it definitely hasn't been easy.

  • Balancing "AI" with Reality: I'll be honest, there's no actual AI or large language model in the CLI right nowβ€”that's on the roadmap! Currently, the "intelligence" comes from a complex tree of heuristics, the pattern matching you see above, and dependency graph analysis. Making it smart enough to be helpful, but not so "magical" that it gives weird suggestions, has been a constant balancing act.
  • The Never-Ending List of Technologies: The original goal was to support just a few stacks I used personally. But then friends wanted support for Go, then Java, then Python. Every ecosystem has its own quirks, package managers, and file structures. Supporting over 260 technologies is an ongoing challenge.
  • Keeping it Simple: My main goal was to build a tool that was "stupidly simple" to use. But as you add more features, you're tempted to add more flags, more configuration, and more complexity. I've had to constantly pull back and ask, "Does this actually make a developer's life easier?"

Try It Yourself and Let Me Know What You Think!

Syncable CLI is still young and has a long way to go, but I'm excited about its direction. It's completely free and open-source.

Try it now:

cargo install syncable-cli
sync-ctl analyze .
Enter fullscreen mode Exit fullscreen mode

What's Next? (And How You Can Help)

While I'm really excited about how the syncable-cli is shaping up, it's just the first step. The bigger dream is to use this open-source core to build a full DevOps platform. On the sidelines, my team and I are working to create a service that covers the entire deployment lifecycle, from code to a running application.

Our goal is to completely remove the barrier to entry for DevOps. We want to make deployments so simple that anyone can do it, achieving true one-click deployment. Imagine connecting your repository and just… letting the platform handle the rest.

Let's Build This Together!

To make that vision a reality, the foundation needs to be rock-solid, and that's where the open-source syncable-cli comes in. I truly believe in the power of community, and I can't build this alone. The CLI is, and will always be, open-source. I'm inviting you to help shape its future.

  • ⭐ Star the project on GitHub: Show your support and help it get discovered by others.
  • πŸ“¦ Crates.io to download
  • 🐞 Find errors and bugs: If you run it on your project and something breaks or seems weird, please open an issue! Real-world use cases are the best way to find problems.
  • πŸ’‘ Come with suggestions: Have an idea for a new check, a better output format, or a technology we should support? Start a discussion! Your feedback is gold.
  • 🀝 Contribute: We're open to any and all PRs! Whether it's fixing a typo in the docs or adding a new feature, check out our contributing guide to get started.

And if you're excited by the idea of a one-click deployment platform, you can join the waitlist at syncable.dev to be the first to know when it's ready.

What's your biggest headache when it comes to deployment and infrastructure? I'd love to hear about it in the comments. Let's figure out how to solve these problems together! πŸ€—

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.