Skip to content

Deployment Files

Daniel Randall edited this page Aug 5, 2017 · 45 revisions

Overview

In order for a project to be compatible with our development pipeline, there are a number of files that may need to be included in the project repository depending on the projects intended purpose.

Files

/vendor

The /vendor directory is used to lock certain Go dependencies to specific versions. See the Go Package Management wiki page for further enlightenment.

At the time of this writing, the easiest method for setting up the /vendor directory the way we need is to run the following commands (after installing gvt) to lock some dependencies to specific versions:

gvt fetch -tag v1.1.0 github.com/jessemillar/jsonresp && gvt fetch -tag v1.1.0 github.com/jessemillar/health && gvt fetch -tag v3.2.1 github.com/labstack/echo

Dockerfile

A Dockerfile is an instruction file for the Docker engine. The Dockerfile in a repository tells Docker how to build a container. Think of it as simple shell script that sets up a brand-new Linux machine. Dockerfiles often have instructions for updating packages or installing dependencies and almost always start a service as the last action. An example Dockerfile can be found in the av-api repository.

Dockerfile-ARM

The Dockerfile-ARM file is the same kind of file as the Dockerfile outlined above except build for ARM processors (which often requires different packages and operating systems). An example can be found in the av-api repository.

Dockerrun.aws.json

The Dockerrun.aws.json file in each repository is ALMOST a standard file. The only things that need to be changed are the repository name on line 8 and the port on line 12. For example, if we were to use the Dockerrun.aws.json file from the av-api repository as a template and were making a new microservice that were hypothetically named example-microservice and ran on port 10000 we would end up with a file that looked like:

{
    "AWSEBDockerrunVersion": "1",
    "Authentication": {
        "Bucket": "elasticbeanstalk-us-west-2-194925301021",
        "Key": ".dockercfg"
    },
    "Image": {
        "Name": "byuoitav/example-microservice:latest",
        "Update": "true"
    },
    "Ports": [{
        "ContainerPort": "10000"
    }]
}

circle.yml

circle.yml files are utilized by the CircleCI continuous integration service. They modify certain build parameters and instruct Circle to run script in certain orders. We generally use similar circle.yml files between repositories. An example "template" can be found in the av-api repository. As of this writing, the av-api circle.yml file instructs Circle to run unit tests, cross-compile the binary for ARM Linux machines, build Docker containers for both x86 and ARM devices, push the Docker containers to Docker Hub, and then deploy to AWS via the deploy.sh script.

Official documentation for circle.yml files can be found here.

deploy.sh

A standard file created by Circle and modified slightly by us that uses our AWS credentials to push the new Docker container to AWS Beanstalk.

When adding this file to the GitHub repository, be sure to run chmod +x deploy.sh to allow it to execute after push.

#!/usr/bin/env bash

PROJECT_NAME=$1
SHA1=$2 # Nab the SHA1 of the desired build from a command-line argument
EB_BUCKET=elasticbeanstalk-us-west-2-194925301021

# Create new Elastic Beanstalk version
aws configure set default.region us-west-2
aws configure set region us-west-2
aws s3 cp Dockerrun.aws.json s3://$EB_BUCKET/Dockerrun.aws.json # Copy the Dockerrun file to the S3 bucket
aws elasticbeanstalk create-application-version --application-name $PROJECT_NAME --version-label $SHA1 --source-bundle S3Bucket=$EB_BUCKET,S3Key=Dockerrun.aws.json

# Update Elastic Beanstalk environment to new version
aws elasticbeanstalk update-environment --environment-name $PROJECT_NAME-env --version-label $SHA1

deploy-pi.sh

A standard file that hits various webhooks on the raspi-deployment-microservice triggering deployments. Which rooms get which code is determined by the room's "roomDesignation" in the configuration database.

This file only needs to be included in repositories that run natively on Raspberry Pi's. If the file is added, be sure to make a call to it at the bottom of the circle.yml file.

The RASPI_DEPLOYMENT_MICROSERVICE_WSO2_HEADER and RASPI_DEPLOYMENT_MICROSERVICE_WSO2_ADDRESS environment variables need to be set in Circle in order for these scripts to run.

RASPI_DEPLOYMENT_MICROSERVICE_WSO2_HEADER Example:

Authorization: Bearer 123456789abc

Obtain the actual Bearer token from the WSO2 interface.

RASPI_DEPLOYMENT_MICROSERVICE_WSO2_ADDRESS:

https://api.byu.edu:443/byuoitav-raspi-deployment-microservice/0.1/webhook

When adding this file to the GitHub repository, be sure to run chmod +x deploy-pi.sh to allow it to execute after a push.

#!/usr/bin/env bash

if [ $1 = "development" ]; then
	curl -X GET --header "Accept: application/json" --header "$RASPI_DEPLOYMENT_MICROSERVICE_WSO2_HEADER" "$RASPI_DEPLOYMENT_MICROSERVICE_WSO2_ADDRESS"_development
elif [ $1 = "stage" ]; then
	curl -X GET --header "Accept: application/json" --header "$RASPI_DEPLOYMENT_MICROSERVICE_WSO2_HEADER" "$RASPI_DEPLOYMENT_MICROSERVICE_WSO2_ADDRESS"_stage
elif [ $1 = "production" ]; then
	curl -X GET --header "Accept: application/json" --header "$RASPI_DEPLOYMENT_MICROSERVICE_WSO2_HEADER" "$RASPI_DEPLOYMENT_MICROSERVICE_WSO2_ADDRESS"_production
else
	echo "Either 'development', 'stage', or 'production' must be passed as the sole argument"
fi

swagger.json

(do once the endpoints are hardened)

An API specification document required by WSO2. The swagger.json file's contents will vary widely across repositories (since each API that's being documented is different from the next), but existing swagger.json documents can be used as a template of sorts when documenting a new API.

Swagger as a specification allows for .json and .yml filetypes but tends to favor .yml. BYU's WSO2 installation has had troubles parsing .yml files in the past, so our team has switched to .json as our filetype of choice. As an added benefit, the Go programming language is a bit better at parsing .json.

Clone this wiki locally