Skip to content

Instantly share code, notes, and snippets.

@halilim
Last active December 23, 2016 09:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save halilim/00252f45aa1d4f16a62a to your computer and use it in GitHub Desktop.
Save halilim/00252f45aa1d4f16a62a to your computer and use it in GitHub Desktop.
"Actually" getting Amazon Elastic Beanstalk to work for a Rails 4 application with 12 Factor and Heroku compatibility

Last Status

  • 2015-11-10: Abandoned AWS EB.

    Got Create environment operation is complete, but with errors. For more information, see troubleshooting documentation..

    Tried to set up CloudWatch Logs but got The following resource(s) failed to create: [AWSEBCWLHttp4xxMetricFilter, AWSEBCWLHttp5xxMetricFilter].

Notes

  1. Modify region name (eu-central-1), app name (your_app) etc according to your requirements.

Preparation

  1. If your Gemfile includes Git sources add Git to packages since it's not included in the default EB AMI.

    # .ebextensions/packages.config
    packages:
      yum:
        git: []
  2. EB doesn't automatically create and populate config/database.yml. Unignore and modify it (assuming you are using Figaro):

    # config/database.yml
    development: &dev
      adapter:  postgresql
      host:     <%= ENV["POSTGRES_HOST"] %>
      encoding: unicode
      database: <%= ENV["POSTGRES_DB"] %>
      pool:     5
      username: <%= ENV["POSTGRES_USER"] %>
      password: <%= ENV["POSTGRES_PASSWORD"] %>
      template: template0
    
    test:
      <<: *dev
      database: your_app_test
    
    production:
      <<: *dev
      database: your_app_production
    # config/application.yml
    # This must be ignored and used only for local dev. We'll set these at the post-config stage
    # using EB CLI like:
    # `eb setenv POSTGRES_HOST=... POSTGRES_DB=... POSTGRES_USER=... POSTGRES_PASSWORD='...'`
    # or through the web interface.
    POSTGRES_HOST: <etc>.<etc>.eu-central-1.rds.amazonaws.com
    POSTGRES_DB: your_app_production
    POSTGRES_USER: <RDS user>
    POSTGRES_PASSWORD: <RDS password>
  3. Create a RDS Instance

    RDS > Get Started Now

    1. Select Engine > PostgreSQL
    2. Production? > Multi-AZ strongly recommended
    3. Specify DB Details
      • DB Engine Version: Latest
      • Storage Type: One of the SSD options
      • Allocated Storage*: > 20 GB
    4. Optional Steps #1
  4. Add your SSH key (EC2 > Key Pairs > Import Key Pair)

  5. (Optional) Set up memory reporting

  6. (Optional) set up CloudWatch Logs

Create Your EB Stack

  1. Create New Environment > Create web server

  2. Environment Type

    • Predefined configuration > Ruby
    • Change platform version > Select Puma
  3. Additional Resources

    • Don't select "Create an RDS DB Instance with this environment", since some RDS options can't be modified from here. An example is Storage Type, which defaults to magnetic and modifying it later to SSD incurs IO and CPU penalties. We'll create the RDS instance separately and enter its credentials as environment variables.
  4. Configuration Details

    • EC2 key pair: Select the SSH key you've uploaded at Preparation step 3.
    • Email address: Enter your email address
    • Root volume type: General Purpose (SSD)

Later Configuration

  1. Enter appropriate values from your config/application.yml of Preparation step 2 including db credentials at Web Tier > Software Configuration > Environment Properties or using EB CLI.

  2. Allow your EC2 instances to connect to your RDS instance:

    1. VPC Console > Security Groups > Create Security Group

      • Name tag:
      • Group name: db
      • Description: db
      • VPC: Select the same VPC instance as your EC2 instances.
      • Type: PostgreSQL (5432)
      • Source: Select the Security Group of your EC2 instances.
    2. RDS > Modify > Security Group > Select the one you've just created above.

Optional Steps

  1. If you want to change the collation of your db (en_US.UTF-8 by default):

    1. SSH into one of your instances (eb ssh)

    2. Connect to your RDS instance:

      psql -h etc.etc.eu-central-1.rds.amazonaws.com -U user -d db
    3. Create a new database:

      CREATE DATABASE your_app_production TEMPLATE template0 ENCODING 'UTF-8' LC_COLLATE 'tr_TR.UTF-8' LC_CTYPE 'tr_TR.UTF-8';

Test Your Deployment

eb deploy

Last Steps

  1. We are doing this after all other steps because modifying more than 1 instance takes a lot longer than a single instance.

    Configuration > Web Tier > Scaling > Auto Scaling

    • Minimum instance count: Increase to at least 2 for HA.
    • Maximum instance count: Increase according to your expected traffic level (along with min. count).
@sgarbesi
Copy link

@halilim Tried to set up CloudWatch Logs but got The following resource(s) failed to create: [AWSEBCWLHttp4xxMetricFilter, AWSEBCWLHttp5xxMetricFilter]. You can resolve this by changing your policy to:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "autoscaling:Describe*",
        "cloudwatch:*",
        "logs:*",
        "sns:*"
      ],
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}

I'm sure there's a much stricter policy that will do the job, but I'm no expert with this and the documentation is scarce on the topic. Hope this helped.

@halilim
Copy link
Author

halilim commented Jan 27, 2016

@sgarbesi thanks for the suggestion! I'm willing to retry when/if I can find some free time for this. Probably not too soon though since the last time I tried every deploy took ridiculously long (especially EC2 instances AFAIR).

@dineshPallapa
Copy link

config/database.yml

host: <%= ENV["POSTGRES_HOST"] %>

What will be the default value for POSTGRES_HOST variable?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment