将Golang应用程序部署到AWS OPSWORKS

Over the last few months I've become familiar with the AWS OpsWorks deployment process as it pertain to Node.js - deployment for Go seems to be another animal.

From what I've gathered, this is what I need to compile a successful Go deployment:

  • Install go on the EC2 box
  • Pull the private repository from GitHub
  • Pull in all dependencies
  • Compile the main package for the box's arch
  • Start the binary with a couple of flags that I use

Everywhere I have read seems to tout the ease of Go deployments because dependencies are included in the binary, but that seems to imply that you are compiling the application in your development environment and pushing that up to the cloud. This doesn't seem like a process that works well across a development team.

https://github.com/crowdmob/chef-golang-web-server-cookbook

I have been attempting to get the Chef Scripts from CrowdMob working, but to no avail. I continue to get errors that look like this:

[2014-08-01T16:08:22+00:00] WARN: Cookbook 'templates' is empty or entirely chefignored at /opt/aws/opsworks/current/merged-cookbooks/templates

What is the proper way to deal with dependencies during deployment?

Are there any established practices for deploying Go onto AWS with Chef?

Use a continuous integration service like CircleCi, Travis or your own setup Jenkins.

On the Continuous integration service then

  1. Add a github post commit hook .
  2. Test / Build the binary
  3. Create the zip file as artifact

At this point you can create an new version on Elastic Beanstalk using the AWS commandline and the zip file created from this version.

venv/bin/aws elasticbeanstalk create-application-version ...

Then just select which version to deploy from the EB dashboard.

For simple services using Chef is overkill IMHO. Docker offers a simple workflow.

Use the Docker container option and then use elastic beanstalk's command-line client to initialize your environment in the project root directory and then you can simply do a 'git aws.push' from the same place.

With the correctly configured Dockerfile in your project and pushed to eb, the EBS' docker container app will pull the correct image with golang installed, then do a go get on your projects dependencies, and then compile and run your app. It sounds way more complicated but it's actually very easy.

Below is a link to a video walkthrough I did for running a simple golang webapp on EBS. The method for uploading the project does not use git. Instead, I zip it up and upload it, but the git method is recommended (and I do it) for automating deployment.

YouTube: How to run a go web app on Amazon's Elastic Beanstalk

I also had some problems to setup a good building process with Elastic Beanstalk and Go.. I don't want to use Docker, and all the people seems to be going on this direction.. so.. you can take a look at this project: https://github.com/battle-arena/heimdall

There you will find a custom setup using the Buildfile and the Procfile.. and I rely on a CI system to build the release package...

Basically I do the following:

  • Hook the commits to a CI system
  • On the CI system I run the test and the install.sh if all good
  • The install.sh will create a build folder and a structure that will be sended to the Elastic Beanstalk with the aws-cli tool
  • After send to the EB the Buildfile will run the build.sh that will basically extract the compressed package with the proper structure, and run a go get ./... and go build
  • The Procfile will run the generated binary

I think the result is pretty good, and you can use with any CI tool.