Skip to content

Commit

Permalink
Flow from dynamodb to terrform implemented
Browse files Browse the repository at this point in the history
new command expose to bind ecs public IPs to r53
new command run to process state from DeveloperEnvironments
  • Loading branch information
alephnull committed Aug 3, 2020
1 parent acf6e62 commit b5f02b2
Show file tree
Hide file tree
Showing 23 changed files with 348 additions and 63 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@
# vendor/
/gromit
.terraform/
terraform.tfstate
*.plan
9 changes: 6 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
FROM golang:1.14 as builder

RUN CGO_ENABLED=0 go get github.com/TykTechnologies/gromit
RUN go get -u github.com/GeertJohan/go.rice/rice
WORKDIR /src/gromit
ADD . .
RUN CGO_ENABLED=0 go build && rice append --exec gromit

# generate clean, final image for end users
# generate clean image for end users
FROM alpine:latest
COPY --from=builder /go/bin/* /usr/bin/
COPY --from=builder /src/gromit/gromit /usr/bin/

EXPOSE 443
VOLUME /cfssl
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
gromit: *.go cmd/*.go devenv/*.go terraform/*.go server/*.go
rice embed-go
go build
rice append --exec $@
go mod tidy
sudo setcap 'cap_net_bind_service=+ep' $(@)

Expand Down
5 changes: 3 additions & 2 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
Generated from lines with TODO in the repo , use the pre-commit hook in .
Binary file gromit matches
server/app.go:// TODO Implement listing of all environments
Binary file terraform/manifests/.terraform/plugins/registry.terraform.io/hashicorp/aws/2.70.0/linux_amd64/terraform-provider-aws_v2.70.0_x4 matches
Binary file terraform/manifests/.terraform/plugins/registry.terraform.io/hashicorp/template/2.1.2/linux_amd64/terraform-provider-template_v2.1.2_x4 matches
terraform/parser.go: // TODO make euc1 an environment variable or part of the config
Binary file terraform/devenv/.terraform/plugins/registry.terraform.io/hashicorp/aws/2.70.0/linux_amd64/terraform-provider-aws_v2.70.0_x4 matches
Binary file terraform/devenv/.terraform/plugins/registry.terraform.io/hashicorp/template/2.1.2/linux_amd64/terraform-provider-template_v2.1.2_x4 matches
6 changes: 3 additions & 3 deletions cmd/expose.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import (
"github.com/spf13/cobra"
)

// EnvConfig holds global environment variables
type EnvConfig struct {
// envConfig holds global environment variables
type exposeEnvConfig struct {
ZoneID string
Domain string
}
Expand All @@ -37,7 +37,7 @@ var exposeCmd = &cobra.Command{
Currently it creates only A records.`,
Run: func(cmd *cobra.Command, args []string) {
var e EnvConfig
var e exposeEnvConfig

err := envconfig.Process("r53", &e)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ var runCmd = &cobra.Command{
Short: "Update envs from $GROMIT_TABLENAME",
Long: `Read state and called the embedded terraform manifest with the new tags. This component is meant to run in a scheduled task.`,
Run: func(cmd *cobra.Command, args []string) {
terraform.Run(args[0])
terraform.Run()
},
}

Expand Down
64 changes: 62 additions & 2 deletions devenv/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package devenv

import (
"context"
"fmt"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/aws/awserr"
Expand All @@ -17,6 +18,8 @@ const (
STATE = "state"
// NAME is the name of the name attribute in the DB :)
NAME = "name"
// NEW is the state when an env is new
NEW = "new"
)

// DevEnv is a tyk env on the dev env. This is not a type because
Expand Down Expand Up @@ -169,7 +172,7 @@ func GetEnv(db dynamodbiface.ClientAPI, table string, env string) (*DevEnv, erro
func InsertEnv(db dynamodbiface.ClientAPI, table string, env string, stateMap DevEnv) error {
// Remove key elements from the map as updates will fail
delete(stateMap, NAME)
stateMap[STATE] = "new"
stateMap[STATE] = NEW

// An env with the "name" key from state should not already exist
cond := expression.AttributeNotExists(expression.Name(NAME))
Expand Down Expand Up @@ -259,7 +262,7 @@ func UpsertEnv(db dynamodbiface.ClientAPI, table string, env string, stateMap De
// Remove key elements from the map as updates will fail
delete(stateMap, NAME)
// Reset the state so that the runner will pick it up
stateMap[STATE] = "new"
stateMap[STATE] = NEW

update := expression.UpdateBuilder{}
for k, v := range stateMap {
Expand Down Expand Up @@ -351,3 +354,60 @@ func DeleteEnv(db dynamodbiface.ClientAPI, table string, env string) error {
}
return nil
}

// GetNewEnvs will fetch all envs with state==NEW from the DB
// Only attribute names matching the list in repos will be fetched
func GetNewEnvs(db dynamodbiface.ClientAPI, table string, repos []string) ([]DevEnv, error) {
filt := expression.Name(STATE).Equal(expression.Value(NEW))

proj := expression.NamesList(expression.Name(NAME))
for _, r := range repos {
newProj := proj.AddNames(expression.Name(r))
proj = newProj
}

expr, err := expression.NewBuilder().
WithFilter(filt).
WithProjection(proj).
Build()
if err != nil {
fmt.Println(err)
}

// Use the built expression to populate the DynamoDB Scan API input parameters.
input := &dynamodb.ScanInput{
ExpressionAttributeNames: expr.Names(),
ExpressionAttributeValues: expr.Values(),
FilterExpression: expr.Filter(),
ProjectionExpression: expr.Projection(),
TableName: aws.String(table),
}

req := db.ScanRequest(input)
result, err := req.Send(context.Background())
var envs []DevEnv
if err != nil {
if aerr, ok := err.(awserr.Error); ok {
switch aerr.Code() {
case dynamodb.ErrCodeResourceNotFoundException:
log.Warn().Msgf("table %s not found", table)
case dynamodb.ErrCodeRequestLimitExceeded:
log.Error().Err(aerr).Msgf("request limit exceeded for table %s", table)
case dynamodb.ErrCodeInternalServerError:
log.Error().Err(aerr).Msg("ISE from AWS, please implement retry if appropriate")
default:
log.Error().Err(aerr).Msgf("error getting new envs from table %s", table)
}
}
return envs, err
}
for _, row := range result.Items {
de := make(DevEnv)
err = dynamodbattribute.UnmarshalMap(row, &de)
if err != nil {
return envs, err
}
envs = append(envs, de)
}
return envs, nil
}
2 changes: 1 addition & 1 deletion devenv/ecr.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func getExistingTag(svc ecriface.ClientAPI, registry string, repo string, tag st

req := svc.DescribeImagesRequest(input)
result, err := req.Send(context.Background())
log.Trace().Interface("netifaces", result).Msgf("images for %s", repo)
log.Trace().Interface("result", result).Msgf("images for %s", repo)
if err != nil {
return "", err
}
Expand Down
3 changes: 1 addition & 2 deletions server/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,11 @@ func (a *App) Init(ca string) {
// Read env vars prefixed by GROMIT_
err := envconfig.Process("gromit", &e)
if err != nil {
log.Fatal().Err(err)
log.Fatal().Err(err).Msg("could not load env")
}
log.Info().Interface("env", e).Msg("loaded env")
a.Env = &e

// Set global cfg
cfg, err := external.LoadDefaultAWSConfig()
if err != nil {
log.Fatal().Err(err).Msg("unable to load SDK config")
Expand Down
33 changes: 33 additions & 0 deletions terraform/base/output.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
data "terraform_remote_state" "integration" {
backend = "remote"

config = {
organization = "Tyk"
workspaces = {
name = "base-euc1"
}
}
}

# repo_rurls should probably be generated from env.Repos
output "repo_urls" {
value = map("tyk", data.terraform_remote_state.integration.outputs.tyk["ecr"],
"tyk-analytics", data.terraform_remote_state.integration.outputs.tyk-analytics["ecr"],
"tyk-pump", data.terraform_remote_state.integration.outputs.tyk-pump["ecr"])
description = "ECR base URLs"
}

output "region" {
value = data.terraform_remote_state.integration.outputs.region
description = "Region in which the env is running"
}

output "cfssl_efs" {
value = data.terraform_remote_state.integration.outputs.cfssl_efs
description = "EFS for keys and certs"
}

output "config_efs" {
value = data.terraform_remote_state.integration.outputs.config_efs
description = "EFS for Tyk config"
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ data "template_file" "dashboard" {
{ port = 3000,
name = local.db_name,
log_group = "internal",
image = var.tyk-analytics_image,
image = var.tyk-analytics,
command = ["--conf=/conf/tyk-analytics.conf"],
mounts = [
{ src = "config", dest = "/conf" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ data "template_file" "gateway" {
{ port = 8080,
name = local.gw_name,
log_group = "internal",
image = var.tyk_image,
image = var.tyk,
command = ["--conf=/conf/tyk.conf"],
mounts = [
{ src = "config", dest = "/conf" }
Expand Down
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion terraform/manifests/pump.tf → terraform/devenv/pump.tf
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ data "template_file" "pump" {
{ port = 3000,
name = local.pump_name,
log_group = "internal",
image = var.tyk-pump_image,
image = var.tyk-pump,
command = ["--conf=/conf/tyk-pump.conf"],
mounts = [
{ src = "config", dest = "/conf" }
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ variable "vpc_id" {
type = string
}

variable "tyk_image" {
variable "tyk" {
description = "Image for the tyk service"
type = string
}

variable "tyk-analytics_image" {
variable "tyk-analytics" {
description = "Image for the tyk-analytics service"
type = string
}

variable "tyk-pump_image" {
variable "tyk-pump" {
description = "Image for the tyk-pump service"
type = string
}
Expand Down
15 changes: 15 additions & 0 deletions terraform/infra/output.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
data "terraform_remote_state" "infra" {
backend = "remote"

config = {
organization = "Tyk"
workspaces = {
name = "dev-euc1"
}
}
}

output "vpc_id" {
value = data.terraform_remote_state.infra.outputs.vpc_id
description = "VPC in which the infra is running"
}
21 changes: 3 additions & 18 deletions terraform/manifests.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,16 @@ import (
// copyBoxToDir() will skip a .terraform dir, if found
func copyBoxToDir(b *rice.Box, boxPath string, dest string) error {
boxFile, err := b.Open(boxPath)
defer boxFile.Close()
if err != nil {
return err
}
defer boxFile.Close()
entries, err := boxFile.Readdir(0)
if err != nil {
return err
}
os.MkdirAll(dest, 0755)

log.Debug().Interface("entries", entries).Msg(boxPath)

for _, e := range entries {
srcPath := filepath.Join(boxPath, e.Name())
destPath := filepath.Join(dest, e.Name())
Expand All @@ -34,8 +32,8 @@ func copyBoxToDir(b *rice.Box, boxPath string, dest string) error {

if e.IsDir() {
// Recursively call copyDir()
if e.Name() == ".terraform" {
log.Debug().Msg("skipping .terraform dir")
if e.Name() == ".terraform" || e.Name() == "terraform.tfstate.d" {
log.Debug().Msg("skipping terraform dir")
continue
}
copyBoxToDir(b, srcPath, destPath)
Expand All @@ -49,16 +47,3 @@ func copyBoxToDir(b *rice.Box, boxPath string, dest string) error {
}
return nil
}

func deployManifests(b *rice.Box, destPrefix string) (string, error) {
tmpDir, err := ioutil.TempDir("", destPrefix)
if err != nil {
return "", err
}

err = copyBoxToDir(b, ".", tmpDir)
if err != nil {
log.Fatal().Err(err).Msgf("could not restore embedded manifests to %s", tmpDir)
}
return tmpDir, nil
}
Binary file removed terraform/manifests/tf.plan
Binary file not shown.
Loading

0 comments on commit b5f02b2

Please sign in to comment.