github.com/compozed/deployadactyl/controller

Make deployment downtime extinct


Keywords
allstate, cloud-foundry, cloud-foundry-instances, compozed, concurrent-deployments, deployment, dinosaur, go, golang
License
Other
Install
go get github.com/compozed/deployadactyl/controller

Documentation

Release CircleCI codecov Stories in Ready GoDoc Gitter Slack Status

Deployadactyl is a Go library for deploying applications to multiple Cloud Foundry instances. Deployadactyl utilizes blue green deployments and if it's unable to push your application it will rollback to the previous version. Deployadactyl utilizes Gochannels for concurrent deployments across the multiple Cloud Foundry instances.

How It Works

Deployadactyl works by utilizing the Cloud Foundry CLI to push your application. The general flow is to get a list of Cloud Foundry instances, check that the instances are available, download your artifact, log into each instance, and concurrently call cf push in the deploying applications directory. If your application fails to deploy on any instance, Deployadactyl will automatically roll the application back to the previous version.

Usage Requirements

Dependencies

Deployadactyl has the following dependencies within the environment:

Configuration File

Deployadactyl needs a yaml configuration file to specify your environments. Each environment has a name, domain and a list of foundations.

The configuration file can be placed anywhere within your project directory as long as you specify the location.

Param Necessity Type Description
name Required string Used in the deploy when the users are sending a request to Deployadactyl to specify which environment from the config they want to use.
domain Required string Used to specify a load balanced URL that has previously been created on the Cloud Foundry instances.
foundations Required []string A list of Cloud Foundry instance URLs.
authenticate Optional bool Used to specify if basic authentication is required for users. See the authentication section in the API documentation for more details
skip_ssl Optional bool Used to skip SSL verification when Deployadactyl logs into Cloud Foundry.
disable_first_deployment_rollback Optional bool Used to disable automatic rollback on first deploy so that initial logs are kept.

Example Configuration Yaml

---
environments:
  - name: preproduction
    domain: preproduction.example.com
    foundations:
    - https://preproduction.foundation-1.example.com
    - https://preproduction.foundation-2.example.com
    authenticate: false
    skip_ssl: true
    disable_first_deployment_rollback: true

  - name: production
    domain: production.example.com
    foundations:
    - https://production.foundation-1.example.com
    - https://production.foundation-2.example.com
    - https://production.foundation-3.example.com
    - https://production.foundation-4.example.com
    authenticate: true
    skip_ssl: false
    disable_first_deployment_rollback: false

Environment Variables

Authentication is optional as long as CF_USERNAME and CF_PASSWORD environment variables are exported. We recommend making a generic user account that is able to push to each Cloud Foundry instance.

$ export CF_USERNAME=some-username
$ export CF_PASSWORD=some-password

Optional: The log level can be changed by defining DEPLOYADACTYL_LOGLEVEL. DEBUG is the default log level.

How To Run Deployadactyl

After a configuration yaml has been created and environment variables have been set, the server can be run using the following commands:

$ go run server.go

or

$ go build && ./deployadactyl

Available Flags

Flag Usage
-config location of the config file (default "./config.yml")

API

A deployment by hitting the API using curl or other means. For more information on using the Deployadactyl API visit the API documentation in the wiki.

Example Curl

curl -X POST \
     -u your_username:your_password \
     -H "Accept: application/json" \
     -H "Content-Type: application/json" \
     -d '{ "artifact_url": "https://example.com/lib/release/my_artifact.jar"}' \
     https://preproduction.example.com/v1/apps/environment/org/space/t-rex

Event Handling

With Deployadactyl you can optionally register event handlers to perform any additional actions your deployment flow may require. For us, this meant adding handlers that would open and close change records, as well as notify anyone on pager duty of significant events.

Available Emitted Event Types

Event Type Returned Struct Emitted
deploy.start DeployEventData Before deployment starts
deploy.success DeployEventData When a deployment succeeds
deploy.failure DeployEventData When a deployment fails
deploy.finish DeployEventData When a deployment finishes, regardless of success or failure
validate.foundationsUnavailable PrecheckerEventData When a foundation you're deploying to is down

Event Handler Example

package pagehandler

type Pager interface {
  Page(description string)
}

import (
    DS "github.com/compozed/deployadactyl/structs"
)

type PageHandler struct {
    Pager        Pager
    Environments map[string]bool
}

func (p PageHandler) OnEvent(event DS.Event) error {
    var (
        precheckerEventData = event.Data.(DS.PrecheckerEventData)
        environmentName     = precheckerEventData.Environment.Name
        allowPage           = p.Environments[environmentName]
    )

    if allowPage {
        p.Pager.Page(precheckerEventData.Description)
    }

    return nil
}
package page

type Page struct {
  Token string
  Log   I.Logger
}

func (p *Page) Page(description string) {
  // pagerduty code
}

Event Handling Example

  // server.go

  p := pagehandler.PageHandler{Pager: pager, Config: config}

  em := creator.CreateEventManager()
  em.AddHandler(p, "deploy.start")
  em.AddHandler(p, "deploy.success")
  em.AddHandler(p, "deploy.failure")
  em.AddHandler(p, "deploy.finish")