Bypassing AWS Complexity
Published: 2024-01-11 16:56:48


## Our mission..

..is to empower Rust developers by providing tooling that bypasses the need to interact with complicated AWS infrastructure or infrastructure files when the requirement is to move fast.

When you're self-hosting, using a VPS, or on the cloud, you have control over everything. It can also be very complex: anything related to AWS, Terraform files, Dockerfiles... the list goes on. If you’re also playing the part as a Software Engineer, this can use up quite a lot of time, especially in cases where moving fast is a higher priority than having control over everything. What you end up with is:

- Spending time context-switching which interrupts your flow.
- Ending up with responsibilities that you may not specialize in, potentially spending more time debugging your work.
- Needing to figure out Cloud consoles; they solve a lot of problems, but are also very complex to use.

![https://pbs.twimg.com/media/EQepmc-VAAEWFpp.jpg](https://pbs.twimg.com/media/EQepmc-VAAEWFpp.jpg)

Other solutions aim to solve this problem by dockerizing your applications for you. However, on those platforms Rust is typically treated as a second-class citizen, requiring you to write your own Dockerfile to deploy on the platform. You may also hit errors that you normally wouldn’t with other languages.

Our aim is to enhance the Rust development experience. We've built our open-source platform with Rust, and we strive to use Rust for our internal tools wherever feasible. Our goal is to provide Rust developers with a smooth and efficient deployment process comparable to what JavaScript developers enjoy with platforms like [Vercel](https://vercel.com), emphasizing ease-of-use with minimal setup.

## What are we doing currently?

### 1. Providing tooling that simplifies deployments

We provide tooling that simplifies deployment by allowing users to add our Shuttle runtime macro to their applications. This means all you need to do is run `cargo shuttle deploy` and your web service gets sent to the Shuttle servers, containerized, and started. No further steps are required!

Check the snippet below for a short example:
```rust
use axum::{routing::get, Router};
use std::net::SocketAddr;
use tokio::net::TcpListener;

// handler function
async fn hello_world() -> &'static str {
    "Hello world!"
}

// serving a web server normally
#[tokio::main]
async fn main() {
    // create the router
    let router = Router::new().route("/", get(hello_world));

    // create TcpListener and serve the web service through it
    let addr = SocketAddr::from(([0,0,0,0], 8000));
    let tcp = TcpListener::bind(addr).await.unwrap();

    axum::serve(tcp, router).await.unwrap();
}

// serving a web server through Shuttle
#[shuttle_runtime::main]
async fn main() -> shuttle_axum::ShuttleAxum {
    let router = Router::new().route("/", get(hello_world));

    // no TcpListener required
    Ok(router.into())
}
```


### 2. Making resource provisioning as easy as possible

You shouldn’t need to set up YAML files just to get your application going. When using our runtime, you can simply pass in annotation macros that [provision resources](https://docs.shuttle.rs/resources/overview) for you. Whether you need a database, key-value store, or some metadata about your project, we can provide that! By doing this, it allows a seamless experience between getting the infra stuff that you want and then going straight back to writing good code.

```rust
use axum::{routing::get, Router};
use sqlx::PgPool,

// handler function
async fn hello_world() -> &'static str {
    "Hello world!"
}

#[tokio::main]
async fn main() {
    // set up database connection then add it as app state
    let conn_str = std::env::var("DB_URL").unwrap();
    let conn = PgPool::connect(&conn_str).await.unwrap();
    let router = Router::new()
        .route("/", get(hello_world))
        .with_state(Arc::new(conn));

    // ... creating the TcpListener and serving
}

#[shuttle_runtime::main]
async fn main(
    // database connection provided through macro
    #[shuttle_shared_db::Postgres] db: PgPool,
) -> shuttle_axum::ShuttleAxum {
    // set up router and return it 
    let router = Router::new()
        .route("/", get(hello_world))
        .with_state(Arc::new(conn));

    Ok(router.into())
}
```

### What we’re doing in 2024

There are several updates we’re looking forward to announcing this year. Most notably, our upcoming builder service which will allow many more use cases and bring additional platform stability. We are also planning on adding more integrations like Redis, S3 object storage, and more so keep an eye out for our 2024 product roadmap which will have more information!

Feedback is always welcome at hello@shuttle.rs if there’s anything you’d like us to know!