Skip to content

Commit

Permalink
Merge pull request #88 from commitdev/pull-in-improvements
Browse files Browse the repository at this point in the history
Updated templates and code to reflect newest best state from aplayr a…
  • Loading branch information
bmonkman committed Dec 17, 2019
2 parents 9b04662 + 0f5e375 commit c04455b
Show file tree
Hide file tree
Showing 24 changed files with 431 additions and 134 deletions.
1 change: 1 addition & 0 deletions go.mod
Expand Up @@ -9,6 +9,7 @@ require (
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/google/uuid v1.1.1
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
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Expand Up @@ -26,6 +26,8 @@ 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/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
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=
Expand Down
4 changes: 2 additions & 2 deletions internal/generate/generate_helper.go
Expand Up @@ -18,12 +18,12 @@ import (

func GenerateArtifactsHelper(t *templator.Templator, cfg *config.Commit0Config, pathPrefix string, runInit bool, runApply bool) {
var wg sync.WaitGroup
if !util.ValidateLanguage(cfg.Frontend.Framework) {
if cfg.Frontend.Framework != "" && !util.ValidateLanguage(cfg.Frontend.Framework) {
log.Fatalln(aurora.Red(emoji.Sprintf(":exclamation: '%s' is not a supported framework.", cfg.Frontend.Framework)))
}

for _, s := range cfg.Services {
if !util.ValidateLanguage(cfg.Frontend.Framework) {
if !util.ValidateLanguage(s.Language) {
log.Fatalln(aurora.Red(emoji.Sprintf(":exclamation: '%s' in service '%s' is not a supported language.", s.Name, s.Language)))
}
}
Expand Down
14 changes: 8 additions & 6 deletions internal/generate/terraform/generate.go
Expand Up @@ -17,11 +17,11 @@ import (

// @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",
"us-east-1": "ami-07d6c8e62ce328a10",
"us-east-2": "ami-053250833d1030033",
"us-west-2": "ami-07be7092831897fd6",
"eu-west-1": "ami-02dca57ad67c7bf57",
"eu-central-1": "ami-03fbd442f4f3aa689",
}

func Generate(t *templator.Templator, cfg *config.Commit0Config, wg *sync.WaitGroup, pathPrefix string) {
Expand Down Expand Up @@ -68,7 +68,9 @@ func Init(cfg *config.Commit0Config, pathPrefix string) {
// @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)
// @TODO : Properly loop through environments when we support that
util.ExecuteCommand(exec.Command("terraform", "apply", "-auto-approve", "-var", "environment=staging", "-state-out=staging.tfstate"), filepath.Join(pathPrefix, "bootstrap/remote-state"), envars)
util.ExecuteCommand(exec.Command("terraform", "apply", "-auto-approve", "-var", "environment=production", "-state-out=staging.tfstate"), filepath.Join(pathPrefix, "bootstrap/remote-state"), envars)

log.Println("Creating users...")
util.ExecuteCommand(exec.Command("terraform", "init"), filepath.Join(pathPrefix, "bootstrap/create-users"), envars)
Expand Down
2 changes: 2 additions & 0 deletions internal/util/util.go
Expand Up @@ -12,6 +12,7 @@ import (
"text/template"

"github.com/kyokomi/emoji"
"github.com/google/uuid"
"github.com/logrusorgru/aurora"
)

Expand All @@ -31,6 +32,7 @@ var FuncMap = template.FuncMap{
"Title": strings.Title,
"ToLower": strings.ToLower,
"CleanGoIdentifier": CleanGoIdentifier,
"GenerateUUID": uuid.New,
}

func GetCwd() string {
Expand Down
6 changes: 4 additions & 2 deletions templates/commit0/commit0.tmpl
Expand Up @@ -19,11 +19,13 @@ infrastructure:
enabled: true

frontend:
framework: {{.FrontendFramework}}
framework: {{.FrontendFramework }}
ci:
system: github
app:
name: {{.ProjectName}}
name: {{.ProjectName }}
app:
name: {{.FrontendHostname }}

services:
{{range .Services}}
Expand Down
@@ -1,10 +1,10 @@
terraform {
backend "s3" {
bucket = "project-{{ .Config.Name }}-terraform-state"
bucket = "{{ .Config.Name }}-development-terraform-state"
key = "infrastructure/terraform/environments/development/kubernetes"
encrypt = true
region = "{{ .Config.Infrastructure.AWS.Region }}"
dynamodb_table = "{{ .Config.Name }}-terraform-state-locks"
dynamodb_table = "{{ .Config.Name }}-development-terraform-state-locks"
}
}

Expand All @@ -20,6 +20,10 @@ module "kubernetes" {

# Assume-role policy used by monitoring fluentd daemonset
assume_role_policy = data.aws_iam_policy_document.assumerole_root_policy.json

external_dns_zone = "{{ .Config.Frontend.Hostname }}"
external_dns_owner_id = "{{ GenerateUUID }}"
external_dns_assume_roles = [ "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/k8s-{{ .Config.Infrastructure.AWS.EKS.ClusterName }}-workers" ]
}

# Data sources for EKS IAM
Expand Down
@@ -1,10 +1,10 @@
terraform {
backend "s3" {
bucket = "project-{{ .Config.Name }}-terraform-state"
bucket = "{{ .Config.Name }}-production-terraform-state"
key = "infrastructure/terraform/environments/production/kubernetes"
encrypt = true
region = "{{ .Config.Infrastructure.AWS.Region }}"
dynamodb_table = "{{ .Config.Name }}-terraform-state-locks"
dynamodb_table = "{{ .Config.Name }}-production-terraform-state-locks"
}
}

Expand All @@ -20,6 +20,10 @@ module "kubernetes" {

# Assume-role policy used by monitoring fluentd daemonset
assume_role_policy = data.aws_iam_policy_document.assumerole_root_policy.json

external_dns_zone = "{{ .Config.Frontend.Hostname }}"
external_dns_owner_id = "{{ GenerateUUID }}"
external_dns_assume_roles = [ "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/k8s-{{ .Config.Infrastructure.AWS.EKS.ClusterName }}-workers" ]
}

# Data sources for EKS IAM
Expand Down
8 changes: 6 additions & 2 deletions templates/kubernetes/terraform/environments/staging/main.tf
@@ -1,10 +1,10 @@
terraform {
backend "s3" {
bucket = "project-{{ .Config.Name }}-terraform-state"
bucket = "{{ .Config.Name }}-staging-terraform-state"
key = "infrastructure/terraform/environments/staging/kubernetes"
encrypt = true
region = "{{ .Config.Infrastructure.AWS.Region }}"
dynamodb_table = "{{ .Config.Name }}-terraform-state-locks"
dynamodb_table = "{{ .Config.Name }}-staging-terraform-state-locks"
}
}

Expand All @@ -20,6 +20,10 @@ module "kubernetes" {

# Assume-role policy used by monitoring fluentd daemonset
assume_role_policy = data.aws_iam_policy_document.assumerole_root_policy.json

external_dns_zone = "{{ .Config.Frontend.Hostname }}"
external_dns_owner_id = "{{ GenerateUUID }}"
external_dns_assume_roles = [ "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/k8s-{{ .Config.Infrastructure.AWS.EKS.ClusterName }}-workers" ]
}

# Data sources for EKS IAM
Expand Down
143 changes: 143 additions & 0 deletions templates/kubernetes/terraform/modules/kubernetes/external_dns.tf
@@ -0,0 +1,143 @@
# Trust relationship
data "aws_iam_policy_document" "external_dns_trust_relationship" {
statement {
actions = ["sts:AssumeRole"]

principals {
type = "Service"
identifiers = ["ec2.amazonaws.com"]
}
}

statement {
actions = ["sts:AssumeRole"]

principals {
type = "AWS"
identifiers = var.external_dns_assume_roles
}
}
}

# external-dns role
resource "aws_iam_role" "external_dns_role" {
name = "k8s-external-dns-role"
assume_role_policy = data.aws_iam_policy_document.external_dns_trust_relationship.json
}

data "aws_iam_policy_document" "external_dns_policy_doc" {
statement {
sid = "k8sExternalDnsRead"
effect = "Allow"

actions = [
"route53:ListHostedZones",
"route53:ListResourceRecordSets",
]

resources = ["*"]
}

statement {
sid = "k8sExternalDnsWrite"
effect = "Allow"

actions = ["route53:ChangeResourceRecordSets"]

resources = ["arn:aws:route53:::hostedzone/*"]
}
}

resource "aws_iam_role_policy" "external_dns_policy" {
name = "k8s-external-dns-policy"
role = aws_iam_role.external_dns_role.id
policy = data.aws_iam_policy_document.external_dns_policy_doc.json
}

resource "kubernetes_service_account" "external_dns" {
metadata {
name = "external-dns"
namespace = "kube-system"
}
}

resource "kubernetes_cluster_role" "external_dns" {
metadata {
name = "external-dns"
}
rule {
verbs = ["get", "list", "watch"]
api_groups = [""]
resources = ["pods", "services"]
}
rule {
verbs = ["get", "list", "watch"]
api_groups = ["extensions"]
resources = ["ingresses"]
}
rule {
verbs = ["list"]
api_groups = [""]
resources = ["nodes"]
}
}

resource "kubernetes_cluster_role_binding" "external_dns" {
metadata {
name = "external-dns"
}
subject {
kind = "ServiceAccount"
name = "external-dns"
namespace = "kube-system"
}
role_ref {
api_group = "rbac.authorization.k8s.io"
kind = "ClusterRole"
name = "external-dns"
}
}

resource "kubernetes_deployment" "external_dns" {
metadata {
name = "external-dns"
namespace = "kube-system"
}
spec {
replicas = 1
selector {
match_labels = {
"app" = "external-dns",
}
}
template {
metadata {
labels = {
"app" = "external-dns",
}
annotations = {
"iam.amazonaws.com/role" = "k8s-external-dns-role",
}
}
spec {
container {
name = "external-dns"
image = "registry.opensource.zalan.do/teapot/external-dns:latest"
args = [
"--source=service",
"--source=ingress",
"--domain-filter=${var.external_dns_zone}", # Give access only to the specified zone
"--provider=aws",
"--aws-zone-type=public",
"--policy=upsert-only", # Prevent ExternalDNS from deleting any records
"--registry=txt",
"--txt-owner-id=${var.external_dns_owner_id}", # ID of txt record to manage state
]
}

service_account_name = "external-dns"
automount_service_account_token = true
}
}
}
}
Expand Up @@ -89,7 +89,7 @@ resource "kubernetes_daemonset" "kube2iam" {
# }
env {
name = "AWS_REGION"
value = var.environment
value = var.region
}
security_context {
privileged = true
Expand Down
15 changes: 14 additions & 1 deletion templates/kubernetes/terraform/modules/kubernetes/variables.tf
Expand Up @@ -12,4 +12,17 @@ variable "cluster_name" {

variable "assume_role_policy" {
description = "Assume-role policy for monitoring"
}
}

variable "external_dns_zone" {
description = "R53 zone that external-dns will have access to"
}

variable "external_dns_owner_id" {
description = "Unique id of the TXT record that external-dns will use to store state (can just be a uuid)"
}

variable "external_dns_assume_roles" {
type = "list"
description = "List of roles that should be able to assume the external dns role (most likely the role of the cluster worker nodes)"
}
11 changes: 7 additions & 4 deletions templates/terraform/bootstrap/remote-state/main.tf
Expand Up @@ -3,7 +3,7 @@ provider "aws" {
}

resource "aws_s3_bucket" "terraform_remote_state" {
bucket = "project-{{ .Config.Name }}-terraform-state"
bucket = "{{ .Config.Name }}-${var.environment}-terraform-state"
acl = "private"

versioning {
Expand All @@ -12,8 +12,7 @@ resource "aws_s3_bucket" "terraform_remote_state" {
}

resource "aws_s3_bucket_public_access_block" "terraform_remote_state" {
bucket = "${aws_s3_bucket.terraform_remote_state.id}"

bucket = aws_s3_bucket.terraform_remote_state.id

block_public_acls = true
block_public_policy = true
Expand All @@ -22,7 +21,7 @@ resource "aws_s3_bucket_public_access_block" "terraform_remote_state" {
}

resource "aws_dynamodb_table" "terraform_state_locks" {
name = "{{ .Config.Name }}-terraform-state-locks"
name = "{{ .Config.Name }}-${var.environment}-terraform-state-locks"
read_capacity = 2
write_capacity = 2
hash_key = "LockID"
Expand All @@ -32,3 +31,7 @@ resource "aws_dynamodb_table" "terraform_state_locks" {
type = "S"
}
}

variable "environment" {
description = "The environment (development/staging/production)"
}

0 comments on commit c04455b

Please sign in to comment.