wait what? generate your entire infra from rust macros

Overview

infra as macro

translate rust structs to terraform at compile time

// your infra is a macro
static DB: Postgres = Postgres16! {
    host: "env.host",
    password: "env.password",
    database: "todos",
    user: "localhost",
    port: 5432
};

// your entites are structs
#[derive(Table)]
struct User {
    id: Id<Self>,
    name: String
}

// and you can use them wherever
async fn main() {
    let users = User::list_all().await;
}

wait what

why would you do this??

well, pulumi is cool and all, but kinda lame since it requires actually running code to generate the right terraform files.

what if... we used rust macros... and const-compatible structs... to spit out the .tf files AT COMPILE TIME.

what this demos

This repo doesn't currently do rust -> tf translation. TODO.

This repo demos a few things:

  • how we can create typesafe macros that provide intellisense and goto-def
  • how this can be automated
  • how this can generate the .tf files, migrations, .sql, etc
  • and the same types can be USED within your app. typesafely!

how we intend it to be used

You'll want to define your infra. You can choose between sqlite, postgres, redis, kafka, clickhouse, mqtt, and s3. This should cover most basic use cases.

For a postgres 16 instance, we create a global static. We can do this in our app or in a workspace dependency - both work and get mapped to the same infra.

static DB: Postgres = Postgres16! {
    host: "env.host",
    password: "env.password",
    database: "todos",
    user: "localhost",
    port: 5432
};

Then, we can create a new table against this bit of infra. We can associate the table manually, or just let iac figure it out at runtime.

#[derive(Table)]
struct User {
    id: Id<Self>,
    name: String,
    email: String,
    friends: Vec<Id<Self>>,
    profile: UrlS3<PHOTOS>
}

We can even reference this entity in other tables:

// And now declare a relation between two tables
#[derive(Table)]
struct Post {
    id: Id<Self>,
    creator: Id<User>,
}

If we wanted, we could add s3 backing photo uploads

static PHOTOS: S3Bucket = S3! {
    name: "photos"
}

And then add it to our struct, typesafely.

#[derive(Table)]
struct User {
    // ....
    profile_photo: UrlS3<PHOTOS>
}

This will spit out the right .sql migrations in our deploy directory. IAC will properly stick together all the migrations and .tf files to get a sense of your infra.

In theory, we could create no-code tooling to visualize and customize the infra.

using iac

Since the structs are readily available in our code, we can just query them directly.

fn main() {
    // query the db for a list
    let users = DB.list::<User>();

    // do some sql
    let users = DB.query(sql!(`select * from {User} where {User.friends.len()} < 5`));

    // handle a photo upload
    let new_photo: S3Url = S3.upload(bytes).unwrap();

    // and then insert those types directly
    DB.insert(User {
        id: unassigned_id(),
        name: "asd",

    })
}

deploying

This is where iac-deploy comes in. You can embed this in any CLI you want. Our plan is to embed this into Dioxus via the dx cli.

iac-deploy swallows up all the metadata and builds a run-plan for you automatically.

ideas

  • so far we've demonstrated rust -> tf but in theory we could go the otherway to allow tf -> rust and bidrectional syncing so you can plug into existing infra.

security

well, don't ship your infra to the frontend, obviously. the iac-macros crate will eliminate all variables on wasm32 unless you specify via cfg flags/features/env vars that you absolutely do want them embedded. You might want this if you're experimenting with wasm-based runners, however IAC does not support any wasm-based drivers.

runtime declaration

Currently... we don't have the concept of choosing your runtime engine yet. We're considering doing this by letting you annotate various functions as a particular entrypoint.

For example, an EC2 instance could be setup with an attribute macro on main...

static APP: EC2 = EC2 {
    size: "t2-micro"
};

#[iac::runner(APP)]
#[tokio::main]
async fn main() {
    // do stuff
}

And say, an edge function could be setup using the "server_fn" attribute, similar to dioxus

#[server_fn]
async fn upload_photos() {

}

This approach would let you stitch together clusters with typesafety. I haven't really thought about going this far yet...

static CLUSTER: Cluster = Cluster! {
    proxy: WEST_VNET,
    services: [ KAFKA, REDIS, APP ]
}

that's all folks

join the dioxus discord and hop into #deploy if this seems like something you'd want to chat about

https://discord.gg/XgGxMSkvUM

You might also like...
Prototype of the `std::io::ensure!` family of macros

io-ensure Prototype of the `std::io::ensure` family of macros API Docs | Releases | Contributing Installation $ cargo add io-ensure Safety This crate

