Skip to content

Commit

Permalink
Merge pull request #34 from commitdev/kubernetes
Browse files Browse the repository at this point in the history
Added kubernetes specs
  • Loading branch information
bmonkman committed Oct 29, 2019
2 parents 516299b + 016a4b5 commit 6b7e4f6
Show file tree
Hide file tree
Showing 56 changed files with 2,087 additions and 12 deletions.
17 changes: 14 additions & 3 deletions cmd/generate.go
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/commitdev/commit0/internal/generate/docker"
"github.com/commitdev/commit0/internal/generate/golang"
"github.com/commitdev/commit0/internal/generate/http"
"github.com/commitdev/commit0/internal/generate/kubernetes"
"github.com/commitdev/commit0/internal/generate/proto"
"github.com/commitdev/commit0/internal/generate/react"
"github.com/commitdev/commit0/internal/templator"
Expand All @@ -20,11 +21,12 @@ var configPath string
var language string

const (
Go = "go"
React = "react"
Go = "go"
React = "react"
Kubernetes = "kubernetes"
)

var supportedLanguages = [...]string{Go, React}
var supportedLanguages = [...]string{Go, React, Kubernetes}

func init() {

Expand Down Expand Up @@ -59,6 +61,8 @@ var generateCmd = &cobra.Command{
docker.GenerateGoDockerCompose(t, cfg, &wg)
case React:
react.Generate(t, cfg, &wg)
case Kubernetes:
kubernetes.Generate(t, cfg, &wg)
}

util.TemplateFileIfDoesNotExist("", "README.md", t.Readme, &wg, cfg)
Expand All @@ -68,7 +72,14 @@ var generateCmd = &cobra.Command{
docker.GenerateGoHTTPGWDockerFile(t, cfg, &wg)
}

// Wait for all the templates to be generated
wg.Wait()

switch language {
case Kubernetes:
kubernetes.Execute(cfg)
}

},
}

Expand Down
5 changes: 3 additions & 2 deletions go.mod
Expand Up @@ -8,11 +8,12 @@ require (
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 // indirect
github.com/k0kubun/pp v3.0.1+incompatible
github.com/mattn/go-colorable v0.1.2 // indirect
github.com/rogpeppe/go-internal v1.3.2 // indirect
github.com/rogpeppe/go-internal v1.5.0 // indirect
github.com/spf13/cobra v0.0.5
github.com/stretchr/testify v1.4.0 // indirect
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392 // indirect
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 // indirect
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // indirect
golang.org/x/sys v0.0.0-20191010194322-b09406accb47 // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gopkg.in/yaml.v2 v2.2.4
)
12 changes: 6 additions & 6 deletions go.sum
Expand Up @@ -48,8 +48,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.3.2 h1:XU784Pr0wdahMY2bYcyK6N1KuaRAdLtqD4qd8D18Bfs=
github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.5.0 h1:Usqs0/lDK/NqTkvrmKSwA/3XkZAs7ZAW/eLeQ2MVBTw=
github.com/rogpeppe/go-internal v1.5.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
Expand All @@ -72,8 +72,8 @@ github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392 h1:ACG4HJsFiNMf47Y4PeRoebLNy/2lXT9EtprMuTFWt1M=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
Expand All @@ -86,8 +86,8 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69 h1:rOhMmluY6kLMhdnrivzec6lLgaVbMHMn2ISQXJeJ5EM=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0 h1:Dh6fw+p6FyRl5x/FvNswO1ji0lIGzm3KP8Y9VkS9PTE=
Expand Down
10 changes: 9 additions & 1 deletion internal/config/config.go
Expand Up @@ -55,7 +55,15 @@ type Commit0Config struct {
Maintainers []Maintainers `yaml:"maintainers"`
Network Network `yaml:"network"`
Services []Service `yaml:"services"`
React React `yaml:react`
React React `yaml:"react"`
Kubernetes Kubernetes `yaml:"kubernetes"`
}

type Kubernetes struct {
ClusterName string `yaml:"clusterName"`
Deploy bool `yaml:"deploy"`
AWSAccountId string `yaml:"awsAccountId"`
AWSRegion string `yaml:"awsRegion"`
}

