Git Product home page Git Product logo

frey's Introduction

Frey

Build Status Join the chat at https://gitter.im/kvz/frey Support

Frey aims to be an all-in-one tool for developers and sysadmins to bring their app to production.

Warning: Frey is Alpha. Use it for new projects and goofing around, leave it for existing ones.

Table of Contents

Intro

Frey is a tool to set up infrastructure, and provision it with software and configuration. You can describe the server components, used software packages, and the deployment strategy for your own app, in a single Freyfile.

Frey combines the power of Terraform and the vast module ecosystem of Ansible to offer an end-to-end solution for setting up servers or entire clusters for your app.

Who uses Frey

Frey can be seen in the wild in these projects:

  • Uppy has a Freyfile that sets up an EC2 instance, and let's Travis CI deploy to it on every push to master.
  • Imagemagick has a Freyfile to set up their website from scratch. If anything 'bad' happens, frey is run to restore the infrastructure and software, as it was defined in the Freyfile.
  • tus.io has a Freyfile that sets up an EC2 instance, and let's Travis CI deploy to it on every push to master.

If you're using Frey, let us know in an issue.

Features

Frey can:

  • launch infra and operating systems (AWS, Google, Digital Ocean, etc)
  • install software packages (Nginx, MySQL, etc)
  • setup these packages
  • deploy your app (via Rsync, S3, Git pull, etc)
  • restart it (via Rsync, S3, Git pull, etc)

Frey will try to complete all of these steps, following along a 'chain of commands'. You're free to exclude commands, run a few, or just one. Chainable commands are indicated by :

screen shot 2016-03-16 at 22 01 55

As you can see, Frey additionally provides commands to:

  • backup
  • restore
  • connect to, or execute remote commands on your platform

Freyfile.toml

So how does Frey know what to do? All of the actions are orchestrated from a single source of truth, a declarative Freyfile.toml, written in TOML, and kept under the source control of your existing project. Preferably in its own directory, like ./infra.

Here's an example launching two web servers and a database server on Digital Ocean.

If you have a huge project and your Freyfile size is becoming an issue, Frey will happilly look for any other *.toml files in the same directory as you can see in this example where we set up a DynamoDB server on AWS using 4 different toml files.

Secrets

Frey prefers using environment variables for secrets such as the keys to your AWS account. Frey will automatically make any environment key that starts with FREY_ available to Terraform so you can use them directly as e.g.:

[infra.provider.aws]
  access_key = "${var.FREY_AWS_ACCESS_KEY}"
  secret_key = "${var.FREY_AWS_SECRET_KEY}"
  region     = "us-east-1"

In Ansible, you could use them like so:

[[install.playbooks.tasks]]
  name = "Showcase we can access FREY_ environment variables"
  command = "echo {{lookup('env', 'FREY_SHOULD_BE_AS_VAR_IN_ANSIBLE')}}"

It's good practice to put the keys needed for you app in an env.sh, and keep that out of Git.

Private keys

For setting up remote connections, Frey generates private and public SSH keys if they don't exist yet, and makes sure the created servers are accessible using those. If you set the magic FREY_ENCRYPTION_SECRET environment variable to a long random secret, Frey will also generate an encrypted version of your private SSH key so that you'd end up with three generated files:

./ssh/frey-myapp.pem
./ssh/frey-myapp.pem.cast5
./ssh/frey-myapp.pub

To change the directory Frey looks for SSH keys for you project from ~/.ssh, you can use the global.ssh.key_dir configuration value. That you can either set via --cfg-var or directly in your Freyfile:

[global.ssh]
  key_dir = "."

If frey-myapp.pem.cast5 exists as well as a FREY_ENCRYPTION_SECRET variable in the environment, Frey automatically reconstructs the frey-myapp.pem, and deletes it when the Frey process exits.

This allows you to for instance commit the encrypted private key to your Git repository, and ignore the .pem file, opening up the possibility of letting a semi-untrusted CI like Travis manage deploys for you. As an example, Travis could keep the encryption secret for you via:

gem install travis
travis encrypt --add env.global "FREY_ENCRYPTION_SECRET=${FREY_ENCRYPTION_SECRET}"

You could then set Travis to run frey deploy whenever there's non-PR push to the master branch. In .travis.yml add something like:

