| Crates.io | ansible-rs |
| lib.rs | ansible-rs |
| version | 1.1.0 |
| created_at | 2025-07-12 13:30:44.812036+00 |
| updated_at | 2025-07-12 13:30:44.812036+00 |
| description | A Rust wrapper library for Ansible command-line tools (Linux/Unix only) |
| homepage | |
| repository | https://github.com/yourusername/ansible-rs |
| max_upload_size | |
| id | 1749291 |
| size | 595,046 |
A modern Rust wrapper library for Ansible command-line tools, built with Rust 2024 edition.
Add this to your Cargo.toml:
[dependencies]
ansible = "1.0.0"
# For async support
ansible = { version = "1.0.0", features = ["async"] }
use ansible::{Ansible, Module, Result};
fn main() -> Result<()> {
let mut ansible = Ansible::default();
ansible
.set_system_envs()
.add_host("all")
.set_inventory("./hosts");
// Execute a ping
let result = ansible.ping()?;
println!("Ping result: {}", result);
// Execute a shell command
let result = ansible.shell("uptime")?;
println!("Uptime: {}", result);
Ok(())
}
use ansible::{AsyncAnsible, Module};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut ansible = AsyncAnsible::new();
ansible
.set_system_envs()
.add_host("all")
.set_inventory("./hosts");
// Execute a ping asynchronously
let result = ansible.ping().await?;
println!("Ping result: {}", result);
// Execute a shell command asynchronously
let result = ansible.shell("uptime").await?;
println!("Uptime: {}", result);
Ok(())
}
use ansible::AsyncAnsible;
use tokio::try_join;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut ansible1 = AsyncAnsible::new();
ansible1.add_host("web-servers");
let mut ansible2 = AsyncAnsible::new();
ansible2.add_host("db-servers");
// Run commands concurrently
let (web_result, db_result) = try_join!(
ansible1.ping(),
ansible2.ping()
)?;
println!("Web servers: {}", web_result);
println!("DB servers: {}", db_result);
Ok(())
}
use ansible::{Playbook, Play, Result};
fn main() -> Result<()> {
let mut playbook = Playbook::default();
playbook.set_inventory("./hosts");
// Run from file
let result = playbook.run(Play::from_file("site.yml"))?;
// Run from string content
let yaml_content = r#"
---
- hosts: all
tasks:
- name: Hello World
debug:
msg: "Hello from Rust!"
"#;
let result = playbook.run(Play::from_content(yaml_content))?;
Ok(())
}
use ansible::{AsyncPlaybook, AsyncPlay};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut playbook = AsyncPlaybook::new();
playbook.set_inventory("./hosts");
// Run from file asynchronously
let result = playbook.run(AsyncPlay::from_file("site.yml")).await?;
// Run from string content asynchronously
let yaml_content = r#"
---
- hosts: all
tasks:
- name: Hello World
debug:
msg: "Hello from async Rust!"
"#;
let result = playbook.run(AsyncPlay::from_content(yaml_content)).await?;
Ok(())
}
use ansible::{Ansible, IntoAsync};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create a synchronous instance
let sync_ansible = Ansible::default();
// Convert to async
let async_ansible = sync_ansible.into_async();
// Use async methods
let result = async_ansible.ping().await?;
println!("Result: {}", result);
Ok(())
}
Add the async feature to your Cargo.toml:
[dependencies]
ansible = { version = "1.0.0", features = ["async"] }
tokio = { version = "1.0", features = ["full"] }
Run the async demo:
cargo run --example async_demo --features async
Run async tests:
cargo test --features async test_async
This project includes a Docker-based testing environment with multiple target systems.
Install cargo-nextest:
cargo install cargo-nextest
Run tests with nextest:
# Quick tests
cargo nextest run --profile quick
# Full test suite
cargo nextest run --all-features
# CI profile tests
cargo nextest run --profile ci
# Use our test script
./scripts/test-nextest.sh all
./test-docker.sh
# Start containers
docker-compose up -d
# Run examples
cargo run --example ansible
cargo run --example playbook
# Clean up
docker-compose down
The test environment includes:
All containers are configured with:
let mut ansible = Ansible::default();
// Configuration
ansible.set_system_envs() // Use system environment
.filter_envs(["HOME", "PATH"]) // Filter specific env vars
.add_host("web-servers") // Add target hosts
.set_inventory("./hosts") // Set inventory file
.arg("-v"); // Add custom arguments
// Execute modules
ansible.ping()?; // Ping module
ansible.setup()?; // Setup/facts module
ansible.shell("ls -la")?; // Shell module
ansible.command("uptime")?; // Command module
ansible.script("./script.sh")?; // Script module
// Custom modules
let module = Module::other("package", "name=nginx state=present");
ansible.run(module)?;
let mut playbook = Playbook::default();
// Configuration
playbook.set_inventory("./hosts")
.set_output_json() // JSON output format
.arg("--check"); // Dry run mode
// Execute playbooks
playbook.run(Play::from_file("site.yml"))?;
playbook.run(Play::from_content(yaml_string))?;
The library provides comprehensive error types:
use ansible::{AnsibleError, Result};
match ansible.ping() {
Ok(result) => println!("Success: {}", result),
Err(AnsibleError::CommandFailed { message, exit_code, stdout, stderr }) => {
eprintln!("Command failed: {}", message);
eprintln!("Exit code: {:?}", exit_code);
eprintln!("Stdout: {:?}", stdout);
eprintln!("Stderr: {:?}", stderr);
},
Err(AnsibleError::InvalidInventory(msg)) => {
eprintln!("Inventory error: {}", msg);
},
Err(e) => eprintln!("Other error: {}", e),
}
This project is licensed under the AGPL-3.0 License - see the LICENSE file for details.