Write simple proc-macros inline with other source code.

script-macro An experimental way to write simple proc-macros inline with other source code. Did you ever end up getting frustrated at the boilerplate

Create Streamdeck Macros For Helldivers 2 Strategems!
Create Streamdeck Macros For Helldivers 2 Strategems!

Helldivers 2 Stratagem Macro Engine For Streamdeck This program contains macros for various stratagems to use. All macros are contained in the macro_e

Crate to generate files in ROFF format (Rust)

roffman A crate to generate roff man pages. Usage Add the following to the Cargo.toml: [dependencies] roffman = "0.3" Example use roffman::{Roff, Roff

Command-line tool to generate Rust code for Google Cloud Spanner

nene nene is a command-line tool to generate Rust code for Google Cloud Spanner. nene uses database schema to generate code by using Information Schem

Generate HTML source files from rust functions!

Htmlificator This crate provides an element struct which can be displayed as HTML. License This crate is licensed under the MIT license Credit This cr

Generate PHP code from Rust using a fluent API 🐘 🦀
Generate PHP code from Rust using a fluent API 🐘 🦀

PHP-Codegen Generate PHP code from Rust using a fluent API 🐘 🦀 Rust PHP Usage To bring this crate into your repository, either add php_codegen to yo

git-cliff can generate changelog files from the Git history by utilizing conventional commits as well as regex-powered custom parsers.⛰️
git-cliff can generate changelog files from the Git history by utilizing conventional commits as well as regex-powered custom parsers.⛰️

git-cliff can generate changelog files from the Git history by utilizing conventional commits as well as regex-powered custom parsers. The changelog template can be customized with a configuration file to match the desired format.

Small and simple CLI app to generate .editorconfig based on a given settings.

add-editorconfig Small and simple CLI app to generate .editorconfig based on a given settings. Usage # Will create an .editorconfig in the current dir

Owner
Jonathan Kelley
Creator @DioxusLabs
Jonathan Kelley
Js-macros - Quickly prototype Rust procedural macros using JavaScript or TypeScript!

js-macros Quickly prototype Rust procedural macros using JavaScript or TypeScript! Have you ever thought "this would be a great use case for a procedu

null 15 Jun 17, 2022
auto-rust is an experimental project that aims to automatically generate Rust code with LLM (Large Language Models) during compilation, utilizing procedural macros.

Auto Rust auto-rust is an experimental project that aims to automatically generate Rust code with LLM (Large Language Models) during compilation, util

Minsky 6 May 14, 2023
INput maCROs: program your keyboard/mouse

incro INput maCROs: program your keyboard/mouse See macro-template for macro example. Build it and place the resulting *.so file in macros/ directory

Mykolas Peteraitis 6 Nov 13, 2023
Generate QR code of your Wi-Fi network

ranpha Generate QR code of your Wi-Fi network. Usage: -p PROTOCOL -s SSID [-k KEY] [-f IMAGE_FORMAT] [-o OUT_DIR] [--size SIZE]

Yuki Okushi 6 Oct 25, 2022
Generate a vanity address (`juno1wynd...`) to show your support for WYND DAO

WYND Generator When you generate a new mnemonic, it is very random (must be to be secure), and you cannot predict the address you will get. However, i

null 9 Dec 8, 2022
Unwrap Macros to help Clean up code and improve production.

unwrap_helpers Unwrap Macros to help Clean up code and improve production. This does include a pub use of https://github.com/Mrp1Dev/loop_unwrap to ga

Ascending Creations 2 Nov 1, 2021
Simple console input macros with the goal of being implemented in the standard library.

Simple console input macros with the goal of being implemented in the standard library.

undersquire 2 Feb 10, 2022
Valq - macros for querying and extracting value from structured data by JavaScript-like syntax

valq   valq provides a macro for querying and extracting value from structured data in very concise manner, like the JavaScript syntax. Look & Feel: u

Takumi Fujiwara 24 Dec 21, 2022
Simple macros to write colored and formatted text to a terminal. Based on `termcolor`, thus also cross-platform.

Bunt: simple macro-based terminal colors and styles bunt offers macros to easily print colored and formatted text to a terminal. It is just a convenie

Lukas Kalbertodt 202 Dec 22, 2022
Croc-look is a tool to make testing and debuging proc macros easier

croc-look croc-look is a tool to make testing and debuging proc macros easier by these two features Printing the implementation specific generated cod

weegee 7 Dec 2, 2022