{"id":13875983,"url":"https://github.com/jonhoo/tsunami","last_synced_at":"2025-07-16T10:32:14.981Z","repository":{"id":46209235,"uuid":"121051602","full_name":"jonhoo/tsunami","owner":"jonhoo","description":"Rust crate for running one-off cloud jobs","archived":true,"fork":false,"pushed_at":"2021-11-06T19:03:19.000Z","size":300,"stargazers_count":153,"open_issues_count":6,"forks_count":22,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-11-16T16:18:17.936Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jonhoo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-02-10T20:29:51.000Z","updated_at":"2024-11-02T08:24:57.000Z","dependencies_parsed_at":"2022-09-08T06:10:43.457Z","dependency_job_id":null,"html_url":"https://github.com/jonhoo/tsunami","commit_stats":null,"previous_names":[],"tags_count":35,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonhoo%2Ftsunami","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonhoo%2Ftsunami/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonhoo%2Ftsunami/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonhoo%2Ftsunami/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jonhoo","download_url":"https://codeload.github.com/jonhoo/tsunami/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226122303,"owners_count":17576920,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-06T06:00:53.970Z","updated_at":"2024-11-24T03:31:36.168Z","avatar_url":"https://github.com/jonhoo.png","language":"Rust","funding_links":[],"categories":["Rust","others"],"sub_categories":[],"readme":"**This project has been deprecated as I no longer use it myself, and\nbetter (and maintained) alternatives exist like\n[Terraform](https://www.terraform.io/). If you'd like to revive the\nproject, please reach out!**\n\n# tsunami\n\n[![Crates.io](https://img.shields.io/crates/v/tsunami.svg)](https://crates.io/crates/tsunami)\n[![Documentation](https://docs.rs/tsunami/badge.svg)](https://docs.rs/tsunami/)\n[![Build Status](https://dev.azure.com/jonhoo/jonhoo/_apis/build/status/tsunami?branchName=master)](https://dev.azure.com/jonhoo/jonhoo/_build/latest?definitionId=25\u0026branchName=master)\n\n`tsunami` provides an interface for running one-off jobs on cloud instances.\n\nImagine you need to run an experiment that involves four machines of different types on AWS. Or\non Azure. And each one needs to be set up in a particular way. Maybe one is a server, two are\nload generating clients, and one is a monitor of some sort. You want to spin them all up with a\ncustom AMI, in different regions, and then run some benchmarks once they're all up and running.\n\nThis crate makes that trivial.\n\nYou say what machines you want, and the library takes care of the rest. It uses the cloud\nservice's API to start the machines as appropriate, and gives you [ssh connections] to each\nhost as it becomes available to run setup. When all the machines are available, you can connect\nto them all in a single step, and then run your distributed job. When you're done, `tsunami`\ntears everything down for you. And did I mention it even supports AWS spot instances, so it\neven saves you money?\n\nHow does this magic work? Take a look at this example:\n\n```rust\nuse azure::Region as AzureRegion;\nuse rusoto_core::{credential::DefaultCredentialsProvider, Region as AWSRegion};\nuse tsunami::Tsunami;\nuse tsunami::providers::{aws, azure};\n#[tokio::main]\nasync fn main() -\u003e Result\u003c(), color_eyre::Report\u003e {\n    // Initialize AWS\n    let mut aws = aws::Launcher::default();\n    // Create an AWS machine descriptor and add it to the AWS Tsunami\n    aws.spawn(\n        vec![(\n            String::from(\"aws_vm\"),\n            aws::Setup::default()\n                .region_with_ubuntu_ami(AWSRegion::UsWest1) // default is UsEast1\n                .await\n                .unwrap()\n                .setup(|vm| {\n                    // default is a no-op\n                    Box::pin(async move {\n                        vm.ssh.command(\"sudo\")\n                            .arg(\"apt\")\n                            .arg(\"update\")\n                            .status()\n                            .await?;\n                        vm.ssh.command(\"bash\")\n                            .arg(\"-c\")\n                            .arg(\"\\\"curl https://sh.rustup.rs -sSf | sh -- -y\\\"\")\n                            .status()\n                            .await?;\n                        Ok(())\n                    })\n                }),\n        )],\n        None,\n    )\n    .await?;\n\n    // Initialize Azure\n    let mut azure = azure::Launcher::default();\n    // Create an Azure machine descriptor and add it to the Azure Tsunami\n    azure\n        .spawn(\n            vec![(\n                String::from(\"azure_vm\"),\n                azure::Setup::default()\n                    .region(AzureRegion::FranceCentral) // default is EastUs\n                    .setup(|vm| {\n                        // default is a no-op\n                        Box::pin(async move {\n                            vm.ssh.command(\"sudo\")\n                                .arg(\"apt\")\n                                .arg(\"update\")\n                                .status()\n                                .await?;\n                            vm.ssh.command(\"bash\")\n                                .arg(\"-c\")\n                                .arg(\"\\\"curl https://sh.rustup.rs -sSf | sh -- -y\\\"\")\n                                .status()\n                                .await?;\n                            Ok(())\n                        })\n                    }),\n            )],\n            None,\n        )\n        .await?;\n\n    // SSH to the VMs and run commands on it\n    let aws_vms = aws.connect_all().await?;\n    let azure_vms = azure.connect_all().await?;\n\n    let vms = aws_vms.into_iter().chain(azure_vms.into_iter());\n\n    // do amazing things with the VMs!\n    // you have access to things like ip addresses for each host too.\n\n    // call terminate_all() to terminate the instances.\n    aws.terminate_all().await?;\n    azure.terminate_all().await?;\n    Ok(())\n}\n```\n\n## Live-coding\n\nAn earlier version of this crate was written as part of a live-coding stream series intended\nfor users who are already somewhat familiar with Rust, and who want to see something larger and\nmore involved be built. You can find the recordings of past sessions [on\nYouTube](https://www.youtube.com/playlist?list=PLqbS7AVVErFgY2faCIYjJZv_RluGkTlKt).\n\n## License\n\nLicensed under either of\n\n * Apache License, Version 2.0\n   ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)\n * MIT license\n   ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)\n\nat your option.\n\n## Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall be\ndual licensed as above, without any additional terms or conditions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonhoo%2Ftsunami","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjonhoo%2Ftsunami","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonhoo%2Ftsunami/lists"}