diff --git a/go.mod b/go.mod index 2073c39c9..8abf4f0ad 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum index 3f777d374..64b7e0de4 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/internal/generate/generate_helper.go b/internal/generate/generate_helper.go index f1fb24957..bba082b18 100644 --- a/internal/generate/generate_helper.go +++ b/internal/generate/generate_helper.go @@ -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))) } } diff --git a/internal/generate/terraform/generate.go b/internal/generate/terraform/generate.go index 7b46c24c1..fee8d78af 100644 --- a/internal/generate/terraform/generate.go +++ b/internal/generate/terraform/generate.go @@ -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) { @@ -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) diff --git a/internal/util/util.go b/internal/util/util.go index 855b5e48a..9c8e5bbce 100644 --- a/internal/util/util.go +++ b/internal/util/util.go @@ -12,6 +12,7 @@ import ( "text/template" "github.com/kyokomi/emoji" + "github.com/google/uuid" "github.com/logrusorgru/aurora" ) @@ -31,6 +32,7 @@ var FuncMap = template.FuncMap{ "Title": strings.Title, "ToLower": strings.ToLower, "CleanGoIdentifier": CleanGoIdentifier, + "GenerateUUID": uuid.New, } func GetCwd() string { diff --git a/templates/commit0/commit0.tmpl b/templates/commit0/commit0.tmpl index 9035c5115..20bd2027b 100644 --- a/templates/commit0/commit0.tmpl +++ b/templates/commit0/commit0.tmpl @@ -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}} diff --git a/templates/kubernetes/terraform/environments/development/main.tf b/templates/kubernetes/terraform/environments/development/main.tf index 552440f1b..fbf7e5065 100644 --- a/templates/kubernetes/terraform/environments/development/main.tf +++ b/templates/kubernetes/terraform/environments/development/main.tf @@ -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" } } @@ -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 diff --git a/templates/kubernetes/terraform/environments/production/main.tf b/templates/kubernetes/terraform/environments/production/main.tf index 9a394bf15..d3fc76c1f 100644 --- a/templates/kubernetes/terraform/environments/production/main.tf +++ b/templates/kubernetes/terraform/environments/production/main.tf @@ -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" } } @@ -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 diff --git a/templates/kubernetes/terraform/environments/staging/main.tf b/templates/kubernetes/terraform/environments/staging/main.tf index ab3ce52f7..af6345866 100644 --- a/templates/kubernetes/terraform/environments/staging/main.tf +++ b/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" } } @@ -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 diff --git a/templates/kubernetes/terraform/modules/kubernetes/external_dns.tf b/templates/kubernetes/terraform/modules/kubernetes/external_dns.tf new file mode 100644 index 000000000..a31405fdc --- /dev/null +++ b/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 + } + } + } +} diff --git a/templates/kubernetes/terraform/modules/kubernetes/kube2iam/main.tf b/templates/kubernetes/terraform/modules/kubernetes/kube2iam/main.tf index 3d01bd81a..75d16d8d7 100755 --- a/templates/kubernetes/terraform/modules/kubernetes/kube2iam/main.tf +++ b/templates/kubernetes/terraform/modules/kubernetes/kube2iam/main.tf @@ -89,7 +89,7 @@ resource "kubernetes_daemonset" "kube2iam" { # } env { name = "AWS_REGION" - value = var.environment + value = var.region } security_context { privileged = true diff --git a/templates/kubernetes/terraform/modules/kubernetes/variables.tf b/templates/kubernetes/terraform/modules/kubernetes/variables.tf index 050b728b8..e8964d21a 100644 --- a/templates/kubernetes/terraform/modules/kubernetes/variables.tf +++ b/templates/kubernetes/terraform/modules/kubernetes/variables.tf @@ -12,4 +12,17 @@ variable "cluster_name" { variable "assume_role_policy" { description = "Assume-role policy for monitoring" -} \ No newline at end of file +} + +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)" +} diff --git a/templates/terraform/bootstrap/remote-state/main.tf b/templates/terraform/bootstrap/remote-state/main.tf index cbf53d65b..5965bbc42 100644 --- a/templates/terraform/bootstrap/remote-state/main.tf +++ b/templates/terraform/bootstrap/remote-state/main.tf @@ -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 { @@ -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 @@ -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" @@ -32,3 +31,7 @@ resource "aws_dynamodb_table" "terraform_state_locks" { type = "S" } } + +variable "environment" { + description = "The environment (development/staging/production)" +} diff --git a/templates/terraform/environments/development/main.tf b/templates/terraform/environments/development/main.tf index ce8c94f13..04dbfc64c 100644 --- a/templates/terraform/environments/development/main.tf +++ b/templates/terraform/environments/development/main.tf @@ -1,11 +1,11 @@ terraform { required_version = ">= 0.12" backend "s3" { - bucket = "project-{{ .Config.Name }}-terraform-state" + bucket = "{{ .Config.Name }}-development-terraform-state" key = "infrastructure/terraform/environments/development/main" encrypt = true region = "{{ .Config.Infrastructure.AWS.Region }}" - dynamodb_table = "{{ .Config.Name }}-terraform-state-locks" + dynamodb_table = "{{ .Config.Name }}-development-terraform-state-locks" } } @@ -15,7 +15,7 @@ module "development" { environment = "development" # Project configuration - project = "{{ .Config.Infrastructure.AWS.EKS.ClusterName }}" + project = "{{ .Config.Name }}" region = "{{ .Config.Infrastructure.AWS.Region }}" allowed_account_ids = ["{{ .Config.Infrastructure.AWS.AccountId }}"] @@ -25,20 +25,29 @@ module "development" { # EKS configuration eks_worker_instance_type = "t2.small" - eks_worker_asg_max_size = 2 + eks_worker_asg_min_size = 1 + 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 }} - # Client configuration + {{- if .Config.Infrastructure.AWS.Cognito.Enabled }} + # Cognito configuration user_pool = "{{ .Config.Name }}-development" hostname = "{{ .Config.Frontend.Hostname }}" - s3_hosting_bucket_name = "{{ .Config.Name }}-development" + {{- end}} + + # Hosting configuration + s3_hosting_buckets = [ + "{{ .Config.Name }}-development" + ] + s3_hosting_cert_domain = "{{ .Config.Frontend.Hostname}}" } +{{- if .Config.Infrastructure.AWS.Cognito.Enabled }} output "cognito_client_id" { value = module.staging.cognito.cognito_client_id } @@ -46,3 +55,4 @@ output "cognito_client_id" { output "cognito_pool_id" { value = module.staging.cognito.cognito_pool_id } +{{- end}} diff --git a/templates/terraform/environments/production/main.tf b/templates/terraform/environments/production/main.tf index 87c2c1368..f07dad488 100644 --- a/templates/terraform/environments/production/main.tf +++ b/templates/terraform/environments/production/main.tf @@ -1,11 +1,11 @@ terraform { required_version = ">= 0.12" backend "s3" { - bucket = "project-{{ .Config.Name }}-terraform-state" + bucket = "{{ .Config.Name }}-production-terraform-state" key = "infrastructure/terraform/environments/production/main" encrypt = true region = "{{ .Config.Infrastructure.AWS.Region }}" - dynamodb_table = "{{ .Config.Name }}-terraform-state-locks" + dynamodb_table = "{{ .Config.Name }}-production-terraform-state-locks" } } @@ -15,7 +15,7 @@ module "production" { environment = "production" # Project configuration - project = "{{ .Config.Infrastructure.AWS.EKS.ClusterName }}" + project = "{{ .Config.Name }}" region = "{{ .Config.Infrastructure.AWS.Region }}" allowed_account_ids = ["{{ .Config.Infrastructure.AWS.AccountId }}"] @@ -25,20 +25,29 @@ module "production" { # EKS configuration eks_worker_instance_type = "m4.large" - eks_worker_asg_max_size = 3 + eks_worker_asg_min_size = 3 + eks_worker_asg_max_size = 6 # 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 }} - # Client configuration + {{- if .Config.Infrastructure.AWS.Cognito.Enabled }} + # Cognito configuration user_pool = "{{ .Config.Name }}-production" hostname = "{{ .Config.Frontend.Hostname }}" - s3_hosting_bucket_name = "{{ .Config.Name }}-production" + {{- end}} + + # Hosting configuration + s3_hosting_buckets = [ + "{{ .Config.Name }}-production" + ] + s3_hosting_cert_domain = "{{ .Config.Frontend.Hostname}}" } +{{- if .Config.Infrastructure.AWS.Cognito.Enabled }} output "cognito_client_id" { value = module.staging.cognito.cognito_client_id } @@ -46,3 +55,4 @@ output "cognito_client_id" { output "cognito_pool_id" { value = module.staging.cognito.cognito_pool_id } +{{- end}} diff --git a/templates/terraform/environments/staging/main.tf b/templates/terraform/environments/staging/main.tf index 598216ae8..6be9dfa99 100644 --- a/templates/terraform/environments/staging/main.tf +++ b/templates/terraform/environments/staging/main.tf @@ -1,11 +1,11 @@ terraform { required_version = ">= 0.12" backend "s3" { - bucket = "project-{{ .Config.Name }}-terraform-state" + bucket = "{{ .Config.Name }}-staging-terraform-state" key = "infrastructure/terraform/environments/staging/main" encrypt = true region = "{{ .Config.Infrastructure.AWS.Region }}" - dynamodb_table = "{{ .Config.Name }}-terraform-state-locks" + dynamodb_table = "{{ .Config.Name }}-staging-terraform-state-locks" } } @@ -15,7 +15,7 @@ module "staging" { environment = "staging" # Project configuration - project = "{{ .Config.Infrastructure.AWS.EKS.ClusterName }}" + project = "{{ .Config.Name }}" region = "{{ .Config.Infrastructure.AWS.Region }}" allowed_account_ids = ["{{ .Config.Infrastructure.AWS.AccountId }}"] @@ -29,19 +29,28 @@ module "staging" { # EKS configuration eks_worker_instance_type = "t2.small" - eks_worker_asg_max_size = 2 + eks_worker_asg_min_size = 2 + eks_worker_asg_max_size = 6 # 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 }} - # Client configuration + {{- if .Config.Infrastructure.AWS.Cognito.Enabled }} + # Cognito configuration user_pool = "{{ .Config.Name }}-staging" hostname = "{{ .Config.Frontend.Hostname }}" - s3_hosting_bucket_name = "{{ .Config.Name }}-staging" + {{- end }} + + # Hosting configuration + s3_hosting_buckets = [ + "{{ .Config.Name }}-staging" + ] + s3_hosting_cert_domain = "{{ .Config.Frontend.Hostname}}" } +{{- if .Config.Infrastructure.AWS.Cognito.Enabled }} output "cognito_client_id" { value = module.staging.cognito.cognito_client_id } @@ -49,3 +58,4 @@ output "cognito_client_id" { output "cognito_pool_id" { value = module.staging.cognito.cognito_pool_id } +{{- end}} diff --git a/templates/terraform/modules/eks/main.tf b/templates/terraform/modules/eks/main.tf index ef7f32ba4..c2164ef74 100644 --- a/templates/terraform/modules/eks/main.tf +++ b/templates/terraform/modules/eks/main.tf @@ -9,16 +9,18 @@ module "eks" { source = "terraform-aws-modules/eks/aws" version = "6.0.2" - cluster_name = var.project + cluster_name = var.cluster_name cluster_version = "1.14" subnets = var.private_subnets vpc_id = var.vpc_id worker_groups = [ { - instance_type = var.worker_instance_type - asg_max_size = var.worker_asg_max_size - ami_id = var.worker_ami + instance_type = var.worker_instance_type + asg_min_size = var.worker_asg_min_size + asg_desired_capacity = var.worker_asg_min_size + asg_max_size = var.worker_asg_max_size + ami_id = var.worker_ami tags = [{ key = "environment" value = var.environment @@ -34,6 +36,8 @@ module "eks" { groups = ["system:masters"] }, ] + cluster_iam_role_name = "k8s-${var.cluster_name}-cluster" + workers_role_name = "k8s-${var.cluster_name}-workers" # TODO, determine if this should be true/false manage_aws_auth = true diff --git a/templates/terraform/modules/eks/variables.tf b/templates/terraform/modules/eks/variables.tf index b68fdcd73..780b774ec 100644 --- a/templates/terraform/modules/eks/variables.tf +++ b/templates/terraform/modules/eks/variables.tf @@ -6,6 +6,10 @@ variable "environment" { description = "The environment (dev/staging/prod)" } +variable "cluster_name" { + description = "Name to be given to the EKS cluster" +} + variable "assume_role_policy" { description = "IAM policy document for AssumeRole" } @@ -23,6 +27,10 @@ variable "worker_instance_type" { description = "Instance type for the EKS workers" } +variable "worker_asg_min_size" { + description = "Minimum number of instances for the EKS ASG" +} + variable "worker_asg_max_size" { description = "Maximum number of instances for the EKS ASG" } diff --git a/templates/terraform/modules/environment/main.tf b/templates/terraform/modules/environment/main.tf index 09091c1aa..231ca2f2c 100644 --- a/templates/terraform/modules/environment/main.tf +++ b/templates/terraform/modules/environment/main.tf @@ -1,10 +1,15 @@ # Environment entrypoint +locals { + kubernetes_cluster_name = "${var.project}-${var.environment}-${var.region}" +} + module "vpc" { - source = "../../modules/vpc" - project = var.project - environment = var.environment - region = var.region + source = "../../modules/vpc" + project = var.project + environment = var.environment + region = var.region + kubernetes_cluster_name = local.kubernetes_cluster_name } # Data sources for EKS IAM @@ -21,19 +26,23 @@ data "aws_iam_policy_document" "assumerole_root_policy" { } } -#{{- if ne .Config.Infrastructure.AWS.EKS.ClusterName "" }} +{{- if ne .Config.Infrastructure.AWS.EKS.ClusterName "" }} # Provision the EKS cluster module "eks" { source = "../../modules/eks" project = var.project environment = var.environment + cluster_name = local.kubernetes_cluster_name + iam_account_id = data.aws_caller_identity.current.account_id + assume_role_policy = data.aws_iam_policy_document.assumerole_root_policy.json private_subnets = module.vpc.private_subnets vpc_id = module.vpc.vpc_id + worker_instance_type = var.eks_worker_instance_type + worker_asg_min_size = var.eks_worker_asg_min_size worker_asg_max_size = var.eks_worker_asg_max_size worker_ami = var.eks_worker_ami # EKS-Optimized AMI for your region: https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html - iam_account_id = data.aws_caller_identity.current.account_id } module "kube2iam" { @@ -43,13 +52,13 @@ module "kube2iam" { eks_worker_iam_role_name = module.eks.worker_iam_role_name iam_account_id = data.aws_caller_identity.current.account_id } - -#{{- end}} +{{- end}} data "aws_iam_user" "ci_user" { user_name = "ci-user" # Should have been created in the bootstrap process } -#{{- if .Config.Services }} +{{- if .Config.Services }} + # Set up ECR repositories module "ecr" { source = "../../modules/ecr" @@ -57,9 +66,9 @@ module "ecr" { ecr_repositories = var.ecr_repositories ecr_principals = [aws_iam_user.id] } -#{{- end}} +{{- end}} -# {{ if .Config.Infrastructure.AWS.Cognito.Enabled }} +{{- if .Config.Infrastructure.AWS.Cognito.Enabled }} module "cognito" { source = "../../modules/cognito" user_pool = var.user_pool @@ -69,11 +78,13 @@ module "cognito" { output "cognito" { value = module.cognito } -# {{- end}} +{{- end}} -# {{ if .Config.Infrastructure.AWS.S3Hosting.Enabled }} +{{ if .Config.Infrastructure.AWS.S3Hosting.Enabled }} module "s3_hosting" { - source = "../../modules/s3_hosting" - bucket_name = var.s3_hosting_bucket_name + source = "../../modules/s3_hosting" + buckets = var.s3_hosting_buckets + cert_domain = var.s3_hosting_cert_domain + project = var.project } -# {{- end}} +{{- end}} diff --git a/templates/terraform/modules/environment/variables.tf b/templates/terraform/modules/environment/variables.tf index 660894412..2ff27eae7 100644 --- a/templates/terraform/modules/environment/variables.tf +++ b/templates/terraform/modules/environment/variables.tf @@ -24,6 +24,10 @@ variable "eks_worker_instance_type" { description = "Instance type for the EKS workers" } +variable "eks_worker_asg_min_size" { + description = "Minimum number of instances for the EKS ASG" +} + variable "eks_worker_asg_max_size" { description = "Maximum number of instances for the EKS ASG" } @@ -32,14 +36,18 @@ variable "eks_worker_ami" { description = "The (EKS-optimized) AMI for EKS worker instances" } -variable "user_pool" { - description = "AWS Cognito pool name" -} - +{{- if .Config.Infrastructure.AWS.Cognito.Enabled }} variable "hostname" { description = "Application hostname" -} +} +{{- end }} +variable "s3_hosting_buckets" { + description = "S3 hosting buckets" + type = set(string) +} -variable "s3_hosting_bucket_name" { - description = "S3 hosting bucket name" +variable "s3_hosting_cert_domain" { + description = "Domain of the ACM certificate to lookup for Cloudfront to use" + type = string } + diff --git a/templates/terraform/modules/s3_hosting/main.tf b/templates/terraform/modules/s3_hosting/main.tf index 2607f019b..f379e93d2 100644 --- a/templates/terraform/modules/s3_hosting/main.tf +++ b/templates/terraform/modules/s3_hosting/main.tf @@ -1,26 +1,14 @@ -resource "aws_s3_bucket" "www" { - // Our bucket's name is going to be the same as our site's domain name. - bucket = "${var.bucket_name}" - // Because we want our site to be available on the internet, we set this so - // anyone can read this bucket. - acl = "public-read" - // We also need to create a policy that allows anyone to view the content. - // This is basically duplicating what we did in the ACL but it's required by - // AWS. This post: http://amzn.to/2Fa04ul explains why. - policy = <