func LoadConfig(filePath string) *Commit0Config {
Expand Down
64 changes: 64 additions & 0 deletions internal/generate/kubernetes/generate.go
@@ -0,0 +1,64 @@
package kubernetes

import (
"fmt"
"io"
"log"
"os"
"os/exec"
"sync"

"github.com/commitdev/commit0/internal/config"
"github.com/commitdev/commit0/internal/templator"
)

func Generate(templator *templator.Templator, config *config.Commit0Config, wg *sync.WaitGroup) {
templator.Kubernetes.TemplateFiles(config, false, wg)

}

func Execute(config *config.Commit0Config) {
if config.Kubernetes.Deploy {
log.Println("Planning infrastructure...")
execute(exec.Command("terraform", "init"))
execute(exec.Command("terraform", "plan"))
}
}

func execute(cmd *exec.Cmd) {
dir, err := os.Getwd()
if err != nil {
log.Fatalf("Getting working directory failed: %v\n", err)
}

cmd.Dir = fmt.Sprintf("%s/kubernetes/terraform/environments/staging", dir)

stdoutPipe, _ := cmd.StdoutPipe()
stderrPipe, _ := cmd.StderrPipe()

var errStdout, errStderr error
err = cmd.Start()
if err != nil {
log.Fatalf("Starting terraform command failed: %v\n", err)
}

go func() {
_, errStdout = io.Copy(os.Stdout, stdoutPipe)
}()
go func() {
_, errStderr = io.Copy(os.Stderr, stderrPipe)
}()

err = cmd.Wait()
if err != nil {
log.Fatalf("Executing terraform command failed: %v\n", err)
}

if errStdout != nil {
log.Printf("Failed to capture stdout: %v\n", errStdout)
}

if errStderr != nil {
log.Printf("Failed to capture stderr: %v\n", errStderr)
}
}
2 changes: 2 additions & 0 deletions internal/templator/templator.go
Expand Up @@ -41,6 +41,7 @@ type Templator struct {
Go *GoTemplator
Docker *DockerTemplator
React *DirectoryTemplator
Kubernetes *DirectoryTemplator
}

func NewTemplator(box *packr.Box) *Templator {
Expand All @@ -54,6 +55,7 @@ func NewTemplator(box *packr.Box) *Templator {
Readme: NewSingleFileTemplator(box, "util/README.tmpl"),
Docker: NewDockerFileTemplator(box),
React: NewDirectoryTemplator(box, "react"),
Kubernetes: NewDirectoryTemplator(box, "kubernetes"),
}
}

Expand Down
6 changes: 6 additions & 0 deletions templates/commit0/commit0.tmpl
Expand Up @@ -7,6 +7,12 @@ maintainers:
# - name: bob
# email: bob@test.com

kubernetes:
clusterName: staging
deploy: true
awsAccountId: 1234
awsRegion: us-east-1

network:
grpc:
host: 0.0.0.0
Expand Down
95 changes: 95 additions & 0 deletions templates/kubernetes/terraform/README.md
@@ -0,0 +1,95 @@
## Guidelines & Style Convention Summary

- All Terraform configuration should be formatted with `terraform fmt` before being accepted into this repository.
- This repository is Terraform version >= 0.12, as such, leverage features from this release whenever possible.
See https://www.terraform.io/upgrade-guides/0-12.html for more information.
- Leverage community-maintained Terraform modules whenever possible.
- Attempt to minimize duplication whenever possible, but only within reason -- sometimes duplication is an acceptable solution.
- Follow style conventions described in `docs/guide.pdf` whenever possible.
- Whenever possible, inject resources down versus referencing resources across modules. This has been made easier with new features in v0.12.
- Whenever possible, define the types of variables.

### Module Conventions

- All modules should contain the following:

`README.md`: A description of the module.
`main.tf`: Module entrypoint where instantiation of resources happens.
`variables.tf`: Module variables.
`outputs.tf`: Output values (optional).
`files/`: Any / all files required by the module.

- All module variables must have a description.
- Again, leverage community-maintained Terraform modules whenever possible.
- Avoid writing a module that is simply a wrapper of a Terraform resource unless absolutely necessary.

### Environment Conventions

- All environments should contain the following:

`main.tf`: Toplevel terraform configuration file that instantiates the `environment` module.

- Configuration should be pushed "top->down" from the `environment` module to it's submodules.

### The Environment Module

- The `environment` module can be considered the top-level module, all other modules are imported from this module.
- Environment-specific variables should be exposed via the `variables.tf` file in this module, where they will be set from within the appropriate environment in the `environments/` directory.
- The `environment` module contains the following:

`main.tf`: Module entrypoint where instantiation of resources happens.
`backend.tf`: Terraform remote state configuration.
`provider.tf`: Provider configuration.
`variables.tf`: Environment-specific variables are desclared here.
`versions.tf`: Terraform version information.
`files/`: (DEPRECATED)

## Directory Structure

```
README.md
environments/
production/
main.tf
staging/
main.tf
development/
main.tf
docs/
guide.pdf
modules/
environment/
...
<module-a>/
files/
scripts/
main.tf
outputs.tf
variables.tf
<module-n>/
...
```

## AWS Guidelines

- TODO: Identity/Access Management (IAM) Guidelines

## Kubernetes Guidelines

- When to use the Terraform Kuberenetes Provider and when to use manifests?

- Use the Terraform Kubernetes Provider (`provider "kubernetes"`) whenever you are provisioning a resource that could be considered relatively static (think Ingress, RoleBinding, CluterRoleBinding, etc).

- Use conventional Kubernetes manifests / `kubectl` when provisioning resouirces that could be considered dynamic (think Deployments).

## Application

1. Set up a profile for your project with your credentials in a specific profile in `~/.aws/credentials` and then export the following env var:
`export AWS_PROFILE=<project_name>`

2. Run the following from the appropriate environment directory under `environments/`:

```
environment/development$ terraform init
environment/development$ terraform plan
```
22 changes: 22 additions & 0 deletions templates/kubernetes/terraform/environments/development/main.tf
@@ -0,0 +1,22 @@
# Instantiate the development environment
module "development" {
source = "../../modules/environment"
environment = "development"

# Project configuration
project = "{{ .Kubernetes.ClusterName }}"
region = "{{ .Kubernetes.AWSRegion }}"
allowed_account_ids = ["{{ .Kubernetes.AWSAccountId }}"]

# ECR configuration
ecr_repositories = ["{{ .Kubernetes.ClusterName }}"]

# EKS configuration
eks_worker_instance_type = "t2.small"
eks_worker_asg_max_size = 2

# EKS-Optimized AMI for your region: https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html
# https://us-east-1.console.aws.amazon.com/systems-manager/parameters/%252Faws%252Fservice%252Feks%252Foptimized-ami%252F1.14%252Famazon-linux-2%252Frecommended%252Fimage_id/description?region=us-east-1
eks_worker_ami = "ami-0392bafc801b7520f"

}
21 changes: 21 additions & 0 deletions templates/kubernetes/terraform/environments/production/main.tf
@@ -0,0 +1,21 @@
# Instantiate the production environment
module "production" {
source = "../../modules/environment"
environment = "production"

# Project configuration
project = "{{ .Kubernetes.ClusterName }}"
region = "{{ .Kubernetes.AWSRegion }}"
allowed_account_ids = ["{{ .Kubernetes.AWSAccountId }}"]

# ECR configuration
ecr_repositories = ["{{ .Kubernetes.ClusterName }}"]

# EKS configuration
eks_worker_instance_type = "m4.large"
eks_worker_asg_max_size = 3

# EKS-Optimized AMI for your region: https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html
# https://us-east-1.console.aws.amazon.com/systems-manager/parameters/%252Faws%252Fservice%252Feks%252Foptimized-ami%252F1.14%252Famazon-linux-2%252Frecommended%252Fimage_id/description?region=us-east-1
eks_worker_ami = "ami-0392bafc801b7520f"
}
21 changes: 21 additions & 0 deletions templates/kubernetes/terraform/environments/staging/main.tf
@@ -0,0 +1,21 @@
# Instantiate the staging environment
module "staging" {
source = "../../modules/environment"
environment = "staging"

# Project configuration
project = "{{ .Kubernetes.ClusterName }}"
region = "{{ .Kubernetes.AWSRegion }}"
allowed_account_ids = ["{{ .Kubernetes.AWSAccountId }}"]

# ECR configuration
ecr_repositories = ["{{ .Kubernetes.ClusterName }}"]

# EKS configuration
eks_worker_instance_type = "t2.small"
eks_worker_asg_max_size = 2
# EKS-Optimized AMI for your region: https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html
# https://us-east-1.console.aws.amazon.com/systems-manager/parameters/%252Faws%252Fservice%252Feks%252Foptimized-ami%252F1.14%252Famazon-linux-2%252Frecommended%252Fimage_id/description?region=us-east-1
eks_worker_ami = "ami-0392bafc801b7520f"

}
9 changes: 9 additions & 0 deletions templates/kubernetes/terraform/modules/ecr/main.tf
@@ -0,0 +1,9 @@
resource "aws_ecr_repository" "ecr_repository" {
count = length(var.ecr_repositories)
name = element(var.ecr_repositories, count.index)

tags = {
environment = var.environment
}
}

9 changes: 9 additions & 0 deletions templates/kubernetes/terraform/modules/ecr/variables.tf
@@ -0,0 +1,9 @@
variable "environment" {
description = "The environment (dev/staging/prod)"
}

variable "ecr_repositories" {
description = "List of ECR repository names to create"
type = list(string)
}

4 changes: 4 additions & 0 deletions templates/kubernetes/terraform/modules/ecr/versions.tf
@@ -0,0 +1,4 @@

terraform {
required_version = ">= 0.12"
}

0 comments on commit 6b7e4f6

Please sign in to comment.