AlexsJones/gravitywell

View on GitHub
README.md

Summary

Maintainability
Test Coverage
# Gravitywell

<img src="https://github.com/ashleymcnamara/gophers/blob/master/SPACEGIRL_GOPHER.png?raw=true" alt="drawing" width="200"/>


**This project is deprecated in favour of ClusterAPI or other excellent provisioning tools**


![ProjectStatus](https://img.shields.io/badge/project%20status-Alpha-yellow.svg)
![buildstatus](https://travis-ci.org/AlexsJones/gravitywell.svg?branch=master)

[![Maintainability](https://api.codeclimate.com/v1/badges/a6cd570642c5aeeedaf9/maintainability)](https://codeclimate.com/github/AlexsJones/gravitywell/maintainability)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
![Release](https://img.shields.io/github/release/AlexsJones/gravitywell.svg)

**Update** Now supports Digital Ocean API for cluster creation
**Update** AWS API now in Alpha for AWS EKS - Still building a CFN for auto node pool creation. For decent results use a more mature tool for AWS such as [eksctl](https://github.com/weaveworks/eksctl)

Gravitywell is designed to *create kubernetes clusters and deploy your applications.
It uses YAML to store deployments and supports multiple versions of kubernetes resource definitions.
It lets you store your entire container infrastructure as code.

Supported providers:

- [x] Google Cloud Platform
- [x] Digital Ocean
- [x] Minikube
- [ ] Amazon Web Services (Only partially at this time)



![flowexample](resources/gravitywellflow.png)

## How is gravitywell different and why is it useful?

- Can deploy across multiple cloud providers at the same time.
    - _All other tools we found would either do the multiple cloud deployment, without the apps or visa versa._
- Based on cloud providers own container API
    - _Ain't nobody got time to be deploying custom networking or policies when its done for free._
- Uses dynamic interpolation with [vortex](https://github.com/AlexsJones/vortex) so you aren't writing template files for days.
- Allows you to do more than just deploy clusters; it lets you bootstrap them with fully working dependant services.
    - _Think about getting mongodb,zookeeper,consul,nifi,nginx,api's and a bunch of other stuff going straight away_

## Getting Started

To get started you'll need golang installed or to fetch the binary from homebrew/releases page (OSX)

- Get with golang: 
    - `go get github.com/AlexsJones/gravitywell`
- Download with homebrew: `brew tap AlexsJones/homebrew-gravitywell && brew install gravitywell`[Tap](https://github.com/AlexsJones/homebrew-gravitywell)
- Download as a cross-platform release: [Latest release](https://github.com/AlexsJones/gravitywell/releases)
- `docker run tibbar/gravitywell:latest /gravitywell` [Docker hub](https://hub.docker.com/r/tibbar/gravitywell)

## Prerequisites

The current implementation works with Google Cloud Platform & Amazon web services.

_For Google Cloud Platform please set your service account for the right project_

`export GOOGLE_APPLICATION_CREDENTIALS=~/Downloads/alex-example-e28058e8985b.json`

_For Digital Ocean please set the TOKEN_

`export DIGITAL_OCEAN_TOKEN=30109aoimvaoim42oi2mg2`

Digital ocean also requires additional tools for authentication found [here](https://github.com/digitalocean/doctl)

_For Amazon Web Services please set the aws profile name and region_

`export AWS_DEFAULT_PROFILE=alexprod`
`export AWS_DEFAULT_REGION=us-west-2`

Aws also requires additional tools for authentication found [here](https://docs.aws.amazon.com/eks/latest/userguide/install-aws-iam-authenticator.html)


## Running on GCP

At this point you are ready to run gravitywell.

For working with templates as per the examples you'll also need [vortex](https://github.com/AlexsJones/vortex)
(go get github.com/AlexsJones/vortex)
_This can be installed either via golang or as a binary also_


_Lets take it for a spin using the gcp example_


If you've looked at the templates you'll see a helmesque style of interpolation
```
"gke_{{.projectname}}_{{.projectregion}}_{{.clustername}}" we're going to override
```

Build the cluster template
```
vortex --output deployment/cluster --template examples/gcp/templates/cluster --set "projectname=alex-example" --set "projectregion=us-east4" --set "clustername=gke_alex-example_us-east4_testcluster"
```
Build the example application templates
```
vortex --output deployment/applications --template examples/common/templates/application --set "projectname=alex-example" --set "projectregion=us-east4" --set "clustername=gke_alex-example_us-east4_testcluster"
```
The deployment directory should look like this
```
deployment
├── applications
│   ├── apache_tika.yaml
│   ├── mongodb.yaml
│   └── zookeeper.yaml
└── cluster
    └── small.yaml
```

```
gravitywell create -f deployment/
```
This will now start to provision any clusters that are required and deploy applications


## Running on Minikube

Adjust the example-minikube/cluster/small.yaml to suit your VMDriver



`gravitywell create -f example-minikube/`

_Yes that's all!_

### Example files

This is what an example cluster may look like:

```bash
APIVersion: "v1"
Kind: "Cluster"
Strategy:
  - Provider:
      Name: "Google Cloud Platform"
      Clusters:
        - Cluster:
            FullName: "gke_{{.projectname}}_{{.projectregion}}_{{.clustername}}"
            ShortName: "{{.clustername}}"
            Project: "{{.projectname}}"
            Region: "us-east4"
            Zones: ["us-east4-a"]
            Labels:
              type: "test"
            InitialNodeCount: 1
            InitialNodeType: "n1-standard-1"
            OauthScopes: "https://www.googleapis.com/auth/monitoring.write,
          https://www.googleapis.com/auth/logging.write,
          https://www.googleapis.com/auth/trace.append,
          https://www.googleapis.com/auth/devstorage.full_control,
          https://www.googleapis.com/auth/compute"
            NodePools:
              - NodePool:
                  Name: "np1"
                  Count: 3
                  NodeType: "n1-standard-1"
                  Labels:
                    k8s-node-type: "test"
            PostInstallHook:
              - Execute:
                  Path: "."
                  Shell: "gcloud container clusters get-credentials {{.clustername}} --region={{.projectregion}} --project={{.projectname}}"
            PostDeleteHook:
              - Execute:
                  Path: "."
                  Shell: "pwd"
```

And this is an example application

```bash
APIVersion: "v1"
Kind: "Application"
Strategy:
  - Cluster:
      FullName: "gke_{{.projectname}}_{{.projectregion}}_{{.clustername}}"
      ShortName: "{{.clustername}}"
      Applications:
        - Application:
            Name: "kubernetes-apache-tika"
            Namespace: "tika"
            VCS:
              FileSystem: # Optional
              Git: "git@github.com:AlexsJones/kubernetes-apache-tika.git"
              #Optional tree reference selectors - use one at a time and follow format
              # refs/heads/{branchname}
              # refs/tags/{tagname}
              # refs/remotes/
              GitReference: refs/heads/master #Optional and this example just pulls master
            ActionList:
              - Execute:
                  Kind: "shell"
                  Configuration:
                    Command: pwd
                    Path: ../ #Optional value
              - Execute:
                  Kind: "shell"
                  Configuration:
                    Command: ./build_environment.sh default
              - Execute:
                  Kind: "kubernetes"
                  Configuration:
                    Path: deployment #Optional value
                    AwaitDeployment: true #Optional defaults to false
```

Action lists can also be moved into the repositories being deployed to keep things clean!

_Or a combination of inline, local and remote..._
e.g.

```
APIVersion: "v1"
Kind: "Application"
Strategy:
  - Cluster:
      FullName: "gke_{{.projectname}}_{{.projectregion}}_{{.clustername}}"
      ShortName: "{{.clustername}}"
      Applications:
        - Application:
            Name: "kubernetes-apache-tika"
            Namespace: "tika"
            VCS:
               FileSystem: # Optional
               Git: "git@github.com:AlexsJones/kubernetes-apache-tika.git"
               #Optional tree reference selectors - use one at a time and follow format
               # refs/heads/{branchname}
               # refs/tags/{tagname}
               # refs/remotes/
              GitReference: refs/heads/master #Optional and this example just pulls master
            ActionList:
              Executions:
                - Execute:
                  Kind: "Shell"
                  Configuration:
                    Command: kubectl create ns zk
                - Execute:
                  Kind: "RunActionList"
                  Configuration:
                    LocalPath: templates/external/gwdeploymentconfig.yaml
                - Execute:
                  Kind: "RunActionList"
                  Configuration:
                    RemotePath: tika-extras/additional-actionlist.yaml
               
```

Where you can have an action list defined..

*actions lists can call other action lists in a chain - helping to create templated commands*

[See an example here](examples/example-gcp/templates/application/zookeeper.yaml)

```
#./templates/external/gwdeploymentconfig.yaml

APIVersion: "v1"
Kind: "ActionList"
ActionList:
    - Execute:
      Kind: "shell"
      Configuration:
        Command: ./build_environment.sh default
    - Execute:
      Kind: "RunActionList"
      Configuration:
        Path: example-gcp/templates/actionlist/actionlist-deployment.yaml
```

### Flags

```
DryRun     bool   `short:"d" long:"dryrun" description:"Performs a dryrun."`
FileName   string `short:"f" long:"filename" description:"filename to execute, also accepts a path."`
SSHKeyPath string `short:"s" long:"sshkeypath" description:"Custom ssh key path."`
MaxTimeout string `short:"m" long:"maxtimeout" description:"Max rollout time e.g. 60s or 1m"`
Verbose    bool   `short:"v" long:"verbose" description:"Enable verbose logging"`
```

## Running the tests

`go test ./... -v` from the gravitywell directory on your gopath


## Contributing

Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us.

## Versioning

We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/AlexsJones/gravitywell/tags). 

## Authors

* **Alex Jones** - *Initial work* 

See also the list of [contributors](https://github.com/your/project/contributors) who participated in this project.

## License

This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details

## Acknowledgments

* Helm & terraform both great projects
* kubicorn does alot of very cool stuff
* https://eksctl.io/ was a fantastic reference for golang AWS sdk API

## Special thanks

<img src="resources/jetbrains.png" alt="jetbrains" width="200"/>