ruk·si

AWS
Setup EB + Docker + Go

Updated at 2015-10-05 22:30

This is a simple guide how to create Docker running a Go application in Elastic Beanstalk, behind load balancer and optional auto-scaling.

You need to have Docker Toolbox, Go, Python and AWS command line tools installed.

pip install awscli awsebcli

# list available elastic beanstalk platform in a region
eb platform list -r us-west-2
# we are going to use the go-1.4-(preconfigured-docker)

Write the Application

mkdir cori # example project name is `cori`
cd cori
touch application.go
// application.go
package main

import (
    "fmt"
    "net/http"
    "time"
    "os"
)

func main() {
    // EB provides this environmental variable.
    port := os.Getenv("PORT")
    if len(port) == 0 {
        port = "3000" // for local
    }
    port = ":" + port
    http.HandleFunc("/", indexHandler)
    fmt.Printf("Starting server at %s\n", port)
    err := http.ListenAndServe(port, nil)
    if err != nil {
        panic(err)
    }
}

func indexHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Time was %s.", time.Now())
}
touch Dockerfile.local      # EB uses its own Dockerfile, this is for local dev
# Dockerfile.local
FROM golang:1.4.2-onbuild

Test that it works.

docker build -f Dockerfile.local -t cori-img .
docker run -it -p 80:80 --rm --name cori-ps cori-img
# curl dockerhost:80

Defining the Elastic Beanstalk application

Create new key pair. EC2 > Key Pairs > Create Key Pair. Name it eb-cori. Move it to ~/.ssh and execute chmod 0600 eb-cori.pem on it.

Create a new role eb-service-role-cori. Use the managed policy: AWSElasticBeanstalkFullAccess and add the following trust relationship to the role.

{
    "Version": "2012-10-17",
    "Statement": [
      {
        "Sid": "1",
        "Effect": "Allow",
        "Principal": {
          "Service": "elasticbeanstalk.amazonaws.com"
        },
        "Action": "sts:AssumeRole",
        "Condition": {
          "StringEquals": {
            "sts:ExternalId": "elasticbeanstalk"
          }
        }
      }
    ]
}

Create a new role eb-instance-role-cori. This is assigned to each individual instance. They won't need permissions as of yet.

# creates the app specification to AWS and `.elasticbeanstalk` directory
# note that these are just defaults, `create` can overwrite any of these
eb init \
    --platform go-1.4-(preconfigured-docker) \
    --region us-west-2 \
    --keyname cori-eb

# each app has multiple app environments e.g. staging and prodution
# WebServer-Standard or Worker, serving or consumes queues?
# create the role first
# instance name is the same as environment name so include the app name
eb create \
    --service-role eb-service-role-cori \
    --instance_type t1.micro \
    --tier "WebServer-Standard" \
    --cname cori-staging-maroon \
    --scale 1 \
    cori-staging-maroon

Deployment

eb deploy staging-maroon

Sources