diff --git a/go.mod b/go.mod index 5bf1f4761..33fe4a198 100644 --- a/go.mod +++ b/go.mod @@ -3,23 +3,26 @@ module github.com/commitdev/commit0 go 1.12 require ( - github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect + github.com/chzyer/logex v1.1.10 // indirect + github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect + github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 // indirect github.com/gobuffalo/logger v1.0.1 // indirect github.com/gobuffalo/packr/v2 v2.5.2 github.com/gorilla/mux v1.7.3 + github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a // indirect github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 // indirect github.com/k0kubun/pp v3.0.1+incompatible github.com/kyokomi/emoji v2.1.0+incompatible github.com/logrusorgru/aurora v0.0.0-20191017060258-dc85c304c434 - github.com/manifoldco/promptui v0.3.2 + github.com/lunixbochs/vtclean v1.0.0 // indirect + github.com/manifoldco/promptui v0.3.0 github.com/mattn/go-colorable v0.1.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-20191011191535-87dc89f01550 // indirect - golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 // indirect golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // indirect golang.org/x/sys v0.0.0-20191010194322-b09406accb47 // indirect - gopkg.in/alecthomas/kingpin.v3-unstable v3.0.0-20191105091915-95d230a53780 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/yaml.v2 v2.2.5 ) diff --git a/go.sum b/go.sum index eca407547..5404c43a6 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,4 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/alecthomas/gometalinter v2.0.11+incompatible h1:ENdXMllZNSVDTJUUVIzBW9CSEpntTrQa76iRsEFLX/M= -github.com/alecthomas/gometalinter v2.0.11+incompatible/go.mod h1:qfIpQGGz3d+NmgyPBqv+LSh50emm1pt72EtcX2vKYQk= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= @@ -11,8 +7,6 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5O github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -30,12 +24,6 @@ github.com/gobuffalo/packd v0.3.0 h1:eMwymTkA1uXsqxS0Tpoop3Lc0u3kTfiMBE6nKtQU4g4 github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= github.com/gobuffalo/packr/v2 v2.5.2 h1:4EvjeIpQLZuRIljwnidYgbRXbr1yIzVRrESiLjqKj6s= github.com/gobuffalo/packr/v2 v2.5.2/go.mod h1:sgEE1xNZ6G0FNN5xn9pevVu4nywaxHvgup67xisti08= -github.com/golang/lint v0.0.0-20181026193005-c67002cb31c3 h1:I4BOK3PBMjhWfQM2zPJKK7lOBGsrsvOB7kBELP33hiE= -github.com/golang/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= -github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf h1:7+FW5aGwISbqUtkfmIpZJGRgNFg2ioYPvFaUxdqpDsg= -github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE= -github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc h1:cJlkeAx1QYgO5N80aF5xRGstVsRQwgLR7uA2FnP1ZjY= -github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= @@ -63,15 +51,13 @@ github.com/kyokomi/emoji v2.1.0+incompatible h1:+DYU2RgpI6OHG4oQkM5KlqD3Wd3UPEsX github.com/kyokomi/emoji v2.1.0+incompatible/go.mod h1:mZ6aGCD7yk8j6QY6KICwnZ2pxoszVseX1DNoGtU2tBA= github.com/logrusorgru/aurora v0.0.0-20191017060258-dc85c304c434 h1:im9kkmH0WWwxzegiv18gSUJbuXR9y028rXrWuPp6Jug= github.com/logrusorgru/aurora v0.0.0-20191017060258-dc85c304c434/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= -github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a h1:weJVJJRzAJBFRlAiJQROKQs8oC9vOxvm4rZmBBk0ONw= -github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= +github.com/lunixbochs/vtclean v1.0.0 h1:xu2sLAri4lGiovBDQKxl5mrXyESr3gUr5m5SM5+LVb8= +github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/manifoldco/promptui v0.3.2 h1:rir7oByTERac6jhpHUPErHuopoRDvO3jxS+FdadEns8= -github.com/manifoldco/promptui v0.3.2/go.mod h1:8JU+igZ+eeiiRku4T5BjtKh2ms8sziGpSYl1gN8Bazw= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/manifoldco/promptui v0.3.0 h1:vJiVJREqDfn9ZhqTG1Dz5zP9RPWlAzWQkwRYLGyUHx4= +github.com/manifoldco/promptui v0.3.0/go.mod h1:zoCNXiJnyM03LlBgTsWv8mq28s7aTC71UgKasqRJHww= github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -100,8 +86,6 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/tsenart/deadcode v0.0.0-20160724212837-210d2dc333e9 h1:vY5WqiEon0ZSTGM3ayVVi+twaHKHDFUVloaQ/wug9/c= -github.com/tsenart/deadcode v0.0.0-20160724212837-210d2dc333e9/go.mod h1:q+QjxYvZ+fpjMXqs+XEriussHjSYqeXVnAdSV1tkMYk= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -109,16 +93,12 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 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/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 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= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -129,14 +109,10 @@ golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/nt 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-20181122213734-04b5d21e00f1/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0 h1:Dh6fw+p6FyRl5x/FvNswO1ji0lIGzm3KP8Y9VkS9PTE= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0 h1:Dh6fw+p6FyRl5x/FvNswO1ji0lIGzm3KP8Y9VkS9PTE= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -gopkg.in/alecthomas/kingpin.v3-unstable v3.0.0-20191105091915-95d230a53780 h1:CEBpW6C191eozfEuWdUmIAHn7lwlLxJ7HVdr2e2Tsrw= -gopkg.in/alecthomas/kingpin.v3-unstable v3.0.0-20191105091915-95d230a53780/go.mod h1:3HH7i1SgMqlzxCcBmUHW657sD4Kvv9sC3HpL3YukzwA= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= diff --git a/internal/generate/generate_helper.go b/internal/generate/generate_helper.go index 45e653bd4..c2056f282 100644 --- a/internal/generate/generate_helper.go +++ b/internal/generate/generate_helper.go @@ -37,8 +37,11 @@ func GenerateArtifactsHelper(t *templator.Templator, cfg *config.Commit0Config, } } + log.Println(aurora.Cyan(emoji.Sprintf("Generating Terraform"))) + terraform.Generate(t, cfg, &wg, pathPrefix) + if cfg.Infrastructure.AWS.EKS.ClusterName != "" { - log.Println(aurora.Cyan(emoji.Sprintf("Generating Terraform"))) + log.Println(aurora.Cyan(emoji.Sprintf("Generating Kubernetes Configuration"))) kubernetes.Generate(t, cfg, &wg, pathPrefix) } @@ -49,9 +52,6 @@ func GenerateArtifactsHelper(t *templator.Templator, cfg *config.Commit0Config, react.Generate(t, cfg, &wg, pathPrefix) } - log.Println(aurora.Cyan(emoji.Sprintf("Generating Terraform"))) - terraform.Generate(t, cfg, &wg, pathPrefix) - util.TemplateFileIfDoesNotExist(pathPrefix, "README.md", t.Readme, &wg, templator.GenericTemplateData{*cfg}) // Wait for all the templates to be generated @@ -60,6 +60,7 @@ func GenerateArtifactsHelper(t *templator.Templator, cfg *config.Commit0Config, log.Println("Executing commands") // @TODO : Move this stuff to another command? Or genericize it a bit. if cfg.Infrastructure.AWS.EKS.Deploy { + terraform.Execute(cfg, pathPrefix) kubernetes.Execute(cfg, pathPrefix) } } diff --git a/internal/generate/kubernetes/generate.go b/internal/generate/kubernetes/generate.go index 37a26047a..569905bc8 100644 --- a/internal/generate/kubernetes/generate.go +++ b/internal/generate/kubernetes/generate.go @@ -1,260 +1,32 @@ package kubernetes import ( - "errors" - "fmt" - "io" - "io/ioutil" "log" - "os" "os/exec" - "path" "path/filepath" - "regexp" "sync" "github.com/commitdev/commit0/internal/config" "github.com/commitdev/commit0/internal/templator" "github.com/commitdev/commit0/internal/util" - "github.com/kyokomi/emoji" "github.com/logrusorgru/aurora" - "github.com/manifoldco/promptui" - "gopkg.in/yaml.v2" ) -// Secrets - AWS prompted credentials -type Secrets struct { - Aws struct { - AwsAccessKeyID string - AwsSecretAccessKey string - Region string - } -} - -// @TODO : These are specific to a k8s version. If we make the version a config option we will need to change this -var amiLookup = map[string]string{ - "us-east-1": "ami-0392bafc801b7520f", - "us-east-2": "ami-082bb518441d3954c", - "us-west-2": "ami-05d586e6f773f6abf", - "eu-west-1": "ami-059c6874350e63ca9", - "eu-central-1": "ami-0e21bc066a9dbabfa", -} - // Generate templates func Generate(t *templator.Templator, cfg *config.Commit0Config, wg *sync.WaitGroup, pathPrefix string) { - if cfg.Infrastructure.AWS.EKS.WorkerAMI == "" { - ami, found := amiLookup[cfg.Infrastructure.AWS.Region] - if !found { - log.Fatalln(aurora.Red(emoji.Sprintf(":exclamation: Unable to look up an AMI for the chosen region"))) - } - - cfg.Infrastructure.AWS.EKS.WorkerAMI = ami - } - data := templator.GenericTemplateData{Config: *cfg} + data := templator.GenericTemplateData{*cfg} t.Kubernetes.TemplateFiles(data, false, wg, pathPrefix) } // Execute terrafrom init & plan func Execute(config *config.Commit0Config, pathPrefix string) { if config.Infrastructure.AWS.EKS.Deploy { - log.Println("Preparing aws environment...") - - dir := util.GetCwd() - - if fileExists(fmt.Sprintf("%s/secrets.yaml", dir)) { - log.Println("secrets.yaml exists ...") - } else { - awsSecrets := promptCredentials() - writeSecrets(awsSecrets) - } - - envars := getAwsEnvars(readSecrets()) + envars := util.MakeAwsEnvars(util.GetSecrets()) pathPrefix = filepath.Join(pathPrefix, "kubernetes/terraform") - // @TODO : A check here would be nice to see if this stuff exists first, mostly for testing - log.Println(aurora.Cyan(emoji.Sprintf(":alarm_clock: Initializing remote backend..."))) - execute(exec.Command("terraform", "init"), filepath.Join(pathPrefix, "bootstrap/remote-state"), envars) - execute(exec.Command("terraform", "apply", "-auto-approve"), filepath.Join(pathPrefix, "bootstrap/remote-state"), envars) - - log.Println(aurora.Cyan(":alarm_clock: Planning infrastructure...")) - execute(exec.Command("terraform", "init"), filepath.Join(pathPrefix, "environments/staging"), envars) - execute(exec.Command("terraform", "plan"), filepath.Join(pathPrefix, "environments/staging"), envars) - - log.Println(aurora.Cyan(":alarm_clock: Applying infrastructure configuration...")) - execute(exec.Command("terraform", "apply"), filepath.Join(pathPrefix, "environments/staging"), envars) - log.Println(aurora.Cyan(":alarm_clock: Applying kubernetes configuration...")) - execute(exec.Command("terraform", "init"), filepath.Join(pathPrefix, "environments/staging/kubernetes"), envars) - execute(exec.Command("terraform", "plan"), filepath.Join(pathPrefix, "environments/staging/kubernetes"), envars) - } -} - -func execute(cmd *exec.Cmd, pathPrefix string, envars []string) { - dir := util.GetCwd() - - cmd.Dir = path.Join(dir, pathPrefix) - - stdoutPipe, _ := cmd.StdoutPipe() - stderrPipe, _ := cmd.StderrPipe() - - var errStdout, errStderr error - - if envars != nil { - cmd.Env = envars - } - - 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) - } -} - -func getAwsEnvars(awsSecrets Secrets) []string { - env := os.Environ() - env = append(env, fmt.Sprintf("AWS_ACCESS_KEY_ID=%s", awsSecrets.Aws.AwsAccessKeyID)) - env = append(env, fmt.Sprintf("AWS_SECRET_ACCESS_KEY=%s", awsSecrets.Aws.AwsSecretAccessKey)) - env = append(env, fmt.Sprintf("AWS_DEFAULT_REGION=%s", awsSecrets.Aws.Region)) - - return env -} - -func readSecrets() Secrets { - - dir := util.GetCwd() - - secretsFile := fmt.Sprintf("%s/secrets.yaml", dir) - - data, err := ioutil.ReadFile(secretsFile) - if err != nil { - log.Fatalln(err) - } - - awsSecrets := Secrets{} - - err = yaml.Unmarshal(data, &awsSecrets) - if err != nil { - log.Fatalln(err) - } - - return awsSecrets -} - -func writeSecrets(s Secrets) { - secretsYaml, err := yaml.Marshal(&s) - - if err != nil { - log.Fatalf("error: %v", err) - panic(err) - } - - dir := util.GetCwd() - - if err != nil { - log.Fatalf("Getting working directory failed: %v\n", err) - panic(err) - } - - secretsFile := filepath.Join(dir, "secrets.yaml") - err = ioutil.WriteFile(secretsFile, []byte(secretsYaml), 0644) - - if err != nil { - log.Fatalf("error: %v", err) - panic(err) - } -} - -func promptCredentials() Secrets { - - validateAKID := func(input string) error { - // 20 uppercase alphanumeric characters - var awsAccessKeyIDPat = regexp.MustCompile(`^[A-Z0-9]{20}$`) - if !awsAccessKeyIDPat.MatchString(input) { - return errors.New("Invalid aws_access_key_id") - } - return nil - } - - validateSAK := func(input string) error { - // 40 base64 characters - var awsSecretAccessKeyPat = regexp.MustCompile(`^[A-Za-z0-9/+=]{40}$`) - if !awsSecretAccessKeyPat.MatchString(input) { - return errors.New("Invalid aws_secret_access_key") - } - return nil - } - - accessKeyIDPrompt := promptui.Prompt{ - Label: "Aws Access Key ID ", - Validate: validateAKID, - } - - accessKeyIDResult, err := accessKeyIDPrompt.Run() - - if err != nil { - log.Fatalf("Prompt failed %v\n", err) - panic(err) - } - - secretAccessKeyPrompt := promptui.Prompt{ - Label: "Aws Secret Access Key ", - Validate: validateSAK, - Mask: '*', - } - - secretAccessKeyResult, err := secretAccessKeyPrompt.Run() - - if err != nil { - log.Fatalf("Prompt failed %v\n", err) - panic(err) - } - - regionPrompt := promptui.Select{ - Label: "Select AWS Region ", - Items: []string{"us-west-1", "us-west-2", "us-east-1", "us-east-2", "ca-central-1", - "eu-central-1", "eu-west-1", "ap-east-1", "ap-south-1"}, - } - - _, regionResult, err := regionPrompt.Run() - - if err != nil { - log.Fatalf("Prompt failed %v\n", err) - panic(err) - } - - awsSecrets := Secrets{} - awsSecrets.Aws.AwsAccessKeyID = accessKeyIDResult - awsSecrets.Aws.AwsSecretAccessKey = secretAccessKeyResult - awsSecrets.Aws.Region = regionResult - - return awsSecrets - -} - -func fileExists(filename string) bool { - info, err := os.Stat(filename) - if os.IsNotExist(err) { - return false + util.ExecuteCommand(exec.Command("terraform", "init"), filepath.Join(pathPrefix, "environments/staging/kubernetes"), envars) + util.ExecuteCommand(exec.Command("terraform", "plan"), filepath.Join(pathPrefix, "environments/staging/kubernetes"), envars) } - return !info.IsDir() } diff --git a/internal/generate/terraform/generate.go b/internal/generate/terraform/generate.go index cc29139f8..2382e07e3 100644 --- a/internal/generate/terraform/generate.go +++ b/internal/generate/terraform/generate.go @@ -1,14 +1,65 @@ package terraform import ( + "log" + "os/exec" + "path/filepath" "sync" "github.com/commitdev/commit0/internal/config" "github.com/commitdev/commit0/internal/templator" + "github.com/commitdev/commit0/internal/util" + "github.com/kyokomi/emoji" + "github.com/logrusorgru/aurora" ) +// @TODO : These are specific to a k8s version. If we make the version a config option we will need to change this +var amiLookup = map[string]string{ + "us-east-1": "ami-0392bafc801b7520f", + "us-east-2": "ami-082bb518441d3954c", + "us-west-2": "ami-05d586e6f773f6abf", + "eu-west-1": "ami-059c6874350e63ca9", + "eu-central-1": "ami-0e21bc066a9dbabfa", +} + func Generate(t *templator.Templator, cfg *config.Commit0Config, wg *sync.WaitGroup, pathPrefix string) { - data := templator.GenericTemplateData{*cfg} + if cfg.Infrastructure.AWS.EKS.WorkerAMI == "" { + ami, found := amiLookup[cfg.Infrastructure.AWS.Region] + if !found { + log.Fatalln(aurora.Red(emoji.Sprintf(":exclamation: Unable to look up an AMI for the chosen region"))) + } + + cfg.Infrastructure.AWS.EKS.WorkerAMI = ami + } + data := templator.GenericTemplateData{Config: *cfg} t.Terraform.TemplateFiles(data, false, wg, pathPrefix) } + +// Execute terrafrom init & plan +func Execute(config *config.Commit0Config, pathPrefix string) { + // @TODO : Change this check. Most likely we should discover the accountid + if config.Infrastructure.AWS.AccountId != "" { + log.Println("Preparing aws environment...") + + envars := util.MakeAwsEnvars(util.GetSecrets()) + + pathPrefix = filepath.Join(pathPrefix, "terraform") + + // @TODO : A check here would be nice to see if this stuff exists first, mostly for testing + log.Println(aurora.Cyan(emoji.Sprintf(":alarm_clock: Initializing remote backend..."))) + util.ExecuteCommand(exec.Command("terraform", "init"), filepath.Join(pathPrefix, "bootstrap/remote-state"), envars) + util.ExecuteCommand(exec.Command("terraform", "apply", "-auto-approve"), filepath.Join(pathPrefix, "bootstrap/remote-state"), envars) + + log.Println(aurora.Cyan(":alarm_clock: Planning infrastructure...")) + util.ExecuteCommand(exec.Command("terraform", "init"), filepath.Join(pathPrefix, "environments/staging"), envars) + util.ExecuteCommand(exec.Command("terraform", "plan"), filepath.Join(pathPrefix, "environments/staging"), envars) + + log.Println(aurora.Cyan(":alarm_clock: Applying infrastructure configuration...")) + util.ExecuteCommand(exec.Command("terraform", "apply"), filepath.Join(pathPrefix, "environments/staging"), envars) + + log.Println(aurora.Cyan(":alarm_clock: Applying kubernetes configuration...")) + util.ExecuteCommand(exec.Command("terraform", "init"), filepath.Join(pathPrefix, "environments/staging/kubernetes"), envars) + util.ExecuteCommand(exec.Command("terraform", "plan"), filepath.Join(pathPrefix, "environments/staging/kubernetes"), envars) + } +} diff --git a/internal/util/secrets.go b/internal/util/secrets.go new file mode 100644 index 000000000..f9c579078 --- /dev/null +++ b/internal/util/secrets.go @@ -0,0 +1,165 @@ +package util + +import ( + "errors" + "fmt" + "io/ioutil" + "log" + "os" + "path/filepath" + "regexp" + + "github.com/manifoldco/promptui" + "gopkg.in/yaml.v2" +) + +// Secrets - AWS prompted credentials +type Secrets struct { + Aws struct { + AwsAccessKeyID string + AwsSecretAccessKey string + Region string + } +} + +func MakeAwsEnvars(awsSecrets Secrets) []string { + env := os.Environ() + env = append(env, fmt.Sprintf("AWS_ACCESS_KEY_ID=%s", awsSecrets.Aws.AwsAccessKeyID)) + env = append(env, fmt.Sprintf("AWS_SECRET_ACCESS_KEY=%s", awsSecrets.Aws.AwsSecretAccessKey)) + env = append(env, fmt.Sprintf("AWS_DEFAULT_REGION=%s", awsSecrets.Aws.Region)) + + return env +} + +func GetSecrets() Secrets { + dir := GetCwd() + + if fileExists(fmt.Sprintf("%s/secrets.yaml", dir)) { + log.Println("secrets.yaml exists ...") + return readSecrets() + } else { + awsSecrets := promptCredentials() + writeSecrets(awsSecrets) + return awsSecrets + } +} + +func readSecrets() Secrets { + + dir := GetCwd() + + secretsFile := fmt.Sprintf("%s/secrets.yaml", dir) + + data, err := ioutil.ReadFile(secretsFile) + if err != nil { + log.Fatalln(err) + } + + awsSecrets := Secrets{} + + err = yaml.Unmarshal(data, &awsSecrets) + if err != nil { + log.Fatalln(err) + } + + return awsSecrets +} + +func writeSecrets(s Secrets) { + secretsYaml, err := yaml.Marshal(&s) + + if err != nil { + log.Fatalf("error: %v", err) + panic(err) + } + + dir := GetCwd() + + if err != nil { + log.Fatalf("Getting working directory failed: %v\n", err) + panic(err) + } + + secretsFile := filepath.Join(dir, "secrets.yaml") + err = ioutil.WriteFile(secretsFile, []byte(secretsYaml), 0644) + + if err != nil { + log.Fatalf("error: %v", err) + panic(err) + } +} + +func promptCredentials() Secrets { + + validateAKID := func(input string) error { + // 20 uppercase alphanumeric characters + var awsAccessKeyIDPat = regexp.MustCompile(`^[A-Z0-9]{20}$`) + if !awsAccessKeyIDPat.MatchString(input) { + return errors.New("Invalid aws_access_key_id") + } + return nil + } + + validateSAK := func(input string) error { + // 40 base64 characters + var awsSecretAccessKeyPat = regexp.MustCompile(`^[A-Za-z0-9/+=]{40}$`) + if !awsSecretAccessKeyPat.MatchString(input) { + return errors.New("Invalid aws_secret_access_key") + } + return nil + } + + accessKeyIDPrompt := promptui.Prompt{ + Label: "Aws Access Key ID ", + Validate: validateAKID, + } + + accessKeyIDResult, err := accessKeyIDPrompt.Run() + + if err != nil { + log.Fatalf("Prompt failed %v\n", err) + panic(err) + } + + secretAccessKeyPrompt := promptui.Prompt{ + Label: "Aws Secret Access Key ", + Validate: validateSAK, + Mask: '*', + } + + secretAccessKeyResult, err := secretAccessKeyPrompt.Run() + + if err != nil { + log.Fatalf("Prompt failed %v\n", err) + panic(err) + } + + regionPrompt := promptui.Select{ + Label: "Select AWS Region ", + Items: []string{"us-west-1", "us-west-2", "us-east-1", "us-east-2", "ca-central-1", + "eu-central-1", "eu-west-1", "ap-east-1", "ap-south-1"}, + } + + _, regionResult, err := regionPrompt.Run() + + if err != nil { + log.Fatalf("Prompt failed %v\n", err) + panic(err) + } + + awsSecrets := Secrets{} + awsSecrets.Aws.AwsAccessKeyID = accessKeyIDResult + awsSecrets.Aws.AwsSecretAccessKey = secretAccessKeyResult + awsSecrets.Aws.Region = regionResult + + return awsSecrets + +} + +func fileExists(filename string) bool { + info, err := os.Stat(filename) + if os.IsNotExist(err) { + return false + } + return !info.IsDir() +} diff --git a/internal/util/util.go b/internal/util/util.go index 87245931d..d2880f43f 100644 --- a/internal/util/util.go +++ b/internal/util/util.go @@ -2,8 +2,10 @@ package util import ( "fmt" + "io" "log" "os" + "os/exec" "path" "strings" "sync" @@ -82,3 +84,43 @@ func TemplateFileIfDoesNotExist(fileDir string, fileName string, template *templ log.Println(aurora.Yellow(emoji.Sprintf("%v already exists. skipping.", fullFilePath))) } } + +func ExecuteCommand(cmd *exec.Cmd, pathPrefix string, envars []string) { + dir := GetCwd() + + cmd.Dir = path.Join(dir, pathPrefix) + + stdoutPipe, _ := cmd.StdoutPipe() + stderrPipe, _ := cmd.StderrPipe() + + var errStdout, errStderr error + + if envars != nil { + cmd.Env = envars + } + + err := cmd.Start() + if err != nil { + log.Fatalf("Starting 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 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) + } +} diff --git a/templates/kubernetes/terraform/environments/development/main.tf b/templates/kubernetes/terraform/environments/development/main.tf index 3083063de..552440f1b 100644 --- a/templates/kubernetes/terraform/environments/development/main.tf +++ b/templates/kubernetes/terraform/environments/development/main.tf @@ -1,7 +1,7 @@ terraform { backend "s3" { bucket = "project-{{ .Config.Name }}-terraform-state" - key = "infrastructure/terraform/environments/development/main" + key = "infrastructure/terraform/environments/development/kubernetes" encrypt = true region = "{{ .Config.Infrastructure.AWS.Region }}" dynamodb_table = "{{ .Config.Name }}-terraform-state-locks" diff --git a/templates/kubernetes/terraform/environments/production/kubernetes/main.tf b/templates/kubernetes/terraform/environments/production/kubernetes/main.tf deleted file mode 100644 index 39e4e34a7..000000000 --- a/templates/kubernetes/terraform/environments/production/kubernetes/main.tf +++ /dev/null @@ -1,37 +0,0 @@ -terraform { - backend "s3" { - bucket = "project-{{ .Config.Name }}-terraform-state" - key = "infrastructure/terraform/environments/production/main" - encrypt = true - region = "{{ .Config.Infrastructure.AWS.Region }}" - dynamodb_table = "{{ .Config.Name }}-terraform-state-locks" - } -} - -# Provision kubernetes resources required to run services/applications -module "kubernetes" { - source = "../../../modules/kubernetes" - - environment = "production" - region = "{{ .Config.Infrastructure.AWS.Region }}" - - # Authenticate with the EKS cluster via the cluster id - cluster_name = "{{ .Config.Infrastructure.AWS.EKS.ClusterName }}" - - # Assume-role policy used by monitoring fluentd daemonset - assume_role_policy = data.aws_iam_policy_document.assumerole_root_policy.json -} - -# Data sources for EKS IAM -data "aws_caller_identity" "current" {} - -data "aws_iam_policy_document" "assumerole_root_policy" { - statement { - actions = ["sts:AssumeRole"] - - principals { - type = "AWS" - identifiers = ["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"] - } - } -} diff --git a/templates/kubernetes/terraform/environments/production/main.tf b/templates/kubernetes/terraform/environments/production/main.tf index ce83256fc..9a394bf15 100644 --- a/templates/kubernetes/terraform/environments/production/main.tf +++ b/templates/kubernetes/terraform/environments/production/main.tf @@ -1,31 +1,37 @@ terraform { backend "s3" { bucket = "project-{{ .Config.Name }}-terraform-state" - key = "infrastructure/terraform/environments/production/main" + key = "infrastructure/terraform/environments/production/kubernetes" encrypt = true region = "{{ .Config.Infrastructure.AWS.Region }}" dynamodb_table = "{{ .Config.Name }}-terraform-state-locks" } } -# Instantiate the production environment -module "production" { - source = "../../modules/environment" +# Provision kubernetes resources required to run services/applications +module "kubernetes" { + source = "../../modules/kubernetes" + environment = "production" + region = "{{ .Config.Infrastructure.AWS.Region }}" + + # Authenticate with the EKS cluster via the cluster id + cluster_name = "{{ .Config.Infrastructure.AWS.EKS.ClusterName }}" - # Project configuration - project = "{{ .Config.Infrastructure.AWS.EKS.ClusterName }}" - region = "{{ .Config.Infrastructure.AWS.Region }}" - allowed_account_ids = ["{{ .Config.Infrastructure.AWS.AccountId }}"] + # Assume-role policy used by monitoring fluentd daemonset + assume_role_policy = data.aws_iam_policy_document.assumerole_root_policy.json +} - # ECR configuration - ecr_repositories = ["{{ .Config.Infrastructure.AWS.EKS.ClusterName }}"] +# Data sources for EKS IAM +data "aws_caller_identity" "current" {} - # EKS configuration - eks_worker_instance_type = "m4.large" - eks_worker_asg_max_size = 3 +data "aws_iam_policy_document" "assumerole_root_policy" { + statement { + actions = ["sts:AssumeRole"] - # 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 = "{{ .Config.Infrastructure.AWS.EKS.WorkerAMI }}" + principals { + type = "AWS" + identifiers = ["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"] + } + } } diff --git a/templates/kubernetes/terraform/environments/staging/kubernetes/main.tf b/templates/kubernetes/terraform/environments/staging/kubernetes/main.tf deleted file mode 100644 index 5a4d0d706..000000000 --- a/templates/kubernetes/terraform/environments/staging/kubernetes/main.tf +++ /dev/null @@ -1,37 +0,0 @@ -terraform { - backend "s3" { - bucket = "project-{{ .Config.Name }}-terraform-state" - key = "infrastructure/terraform/environments/staging/kubernetes" - encrypt = true - region = "{{ .Config.Infrastructure.AWS.Region }}" - dynamodb_table = "{{ .Config.Name }}-terraform-state-locks" - } -} - -# Provision kubernetes resources required to run services/applications -module "kubernetes" { - source = "../../../modules/kubernetes" - - environment = "staging" - region = "{{ .Config.Infrastructure.AWS.Region }}" - - # Authenticate with the EKS cluster via the cluster id - cluster_name = "{{ .Config.Infrastructure.AWS.EKS.ClusterName }}" - - # Assume-role policy used by monitoring fluentd daemonset - assume_role_policy = data.aws_iam_policy_document.assumerole_root_policy.json -} - -# Data sources for EKS IAM -data "aws_caller_identity" "current" {} - -data "aws_iam_policy_document" "assumerole_root_policy" { - statement { - actions = ["sts:AssumeRole"] - - principals { - type = "AWS" - identifiers = ["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"] - } - } -} diff --git a/templates/kubernetes/terraform/environments/staging/main.tf b/templates/kubernetes/terraform/environments/staging/main.tf index e23628e52..ab3ce52f7 100644 --- a/templates/kubernetes/terraform/environments/staging/main.tf +++ b/templates/kubernetes/terraform/environments/staging/main.tf @@ -1,32 +1,37 @@ terraform { backend "s3" { bucket = "project-{{ .Config.Name }}-terraform-state" - key = "infrastructure/terraform/environments/staging/main" + key = "infrastructure/terraform/environments/staging/kubernetes" encrypt = true region = "{{ .Config.Infrastructure.AWS.Region }}" dynamodb_table = "{{ .Config.Name }}-terraform-state-locks" } } -# Instantiate the staging environment -module "staging" { - source = "../../modules/environment" +# Provision kubernetes resources required to run services/applications +module "kubernetes" { + source = "../../modules/kubernetes" + environment = "staging" + region = "{{ .Config.Infrastructure.AWS.Region }}" - # Project configuration - project = "{{ .Config.Infrastructure.AWS.EKS.ClusterName }}" - region = "{{ .Config.Infrastructure.AWS.Region }}" - allowed_account_ids = ["{{ .Config.Infrastructure.AWS.AccountId }}"] + # Authenticate with the EKS cluster via the cluster id + cluster_name = "{{ .Config.Infrastructure.AWS.EKS.ClusterName }}" - # ECR configuration - ecr_repositories = ["{{ .Config.Infrastructure.AWS.EKS.ClusterName }}"] + # Assume-role policy used by monitoring fluentd daemonset + assume_role_policy = data.aws_iam_policy_document.assumerole_root_policy.json +} - # EKS configuration - eks_worker_instance_type = "t2.small" - eks_worker_asg_max_size = 2 +# Data sources for EKS IAM +data "aws_caller_identity" "current" {} - # 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 = "{{ .Config.Infrastructure.AWS.EKS.WorkerAMI }}" +data "aws_iam_policy_document" "assumerole_root_policy" { + statement { + actions = ["sts:AssumeRole"] + principals { + type = "AWS" + identifiers = ["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"] + } + } } diff --git a/templates/kubernetes/terraform/README.md b/templates/terraform/README.md similarity index 100% rename from templates/kubernetes/terraform/README.md rename to templates/terraform/README.md diff --git a/templates/kubernetes/terraform/bootstrap/remote-state/main.tf b/templates/terraform/bootstrap/remote-state/main.tf similarity index 100% rename from templates/kubernetes/terraform/bootstrap/remote-state/main.tf rename to templates/terraform/bootstrap/remote-state/main.tf diff --git a/templates/kubernetes/terraform/environments/development/kubernetes/main.tf b/templates/terraform/environments/development/main.tf similarity index 89% rename from templates/kubernetes/terraform/environments/development/kubernetes/main.tf rename to templates/terraform/environments/development/main.tf index 9e3d5e20d..439d876d2 100644 --- a/templates/kubernetes/terraform/environments/development/kubernetes/main.tf +++ b/templates/terraform/environments/development/main.tf @@ -1,4 +1,5 @@ terraform { + required_version = ">= 0.12" backend "s3" { bucket = "project-{{ .Config.Name }}-terraform-state" key = "infrastructure/terraform/environments/development/main" @@ -10,7 +11,7 @@ terraform { # Instantiate the development environment module "development" { - source = "../../../modules/environment" + source = "../../modules/environment" environment = "development" # Project configuration @@ -18,6 +19,7 @@ module "development" { region = "{{ .Config.Infrastructure.AWS.Region }}" allowed_account_ids = ["{{ .Config.Infrastructure.AWS.AccountId }}"] + {{- if ne .Config.Infrastructure.AWS.EKS.ClusterName "" }} # ECR configuration ecr_repositories = ["{{ .Config.Infrastructure.AWS.EKS.ClusterName }}"] @@ -28,5 +30,6 @@ module "development" { # 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 = "{{ .Config.Infrastructure.AWS.EKS.WorkerAMI }}" + {{- end }} } diff --git a/templates/terraform/environments/production.tfvars b/templates/terraform/environments/production.tfvars deleted file mode 100644 index e69de29bb..000000000 diff --git a/templates/terraform/environments/production/main.tf b/templates/terraform/environments/production/main.tf new file mode 100644 index 000000000..615bff2ab --- /dev/null +++ b/templates/terraform/environments/production/main.tf @@ -0,0 +1,34 @@ +terraform { + required_version = ">= 0.12" + backend "s3" { + bucket = "project-{{ .Config.Name }}-terraform-state" + key = "infrastructure/terraform/environments/production/main" + encrypt = true + region = "{{ .Config.Infrastructure.AWS.Region }}" + dynamodb_table = "{{ .Config.Name }}-terraform-state-locks" + } +} + +# Instantiate the production environment +module "production" { + source = "../../modules/environment" + environment = "production" + + # Project configuration + project = "{{ .Config.Infrastructure.AWS.EKS.ClusterName }}" + region = "{{ .Config.Infrastructure.AWS.Region }}" + allowed_account_ids = ["{{ .Config.Infrastructure.AWS.AccountId }}"] + + {{- if ne .Config.Infrastructure.AWS.EKS.ClusterName "" }} + # ECR configuration + ecr_repositories = ["{{ .Config.Infrastructure.AWS.EKS.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 = "{{ .Config.Infrastructure.AWS.EKS.WorkerAMI }}" + {{- end }} +} diff --git a/templates/terraform/environments/staging.tfvars b/templates/terraform/environments/staging.tfvars deleted file mode 100644 index e69de29bb..000000000 diff --git a/templates/terraform/environments/staging/main.tf b/templates/terraform/environments/staging/main.tf new file mode 100644 index 000000000..fe42920a2 --- /dev/null +++ b/templates/terraform/environments/staging/main.tf @@ -0,0 +1,35 @@ +terraform { + required_version = ">= 0.12" + backend "s3" { + bucket = "project-{{ .Config.Name }}-terraform-state" + key = "infrastructure/terraform/environments/staging/main" + encrypt = true + region = "{{ .Config.Infrastructure.AWS.Region }}" + dynamodb_table = "{{ .Config.Name }}-terraform-state-locks" + } +} + +# Instantiate the staging environment +module "staging" { + source = "../../modules/environment" + environment = "staging" + + # Project configuration + project = "{{ .Config.Infrastructure.AWS.EKS.ClusterName }}" + region = "{{ .Config.Infrastructure.AWS.Region }}" + allowed_account_ids = ["{{ .Config.Infrastructure.AWS.AccountId }}"] + + {{- if ne .Config.Infrastructure.AWS.EKS.ClusterName "" }} + # ECR configuration + ecr_repositories = ["{{ .Config.Infrastructure.AWS.EKS.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 = "{{ .Config.Infrastructure.AWS.EKS.WorkerAMI }}" + {{- end }} + +} diff --git a/templates/terraform/global/remote-state/main.tf b/templates/terraform/global/remote-state/main.tf deleted file mode 100644 index cea38fef4..000000000 --- a/templates/terraform/global/remote-state/main.tf +++ /dev/null @@ -1,4 +0,0 @@ -provider "aws" { - region = "${ var.region }" -} - diff --git a/templates/terraform/global/remote-state/terraform.tfvars b/templates/terraform/global/remote-state/terraform.tfvars deleted file mode 100644 index bf85a742a..000000000 --- a/templates/terraform/global/remote-state/terraform.tfvars +++ /dev/null @@ -1 +0,0 @@ -region = "{{ .Config.Infrastructure.AWS.Region }}" diff --git a/templates/terraform/global/remote-state/variables.tf b/templates/terraform/global/remote-state/variables.tf deleted file mode 100644 index daef22220..000000000 --- a/templates/terraform/global/remote-state/variables.tf +++ /dev/null @@ -1,11 +0,0 @@ -variable "region" { - description = "The AWS region" -} - -variable "remote_state_s3_bucket" { - description = "Name of the S3 bucket to store the remote state" -} - -variable "remote_state_dynamo_table" { - description = "Dynamo DB Table to store the remote state locks" -} \ No newline at end of file diff --git a/templates/terraform/main.tf b/templates/terraform/main.tf deleted file mode 100644 index 2ad3d8af9..000000000 --- a/templates/terraform/main.tf +++ /dev/null @@ -1,64 +0,0 @@ -provider "aws" { - region = "${var.region}" -} - -# {{ if .Config.Infrastructure.AWS.Terraform.RemoteState }} -# Store remote state in S3 -resource "aws_s3_bucket" "terraform_remote_state" { - bucket = "${ var.remote_state_s3_bucket }" - acl = "private" - - versioning { - enabled = true - } -} - -resource "aws_dynamodb_table" "terraform_state_locks" { - name = "${ var.remote_state_dynamo_table }" - read_capacity = 2 - write_capacity = 2 - hash_key = "LockID" - - attribute { - name = "LockID" - type = "S" - } -} - -# Reference the remote state -terraform { - backend "s3" { - bucket = "${var.remote_state_s3_bucket}" - key = "infrastructure/terraform/shared" - encrypt = true - region = "${var.region}" - dynamodb_table = "${var.remote_state_dynamo_table}" - } -} -# {{- end}} -# {{ if .Config.Infrastructure.AWS.Cognito }} -# ref: https://github.com/squidfunk/terraform-aws-cognito-auth#usage - -# data "aws_acm_certificate" "wildcard_cert" { -# domain = "*.${var.public_dns_zone}" -# } - -module "cognito-auth" { - source = "squidfunk/cognito-auth/aws" - version = "0.4.2" - - namespace = "${var.auth_namespace}" - region = "${var.region}" - cognito_identity_pool_name = "${var.auth_pool_name}" - cognito_identity_pool_provider = "${var.auth_pool_provider}" - - # Optional: Default UI - # app_hosted_zone_id = "" - # app_certificate_arn = "${data.aws_acm_certificate.wildcard_cert.arn}" - # app_domain = "" - # app_origin = "" - - # Optional: Email delivery - # ses_sender_address = "" -} -# {{- end}} diff --git a/templates/kubernetes/terraform/modules/ecr/main.tf b/templates/terraform/modules/ecr/main.tf similarity index 100% rename from templates/kubernetes/terraform/modules/ecr/main.tf rename to templates/terraform/modules/ecr/main.tf diff --git a/templates/kubernetes/terraform/modules/ecr/variables.tf b/templates/terraform/modules/ecr/variables.tf similarity index 100% rename from templates/kubernetes/terraform/modules/ecr/variables.tf rename to templates/terraform/modules/ecr/variables.tf diff --git a/templates/kubernetes/terraform/modules/ecr/versions.tf b/templates/terraform/modules/ecr/versions.tf similarity index 100% rename from templates/kubernetes/terraform/modules/ecr/versions.tf rename to templates/terraform/modules/ecr/versions.tf diff --git a/templates/kubernetes/terraform/modules/eks/main.tf b/templates/terraform/modules/eks/main.tf similarity index 100% rename from templates/kubernetes/terraform/modules/eks/main.tf rename to templates/terraform/modules/eks/main.tf diff --git a/templates/kubernetes/terraform/modules/eks/outputs.tf b/templates/terraform/modules/eks/outputs.tf similarity index 100% rename from templates/kubernetes/terraform/modules/eks/outputs.tf rename to templates/terraform/modules/eks/outputs.tf diff --git a/templates/kubernetes/terraform/modules/eks/variables.tf b/templates/terraform/modules/eks/variables.tf similarity index 100% rename from templates/kubernetes/terraform/modules/eks/variables.tf rename to templates/terraform/modules/eks/variables.tf diff --git a/templates/kubernetes/terraform/modules/eks/versions.tf b/templates/terraform/modules/eks/versions.tf similarity index 100% rename from templates/kubernetes/terraform/modules/eks/versions.tf rename to templates/terraform/modules/eks/versions.tf diff --git a/templates/kubernetes/terraform/modules/environment/main.tf b/templates/terraform/modules/environment/main.tf similarity index 61% rename from templates/kubernetes/terraform/modules/environment/main.tf rename to templates/terraform/modules/environment/main.tf index 041069501..44d495cca 100644 --- a/templates/kubernetes/terraform/modules/environment/main.tf +++ b/templates/terraform/modules/environment/main.tf @@ -42,3 +42,32 @@ module "kube2iam" { eks_worker_iam_role_name = module.eks.worker_iam_role_name iam_account_id = data.aws_caller_identity.current.account_id } + +# @TODO - Move this to a different file + +# {{ if .Config.Infrastructure.AWS.Cognito }} +# ref: https://github.com/squidfunk/terraform-aws-cognito-auth#usage + +# data "aws_acm_certificate" "wildcard_cert" { +# domain = "*.${var.public_dns_zone}" +# } + +module "cognito-auth" { + source = "squidfunk/cognito-auth/aws" + version = "0.4.2" + + namespace = "${var.auth_namespace}" + region = "${var.region}" + cognito_identity_pool_name = "${var.auth_pool_name}" + cognito_identity_pool_provider = "${var.auth_pool_provider}" + + # Optional: Default UI + # app_hosted_zone_id = "" + # app_certificate_arn = "${data.aws_acm_certificate.wildcard_cert.arn}" + # app_domain = "" + # app_origin = "" + + # Optional: Email delivery + # ses_sender_address = "" +} +# {{- end}} diff --git a/templates/kubernetes/terraform/modules/environment/provider.tf b/templates/terraform/modules/environment/provider.tf similarity index 100% rename from templates/kubernetes/terraform/modules/environment/provider.tf rename to templates/terraform/modules/environment/provider.tf diff --git a/templates/kubernetes/terraform/modules/environment/variables.tf b/templates/terraform/modules/environment/variables.tf similarity index 75% rename from templates/kubernetes/terraform/modules/environment/variables.tf rename to templates/terraform/modules/environment/variables.tf index 1bdc31c45..0af197fe8 100644 --- a/templates/kubernetes/terraform/modules/environment/variables.tf +++ b/templates/terraform/modules/environment/variables.tf @@ -31,3 +31,15 @@ variable "eks_worker_asg_max_size" { variable "eks_worker_ami" { description = "The (EKS-optimized) AMI for EKS worker instances" } + +# {{ if .Config.Infrastructure.AWS.Cognito }} +variable "auth_namespace" { + default = "cognito_auth" +} +variable "auth_pool_name" { + description = "AWS Cognito pool name" +} +variable "auth_pool_provider" { + description = "AWS Cognito pool provider" +} +# {{- end}} diff --git a/templates/kubernetes/terraform/modules/environment/versions.tf b/templates/terraform/modules/environment/versions.tf similarity index 100% rename from templates/kubernetes/terraform/modules/environment/versions.tf rename to templates/terraform/modules/environment/versions.tf diff --git a/templates/kubernetes/terraform/modules/kube2iam/README.md b/templates/terraform/modules/kube2iam/README.md similarity index 100% rename from templates/kubernetes/terraform/modules/kube2iam/README.md rename to templates/terraform/modules/kube2iam/README.md diff --git a/templates/kubernetes/terraform/modules/kube2iam/main.tf b/templates/terraform/modules/kube2iam/main.tf similarity index 100% rename from templates/kubernetes/terraform/modules/kube2iam/main.tf rename to templates/terraform/modules/kube2iam/main.tf diff --git a/templates/kubernetes/terraform/modules/kube2iam/variables.tf b/templates/terraform/modules/kube2iam/variables.tf similarity index 100% rename from templates/kubernetes/terraform/modules/kube2iam/variables.tf rename to templates/terraform/modules/kube2iam/variables.tf diff --git a/templates/kubernetes/terraform/modules/kube2iam/versions.tf b/templates/terraform/modules/kube2iam/versions.tf similarity index 100% rename from templates/kubernetes/terraform/modules/kube2iam/versions.tf rename to templates/terraform/modules/kube2iam/versions.tf diff --git a/templates/kubernetes/terraform/modules/vpc/main.tf b/templates/terraform/modules/vpc/main.tf similarity index 100% rename from templates/kubernetes/terraform/modules/vpc/main.tf rename to templates/terraform/modules/vpc/main.tf diff --git a/templates/kubernetes/terraform/modules/vpc/outputs.tf b/templates/terraform/modules/vpc/outputs.tf similarity index 100% rename from templates/kubernetes/terraform/modules/vpc/outputs.tf rename to templates/terraform/modules/vpc/outputs.tf diff --git a/templates/kubernetes/terraform/modules/vpc/variables.tf b/templates/terraform/modules/vpc/variables.tf similarity index 100% rename from templates/kubernetes/terraform/modules/vpc/variables.tf rename to templates/terraform/modules/vpc/variables.tf diff --git a/templates/kubernetes/terraform/modules/vpc/versions.tf b/templates/terraform/modules/vpc/versions.tf similarity index 100% rename from templates/kubernetes/terraform/modules/vpc/versions.tf rename to templates/terraform/modules/vpc/versions.tf diff --git a/templates/terraform/variables.tf b/templates/terraform/variables.tf deleted file mode 100644 index 44136049a..000000000 --- a/templates/terraform/variables.tf +++ /dev/null @@ -1,27 +0,0 @@ -variable "region" { - default = "{{ .Config.Infrastructure.AWS.Region }}" - description = "The AWS region" -} - -# {{ if .Config.Infrastructure.AWS.Terraform.RemoteState }} -variable "remote_state_s3_bucket" { - default = "project-{{ .Config.Name }}-terraform-state" - description = "Name of the S3 bucket to store the remote state" -} - -variable "remote_state_dynamo_table" { - default = "{{ .Config.Name }}-terraform-state-locks" - description = "Dynamo DB Table to store the remote state locks" -} -# {{- end}} -# {{ if .Config.Infrastructure.AWS.Cognito }} -variable "auth_namespace" { - default = "cognito_auth" -} -variable "auth_pool_name" { - description = "AWS Cognito pool name" -} -variable "auth_pool_provider" { - description = "AWS Cognito pool provider" -} -# {{- end}} diff --git a/templates/terraform/versions.tf b/templates/terraform/versions.tf deleted file mode 100644 index ac97c6ac8..000000000 --- a/templates/terraform/versions.tf +++ /dev/null @@ -1,4 +0,0 @@ - -terraform { - required_version = ">= 0.12" -}