davideisinger.com

My personal website
Log | Files | Refs | README

index.md (4728B)


      1 ---
      2 title: "AWS OpsWorks: Lessons Learned"
      3 date: 2013-10-04T00:00:00+00:00
      4 draft: false
      5 canonical_url: https://www.viget.com/articles/aws-opsworks-lessons-learned/
      6 references:
      7 - title: "Introduction to AWS OpsWorks - Artsy Engineering"
      8   url: https://artsy.github.io/blog/2013/08/27/introduction-to-aws-opsworks/
      9   date: 2024-11-21T15:35:22Z
     10   file: artsy-github-io-sroaub.txt
     11 ---
     12 
     13 We've been using Amazon's [AWS
     14 OpsWorks](http://aws.amazon.com/opsworks/) to manage our infrastructure
     15 on a recent client project. The website describes OpsWorks as
     16 
     17 > a DevOps solution for managing applications of any scale or complexity
     18 > on the AWS cloud.
     19 
     20 You can think of it as a middle ground between something like Heroku and
     21 a manually configured server environment. You can also think of it as
     22 [Chef](http://www.opscode.com/chef/)-as-a-service. Before reading on,
     23 I'd recommend reading this [Introduction to AWS
     24 OpsWorks](http://artsy.github.io/blog/2013/08/27/introduction-to-aws-opsworks/),
     25 a post I wish had existed when I was first diving into this stuff. With
     26 that out of the way, here are a few lessons I had to learn the hard way
     27 so hopefully you won't have to.
     28 
     29 ### You'll need to learn Chef
     30 
     31 The basis of OpsWorks is [Chef](http://www.opscode.com/chef/), and if
     32 you want to do anything interesting with your instances, you're going to
     33 have to dive in, fork the [OpsWorks
     34 cookbooks](https://github.com/aws/opsworks-cookbooks), and start adding
     35 your own recipes. Suppose, like we did, you want to add
     36 [PDFtk](http://www.pdflabs.com/tools/pdftk-the-pdf-toolkit/) to your
     37 servers to merge some documents:
     38 
     39 1.  Check the [OpsCode
     40     Community](http://community.opscode.com/cookbooks) site for a
     41     recipe.
     42 2.  [A recipe exists.](http://community.opscode.com/cookbooks/pdftk) You
     43     lucky dog.
     44 3.  Add the recipe to your fork, push it up, and run it.
     45 4.  It fails. Turns out they renamed the `gcj` package to `gcj-jdk`.
     46     Fix.
     47 5.  It fails again. The recipe is referencing an old version of PDFtk.
     48     Fix.
     49 6.  Great success.
     50 
     51 A little bit tedious compared with `wget/tar/make`, for sure, but once
     52 you get it configured properly, you can spin up new servers at will and
     53 be confident that they include all the necessary software.
     54 
     55 ### Deploy hooks: learn them, love them
     56 
     57 Chef offers a number of [deploy
     58 callbacks](http://docs.opscode.com/resource_deploy.html#callbacks) you
     59 can use as a stand-in for Capistrano's `before`/`after` hooks. To use
     60 them, create a directory in your app called `deploy` and add files named
     61 for the appropriate callbacks (e.g. `deploy/before_migrate.rb`). For
     62 example, here's how we precompile assets before migration:
     63 
     64 ```ruby
     65 rails_env = new_resource.environment["RAILS_ENV"]
     66 
     67 Chef::Log.info("Precompiling assets for RAILS_ENV=#{rails_env}...")
     68 
     69 execute "rake assets:precompile" do
     70   cwd release_path
     71   command "bundle exec rake assets:precompile"
     72   environment "RAILS_ENV" => rails_env
     73 end
     74 ```
     75 
     76 ### Layers: roles, but not *dedicated* roles
     77 
     78 AWS documentation describes
     79 [layers](http://docs.aws.amazon.com/opsworks/latest/userguide/workinglayers.html)
     80 as
     81 
     82 > how to set up and configure a set of instances and related resources
     83 > such as volumes and Elastic IP addresses.
     84 
     85 The default layer types ("PHP App Server", "MySQL") imply that layers
     86 distinguish separate components of your infrastructure. While that's
     87 partially true, it's better to think about layers as the *roles* your
     88 EC2 instances fill. For example, you might have two instances in your
     89 "Rails App Server" role, a single, separate instance for your "Resque"
     90 role, and one of the two app servers in the "Cron" role, responsible for
     91 sending nightly emails.
     92 
     93 ### Altering the Rails environment
     94 
     95 If you need to manually execute a custom recipe against your existing
     96 instances, the Rails environment is going to be set to "production" no
     97 matter what you've defined in the application configuration. In order to
     98 change this value, add the following to the "Custom Chef JSON" field:
     99 
    100 ```json
    101 {
    102   "deploy": {
    103     "app_name": {
    104       "rails_env": "staging"
    105     }
    106   }
    107 }
    108 ```
    109 
    110 (Substituting in your own application and environment names.)
    111 
    112 ------------------------------------------------------------------------
    113 
    114 We've found OpsWorks to be a solid choice for repeatable, maintainable
    115 server infrastructure that still offers the root access we all crave.
    116 Certainly, it's slower out of the gate than spinning up a new Heroku app
    117 or logging into a VPS and `apt-get`ting it up, but the investment up
    118 front leads to a more sustainable system over time. If this sounds at
    119 all interesting to you, seriously go check out that [introduction
    120 post](http://artsy.github.io/blog/2013/08/27/introduction-to-aws-opsworks/).
    121 It's the post this post wishes it was.