after_success:
  - if [ "${TRAVIS_PULL_REQUEST}" == "false" ] && [ "${TRAVIS_BRANCH}" == "master" ]; then frey deploy; else echo "Skipping deploy for non-master/prs"; fi

When frey starts, it will find the .cast5 file since that was committed to Git, it won't find the .pem file but it will recreate that with using the FREY_ENCRYPTION_SECRET, which was in turn encrypted by Travis.

Run

To run all the commands the belong to the chain (), just type frey

cd ~/code/myapp/infra
frey

This might not always be what you want.

You can step into the 'chain of commands' at any point. For so you'd type frey deploy, Frey would deploy your app, restart it, and show you the status.

You can also step out of the chain. If you only want a deploy without a restart, you can use --bail:

cd ~/code/myapp/infra
frey deploy --bail

You can also define a range, via --bail-after:

cd ~/code/myapp/infra
frey --bail-after plan

Making Frey execute all the steps, including plan, but then abort.

Configuration

The Freyfile and its *.toml siblings, along with environment variables for secrets, are the main way to configure infrastructure. Additionally, it may make sense to override configuration at runtime. This can be achieved via the --cfg-var command-line argument. For instance, your Freyfile could hold:

[infra.resource.digitalocean_droplet.myapp-web]
  image    = "ubuntu-14-04-x64"
  name     = "web-${count.index}"
  region   = "nyc2"
  size     = "512mb"
  ssh_keys = [ "${digitalocean_ssh_key.myapp-sshkey.id}" ]
  count    = "${var.web_count}"

Which could be overridden via:

frey --cfg-var="infra.resource.digitalocean_droplet.myapp-web.count=10"

Supply multiple --cfg-var arguments if you want to override multiple configuration values.

Alternatively you could use use a simple templating language that Frey provides to reference to values inside your Freyfile. In this example we reference to Frey-provided ssh keys. Notice that we prefix with config. here, as you can also use magic prefixes such as self. and parent..

[infra.resource.digitalocean_droplet.myapp-web.connection]
   key_file = "{{{config.global.ssh.privatekey_file}}}"
   user     = "{{{config.global.ssh.user}}}"

The full list of config variables that you can reference is constituted by what's in your Freyfile, as well as a few defaults that Frey provides for convenience, which are listed here.

Install

Frey would like to be installed globally for convenience:

npm install --global frey

But it will then choose a locally installed version if you have it available. This is great to pin a Frey version to an infra project. This way, you will know nothing that works now, can break in the future. So in addition to the global install, we recommend a local install in your project with exact version pinning:

cd ~/code/myapp
npm install --save --exact frey

A fixed version of Frey, installs fixed local versions of its dependencies (such as Ansible and Terraform) in local directories as well, all to keep chances of conflict slim, and chances of things working five years from now, optimal. More on this later.

Design goals

  • Frey should be ridiculously convenient, and hence offer auto-installation of requirements for instance
  • Version pinning is holy
  • An abundance of automated acceptance tests, that verify actual setting up and tearing down of infrastructure
  • Written in ES6 JavaScript, transpiling builds to ES5

Changelog

The changelog and todo list and can be found here

Todo

The changelog and todo list and can be found here

FAQ

The FAQ can be found here

Comparison

Comparison with Terraform

Terraform is our opinion the best infrastructure automation tool, but without Ansible / Chef / Puppet, it's mostly relying on shell scripts to set up servers. Hashicorp has many other tools to compensate, most noteworthy Otto, for which there is a separate comparison.

Comparison with Ansible / Chef / Puppet

While it's true that some of these tools can launch infrastructure, they're not the right tool it. The main reason is that while they're okay-ish at managing state on a server, they weren't built to manage state 'outside' of it, what Terraform really shines in.

Comparison with Otto

Seeing as Otto uses Terraform for infra orchestration and also installs software on it, there's a big conceptual overlap.

Where the projects differ is that Otto aims to be zero config, and Frey aims to be minimal yet complete config. Every component needs to be described, and saved under Git. This approach provides more control and flexibility at the tradeoff of it being more work to describe all your pieces. Wether this trade-off is acceptable depends on the project.

Frey does not offer setting up local environments yet, but this should be easy enough to add (as we can make local connections already) and is on the roadmap.

Contributors

  • Kevin van Zonneveld (@kvz)

License

MIT

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.