{"id":13395093,"url":"https://github.com/kenn/sunzi","last_synced_at":"2025-12-24T09:57:28.475Z","repository":{"id":2563189,"uuid":"3542516","full_name":"kenn/sunzi","owner":"kenn","description":"Sunzi: Server configuration automation for minimalists","archived":false,"fork":false,"pushed_at":"2022-02-25T12:13:08.000Z","size":152,"stargazers_count":447,"open_issues_count":2,"forks_count":35,"subscribers_count":16,"default_branch":"master","last_synced_at":"2024-10-01T07:15:07.693Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://rubygems.org/gems/sunzi","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kenn.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-02-25T04:52:40.000Z","updated_at":"2024-03-28T03:14:05.000Z","dependencies_parsed_at":"2022-08-29T02:41:36.431Z","dependency_job_id":null,"html_url":"https://github.com/kenn/sunzi","commit_stats":null,"previous_names":[],"tags_count":28,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kenn%2Fsunzi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kenn%2Fsunzi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kenn%2Fsunzi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kenn%2Fsunzi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kenn","download_url":"https://codeload.github.com/kenn/sunzi/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243478284,"owners_count":20297228,"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-07-30T17:01:41.821Z","updated_at":"2025-12-24T09:57:28.411Z","avatar_url":"https://github.com/kenn.png","language":"Ruby","readme":"Sunzi\n=====\n\n[![Build Status](https://secure.travis-ci.org/kenn/sunzi.png)](http://travis-ci.org/kenn/sunzi)\n\n```\n\"The supreme art of war is to subdue the enemy without fighting.\" - Sunzi\n```\n\nSunzi is the easiest configuration automation and [infrastructure as code](https://en.wikipedia.org/wiki/Infrastructure_as_Code) utility designed for mere mortals.\n\nIf Chef, Puppet, Ansible or SaltStack is driving you nuts, try Sunzi!\n\nSunzi assumes that modern Linux distributions have (mostly) sane defaults and great package managers.\n\nIts design goals are:\n\n* **It's just shell script.** No clunky Ruby DSL involved. Most of the information about server configuration on the web is written in shell commands. Just copy-paste them, rather than translate it into an arbitrary DSL. Also, Bash is the greatest common denominator on minimum Linux installs.\n\n* **Minimal diff from default.** No big-bang overwriting. Append or replace the smallest possible piece of data in a config file. Loads of custom configurations make it difficult to reason what you are really doing.\n\n* **Minimum dependencies.** No configuration server required. You don't even need a Ruby runtime on the remote server, sunzi runs a combined shell script over SSH.\n\nSee also:\n\n* [sunzi-vps](https://github.com/kenn/sunzi-vps) - Interactive server provisioning plugin for Linode and DigitalOcean.\n* [sunzi-recipes](https://github.com/kenn/sunzi-recipes) - Sample repository for remote recipes.\n\n### What's new:\n\nPlease see the [CHANGELOG](https://github.com/kenn/sunzi/blob/master/CHANGELOG.md).\n\nQuickstart\n----------\n\nInstall:\n\n```bash\n$ gem install sunzi\n```\n\nGo into your project directory (if it's a Rails project, `config` would be a good place to start with), then:\n\n```bash\n$ sunzi create\n```\n\nIt generates a `sunzi` folder along with subdirectories and templates. Inside `sunzi`, there are `sunzi.yml` and `install.sh`. Those two are the most important files that you mainly work on.\n\nGo into the `sunzi` directory, then run `sunzi deploy`:\n\n```bash\n$ cd sunzi\n$ sunzi deploy example.com\n```\n\nNow, what it actually does is:\n\n1. Compile `sunzi.yml` to generate variables and retrieve remote recipes, then copy files into the `compiled` directory\n1. SSH to `example.com` and login as `root`\n1. Transfer the content of the `compiled` directory to the remote server and extract in `$HOME/sunzi`\n1. Run `install.sh` on the remote server\n\nAs you can see, all you need to do is edit `install.sh` and add some shell commands. That's it.\n\nA Sunzi project without any recipes or roles is totally fine, so that you can start small, go big as you get along.\n\nCommands\n--------\n\n```bash\n$ sunzi                                           # Show command help\n$ sunzi create                                    # Create a new Sunzi project\n$ sunzi deploy [user@host:port] [role] [--sudo]   # Deploy Sunzi project\n```\n\nDirectory structure\n-------------------\n\nHere's the directory structure that `sunzi create` automatically generates:\n\n```bash\nsunzi/\n  install.sh      # main script\n  sunzi.yml       # add custom variables and remote recipes here\n\n  recipes/        # put commonly used scripts here, referred from install.sh\n    sunzi.sh\n  roles/          # when role is specified, scripts here will be concatenated\n    db.sh         # to install.sh in the compile phase\n    web.sh\n  files/          # put any files to be transferred\n\n  compiled/       # everything under this folder will be transferred to the\n                  # remote server (do not edit directly)\n```\n\nHow do you pass dynamic values?\n-------------------------------\n\nIn the compile phase, variables defined in `sunzi.yml` are accessible from any files in the form of `\u003c%= @vars.ruby_version %\u003e`\n\nFor instance, given the following `install.sh`:\n\n```bash\necho \"Goodbye \u003c%= @vars.goodbye %\u003e, Hello \u003c%= @vars.hello %\u003e!\"\n```\n\nWith `sunzi.yml`:\n\n```yaml\nvars:\n  goodbye: Chef\n  hello: Sunzi\n```\n\nNow, you get the following result.\n\n```\nGoodbye Chef, Hello Sunzi!\n```\n\nRemote Recipes\n--------------\n\nRecipes can be retrieved remotely via HTTP. Put a URL in the recipes section of `sunzi.yml`, and Sunzi will automatically load the content and put it into the `compiled/recipes` folder in the compile phase.\n\nFor instance, if you have the following line in `sunzi.yml`,\n\n```yaml\nrecipes:\n  rvm: https://raw.githubusercontent.com/kenn/sunzi-recipes/master/ruby/rvm.sh\n```\n\n`rvm.sh` will be available and you can refer to that recipe by `source recipes/rvm.sh`.\n\nYou may find sample recipes in this repository useful: https://github.com/kenn/sunzi-recipes\n\nRole-based configuration\n------------------------\n\nYou probably have different configurations between **web servers** and **database servers**.\n\nNo problem - how Sunzi handles role-based configuration is refreshingly simple.\n\nShell scripts under the `roles` directory, such as `web.sh` or `db.sh`, are automatically recognized as a role. The role script will be appended to `install.sh` at deploy, so you should put common configurations in `install.sh` and role specific procedures in the role script.\n\nFor instance, when you set up a new web server, deploy with a role name:\n\n```bash\nsunzi deploy example.com web\n```\n\nIt is equivalent to running `install.sh`, followed by `web.sh`.\n\nVagrant\n-------\n\nIf you're using Sunzi with [Vagrant](http://vagrantup.com/), make sure that you have a root access via SSH.\n\nAn easy way is to edit `Vagrantfile`:\n\n```ruby\nVagrant.configure(\"2\") do |config|\n  config.vm.provision \"shell\",\n    inline: \"sudo echo 'root:vagrant' | /usr/sbin/chpasswd\"\n  end\nend\n```\n\nand now run `vagrant up`, it will change the root password to `vagrant`.\n\nAlso keep in mind that you need to specify the port number 2222.\n\n```bash\n$ sunzi deploy localhost:2222\n```\n\nDemonstration Videos\n-------\n\nYou can watch video on how to deploy a Rails 4.1 app with Sunzi and Capistrano 3 at http://youtu.be/3mwupXqtkmg\n","funding_links":[],"categories":["Ruby","DevOps Tools"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkenn%2Fsunzi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkenn%2Fsunzi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkenn%2Fsunzi/lists"}