/simple_provision

Simplest way to provision your server. Support bash, ruby and python and nodejs.

Primary LanguageRubyMIT LicenseMIT

Introduction

This is based on the work that brandonhilkert initally carried to automate EC2 instance provision with YAML and SHELL script. It tries to bring the good spirit: SIMPLE, and JUST WORK to the world of every remote machine.

I used to use this to do all the provision of Redis, Postgres, Nginx, Unicorn, Cron, etc before. These days I just use this to provision docker on the server and then use crane to orchestrate the rest.

Let's rock.

Recipes repo

Don't forget to also checkout the recipes collection https://github.com/phuongnd08/simple_provision_recipes

How it works

This gem carries the provision by uploading a set of scripts and files to the server and execute there.

It's up to you to choose the language you want. I often use a mix of SHELL and RUBY scripts to accomplish the task. SHELL for some simple stuff like install a package on the server and RUBY when I need to complete some tricky part of the configuration.

Just remember that you need to use a shell script to install ruby/python first, and then you can start use ruby/python. The install of ruby and python can be as simple as create a bash contains "yum install ruby(python) -y" and include it in the top of the scripts section in your server definition file.

Installation

Add this line to your application's Gemfile:

gem 'simple_provision'

And then execute:

$ bundle

Or install it yourself as:

$ gem install simple_provision

Project Structure

The provision profile need to be defined inside /provision directory. Since it's just scripting, feel free to use ERB, HAML, or any kind of templates that you want, assume you install the necessary library before you do that.

./provision
├── files
│   ├── keys
│   │   └── deploy_key
│   └── rails_config
│       └── database.yml
├── scripts
│   ├── apt.sh
│   ├── deploy_key.sh
│   ├── git.sh
│   ├── redis.rb
│   ├── ruby2.sh
│   ├── rubygems.sh
│   ├── install_tornado.py
│   ├── search_service_code.sh
│   └── search_service_env.sh
└── servers
    ├── webapp.yml
    ├── docker.yml
    └── search-service.yml

In /provision/servers/{webapp, docker, search-service}.yml, you define your server defintion (read below).

Server Definition

To define a server type, create a yaml file in the ./provision/servers directory with the following format:

files:
  - files/credentials.yml
scripts:
  - scripts/git.sh
  - scripts/ruby.sh
  - scripts/rubygems.sh
  - scripts/redis.sh
env:
  DBNAME: my_db_name
  REDISNAME: <%= ENV["REDIS_NAME"] %>
  WEBROOT: /var/www/app

File declared in files and scripts can point to anywhere in the machine from which you make the provision. The file path is calculated relative to ./provision directory. These files/scripts will then be uploaded to provisioned server at ~/files and ~/scripts

Passing variables to scripts

Variables defined in env will be exposed to scripts during execution. That way you can re-use the same scripts for different type of servers. You can pass environment variables (available through the use of bash export ENVNAME=value or passing to simpro command such as ENVNAME=value simpro) to the env section using the ERB syntax (<%= ENV['ENVNAME'] %>).

Provision your server

bundle exec simpro my-awesome-server root@my-host

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request