This page looks best with JavaScript enabled

Continuous Integration and Deployment to Beanstalk With Docker

 ·   ·  ☕ 4 min read

In a previous post we discovered how can we run commands on each push and check if the test is passing against multiple versions of go. This is a continuation of the same concept. We are going to deploy our code to Elastic Beanstalk, straight from git push.

Elastic Beanstalk is nothing but a wrapper around it’s EC2 infrastructure. It is a developer-centric view of deploying an application on AWS. Developers just have to push the code and Beanstalk can take care of Auto Scaling Group, Elastic Load Balancer, databases etc. No need to manage infrastructure manually.

Here is the outline of the post:

  1. Prerequisites
  2. Create an app on Elastic Beanstalk
  3. Obtain the access and secret key from AWS Console
  4. Create an HTTP Server
  5. Setup .travis.yml

Prerequisites

I will assume that:

  • You have a working knowledge of git and TDD.
  • You have an AWS account.
  • You are hosting your code on GitHub and Travis is enabled on repo.

This setup must work on other providers, but I haven’t got time to test it. Let me know in the comments if you did it yourself and want to share it.

Create an app on Elastic Beanstalk

Before we automate the process of deployment, we must have an already running application on Beanstalk. If you don’t have one, head over to https://console.aws.amazon.com/elasticbeanstalk/home and look for a button saying Create a new application.

Select Docker for platform.

Create new beanstalk application

Create new beanstalk application

This will create an app, an environment, and an S3 bucket where the code well be uploaded.

Here is my already working instance of unittest application which we’ll be automating the CD workflow to.

Already working instance of beanstalk application

Already working instance of beanstalk application

Get the access and secret key from IAM Console

At this stage, you might want to create a user for this app and attach AWSElasticBeanstalkFullAccess policy to the user. But I am going to use my master account.

You can generate Access key ID and Secret access key by heading over to https://console.aws.amazon.com/iam/home?#/security_credentials.

Get Secret key and AWS IAM Console

Get Secret key and AWS IAM Console

You access key ID will look something like AKIABOOMLWMXVM5DUA4G and secret access key MdrNmw6Ub+vHp2cBZKZLBbtY54XaAMufNnfW1Rz5. Both will be needed by Travis to access your AWS programatically.

Let’s create a simple app

main.go file with driver code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
package main

import (
    "fmt"
    "net/http"
)

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", hello)
    http.ListenAndServe(":8080", mux)
}

func hello(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "Hello, world!")
}

main_test.go file with test:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
package main

import (
    "net/http"
    "net/http/httptest"
    "testing"
)

func TestHelloResponse(t *testing.T) {
    request, _ := http.NewRequest(http.MethodGet, "/", nil)
    response := httptest.NewRecorder()

    hello(response, request)

    got := response.Body.String()
    want := "Hello, world!\n"

    if got != want {
        t.Errorf("got %q want %q", got, want)
    }
}

While this is a simple server. I’ll do a tutorial on multi-container deployment when I’m upto it.

Dockerfile

Dockerfile for our repo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
FROM golang:alpine

ENV CGO_ENABLED=0
WORKDIR /go/src/github.com/santosh/unittest

COPY . .

RUN go get -d
RUN GOOS=linux GOARCH=amd64 go build -a -installsuffix cgo -o app .

EXPOSE 8080
CMD ["./app"]

Tune up the .travis.yml

Add deploy section to .travis.yml:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
sudo: required

services:
  - docker

before_install:
  - docker build -t sntshk/untittest .

script:
  - docker run sntshk/untittest go test


deploy:
  provider: elasticbeanstalk
  access_key_id: $AWS_ACCESS_KEY
  secret_access_key:
    secure: $AWS_SECRET_KEY
  region: "ap-south-1"
  app: "unittest"
  env: "Unittest-env"
  bucket_name: "elasticbeanstalk-ap-south-1-086705419055"

As you can see, we haven’t put access key and secret key directly. Travis provides a way to pass environment variables to running jobs. You can find it in the project settings. Below I have set both those variables.

Set environment variable in project settings.

Set environment variable in project settings.

Set the region in which you have created the application. Fill in the app, env and bucket_name appropriately.

Set environment variable in project settings.

Set environment variable in project settings.

Share on

santosh
WRITTEN BY
santosh
Pipeline & Backend Developer