Code Monkey home page Code Monkey logo

terraform's Introduction

Terraform

Terraform is a small goal-oriented Ruby DSL for setting up a machine, similar in purpose to Chef and Puppet, but without the complexity. It's tailored for the kinds of tasks needed for deploying web apps and is designed to be refreshingly easy to understand and debug. You can read through the entire Terraform library in two minutes and know precisely what it will and won't do for you. Its design is inspired by Babushka.

Usage

This is the basic structure of a system provisioning script written using Terraform:

require "terraform_dsl"
include Terraform::DSL

dep "pygments" do
  met? { in_path? "pygmentize" }         # Check if your dependency is met.
  meet { shell "pip install pygments" }  # Install your dependency.
end

...

satisfy_dependencies()

The Terraform DSL provides these functions which are commonly used when provisioning systems to run web services:

shell(command) Executes a shell command. Use this generally instead of backticks. It raises an exception if the exit status of the command was nonzero, and prints the command string as well as the output.
in_path?(command) True if the command is in the current path.
package_installed?(package_name) True if a package is installed. Currently only apt-get is supported.
ensure_packages(*package_names) Ensures the given packages are installed via apt-get.
ensure_ppa(ppa_url) Ensures the given PPA (used on Ubuntu) is installed. "ppa_url" is of the form "ppa:user/name".
gem_installed?(name) True if the given Ruby gem is installed.
ensure_gem(name) Ensures the given Ruby gem is installed.
ensure_rbenv() Ensures rbenv is installed.
ensure_rbenv_ruby(ruby_version) Ensures the given version of Ruby is installed. `ruby_version` is an rbenv Ruby version string like "1.9.2.-p290".
ensure_run_once(dependency_name, block) Runs the given block once. Use for tasks that you're too lazy to write a proper `met?` block for, like running database migrations.
ensure_file(source_path, dest_path, on_change) Ensures the file at dest_path is the exact same as the file at source_path. Use this for copying configuration files (e.g. nginx.conf) to their proper locations.
fail_and_exit(message) Use when your meet() block encounters an error and cannot satisfy a dependency.

For further details, see the source. It's a short, well-documented file and there's no magic.

Installation

  1. Install the Terraform gem on your local machine (the machine you're deploying from): gem install terraform

  2. Write your system provisioning script using the Terraform DSL.

  3. Copy your system provisioning script and the Terraform library (which is a single file) to your remote machine and run it. Do this as part of your deploy script.

You can use the Terraform gem to write the Terraform library out to a single file as part of your deploy script, prior to copying it over to your remote machine:

require "terraform"
Terraform.write_dsl_file("/tmp/staging/my_app/terraform_dsl.rb")

Terraform is designed to be run on a barebones machine with little preinstalled software. The only requirement is that some version (any version) of Ruby is installed on the machine you're provisioning.

Examples

See the Terraform library itself, which makes use of the DSL quite a bit.

Barkeep is a code review system which uses Terraform for provisioning the machines it gets deployed to. You can see its system provisioning script written using Terraform here, and its Fezzik deploy script here.

Plugins

Terraform can be easily extended with custom deps distributed as gems or scripts. A library that defines new Terraform deps should call Terraform.add_plugin(__FILE__) in any file that adds to the Terraform DSL. For example, if you wanted to package a dep as a gem, the contents of your project might look like this:

terraform-yourgem/
`-lib/
  `-terraform/
    `-yourgem.rb

yourgem.rb
----------
require "terraform"

module Terraform
  module DSL
    # Define your deps
  end
end

Terraform.add_plugin(__FILE__)

Then in your application setup script you would write:

require "terraform"
require "terraform/yourgem"

Terraform.write_terraform_files("./terraform")

This will write out the core Terraform DSL plus all required plugins, ready to be required by your bootstrap code on the server.

For more complete example see terraform-rbenv, which reimplements Terraform's existing rbenv deps as a plugin.

Contribute

When developing this gem you can quickly preview and test your changes by loading your local copy of the gem in your project's Gemfile:

gem "terraform", :path => "~/path/to/terraform_checkout"

Credits

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.