From 1b9cffd6fd29ed617d202a564f9a30c5536e8602 Mon Sep 17 00:00:00 2001 From: Filippo Morelli Date: Fri, 20 May 2022 15:27:26 +0000 Subject: [PATCH 1/8] TG-680 Fix domains params collection --- bootstrap/collector.py | 138 ++++++++----------------- start.py | 5 + tests/test_collector.py | 224 +++++++++------------------------------- 3 files changed, 101 insertions(+), 266 deletions(-) diff --git a/bootstrap/collector.py b/bootstrap/collector.py index ce6098fa..5728a081 100755 --- a/bootstrap/collector.py +++ b/bootstrap/collector.py @@ -74,6 +74,7 @@ def collect( project_url_monitoring, letsencrypt_certificate_email, digitalocean_domain_create, + digitalocean_dns_records_create, digitalocean_k8s_cluster_region, digitalocean_database_cluster_region, digitalocean_database_cluster_node_size, @@ -171,8 +172,7 @@ def collect( project_url_prod, project_url_monitoring, letsencrypt_certificate_email, - ) = clean_project_urls( - deployment_type, + ) = clean_domains( project_slug, project_domain, use_monitoring, @@ -190,14 +190,15 @@ def collect( if digitalocean_enabled: ( digitalocean_domain_create, + digitalocean_dns_records_create, digitalocean_k8s_cluster_region, digitalocean_database_cluster_region, digitalocean_database_cluster_node_size, digitalocean_redis_cluster_region, digitalocean_redis_cluster_node_size, ) = clean_digitalocean_options( - project_domain, digitalocean_domain_create, + digitalocean_dns_records_create, digitalocean_k8s_cluster_region, digitalocean_database_cluster_region, digitalocean_database_cluster_node_size, @@ -584,26 +585,7 @@ def clean_kubernetes_credentials( return kubernetes_cluster_ca_certificate, kubernetes_host, kubernetes_token -def clean_project_domain(project_domain): - """Return the project domain.""" - return ( - project_domain - or ( - project_domain is None - and click.confirm( - warning( - "Do you want to configure DNS records? " - "(BEWARE: NS must be set accordingly)" - ) - ) - and validate_or_prompt_domain("Project domain", project_domain) - ) - or None - ) - - -def clean_project_urls( - deployment_type, +def clean_domains( project_slug, project_domain, use_monitoring, @@ -618,68 +600,32 @@ def clean_project_urls( letsencrypt_certificate_email, ): """Return project URLs.""" - if deployment_type == DEPLOYMENT_TYPE_DIGITALOCEAN and ( - project_domain := clean_project_domain(project_domain) - ): - domain_prefix_dev = domain_prefix_dev or click.prompt( - "Development domain prefix", default="dev" - ) - project_url_dev = f"https://{domain_prefix_dev}.{project_domain}" - domain_prefix_stage = domain_prefix_stage or click.prompt( - "Staging domain prefix", default="stage" - ) - project_url_stage = f"https://{domain_prefix_stage}.{project_domain}" - domain_prefix_prod = domain_prefix_prod or click.prompt( - "Production domain prefix", default="www" + project_domain = validate_or_prompt_domain( + "Project domain", project_domain, default=f"{project_slug}.com" + ) + domain_prefix_dev = domain_prefix_dev or click.prompt( + "Development domain prefix", default="dev" + ) + project_url_dev = f"https://{domain_prefix_dev}.{project_domain}" + domain_prefix_stage = domain_prefix_stage or click.prompt( + "Staging domain prefix", default="stage" + ) + project_url_stage = f"https://{domain_prefix_stage}.{project_domain}" + domain_prefix_prod = domain_prefix_prod or click.prompt( + "Production domain prefix", default="www" + ) + project_url_prod = f"https://{domain_prefix_prod}.{project_domain}" + if use_monitoring: + domain_prefix_monitoring = domain_prefix_monitoring or click.prompt( + "Monitorng domain prefix", default="logs" ) - project_url_prod = f"https://{domain_prefix_prod}.{project_domain}" - if use_monitoring: - domain_prefix_monitoring = domain_prefix_monitoring or click.prompt( - "Monitorng domain prefix", default="logs" - ) - project_url_monitoring = ( - f"https://{domain_prefix_monitoring}.{project_domain}" - ) - else: - domain_prefix_monitoring = None - project_url_monitoring = None - letsencrypt_certificate_email = None + project_url_monitoring = f"https://{domain_prefix_monitoring}.{project_domain}" else: - project_domain = None - domain_prefix_dev = None - domain_prefix_stage = None - domain_prefix_prod = None domain_prefix_monitoring = None - project_url_dev = validate_or_prompt_url( - "Development environment complete URL", - project_url_dev or None, - default=f"https://dev.{project_slug}.com", - required=False, - ) - project_url_stage = validate_or_prompt_url( - "Staging environment complete URL", - project_url_stage or None, - default=f"https://stage.{project_slug}.com", - required=False, - ) - project_url_prod = validate_or_prompt_url( - "Production environment complete URL", - project_url_prod or None, - default=f"https://www.{project_slug}.com", - required=False, - ) - if use_monitoring: - project_url_monitoring = validate_or_prompt_url( - "Monitoring complete URL", - project_url_monitoring or None, - default=f"https://logs.{project_slug}.com", - required=False, - ) - else: - project_url_monitoring = None - letsencrypt_certificate_email = clean_letsencrypt_certificate_email( - letsencrypt_certificate_email - ) + project_url_monitoring = None + letsencrypt_certificate_email = clean_letsencrypt_certificate_email( + letsencrypt_certificate_email + ) return ( project_domain, domain_prefix_dev, @@ -784,8 +730,8 @@ def clean_frontend_sentry_dsn(frontend_type, frontend_sentry_dsn): def clean_digitalocean_options( - project_domain, digitalocean_domain_create, + digitalocean_dns_records_create, digitalocean_k8s_cluster_region, digitalocean_database_cluster_region, digitalocean_database_cluster_node_size, @@ -795,17 +741,22 @@ def clean_digitalocean_options( ): """Return DigitalOcean configuration options.""" # TODO: ask these settings for each stack - if project_domain: - digitalocean_domain_create = ( - digitalocean_domain_create - if digitalocean_domain_create is not None - else click.confirm( - f"Do you want to create DigitalOcean domain '{project_domain}'?", - default=True, - ) + digitalocean_domain_create = ( + digitalocean_domain_create + if digitalocean_domain_create is not None + else click.confirm( + "Do you want to create the DigitalOcean domain?", + default=True, ) - else: - digitalocean_domain_create = None + ) + digitalocean_dns_records_create = ( + digitalocean_dns_records_create + if digitalocean_dns_records_create is not None + else click.confirm( + "Do you want to create DigitalOcean DNS records?", + default=True, + ) + ) digitalocean_k8s_cluster_region = digitalocean_k8s_cluster_region or click.prompt( "Kubernetes cluster DigitalOcean region", default="fra1" ) @@ -836,6 +787,7 @@ def clean_digitalocean_options( ) return ( digitalocean_domain_create, + digitalocean_dns_records_create, digitalocean_k8s_cluster_region, digitalocean_database_cluster_region, digitalocean_database_cluster_node_size, diff --git a/start.py b/start.py index 94174760..641d857e 100755 --- a/start.py +++ b/start.py @@ -78,6 +78,11 @@ is_flag=True, default=None, ) # ADD TO README +@click.option( + "--digitalocean-dns-records-create/--digitalocean-dns-records-create-skip", + is_flag=True, + default=None, +) # ADD TO README @click.option("--digitalocean-k8s-cluster-region") @click.option("--digitalocean-database-cluster-region") @click.option("--digitalocean-database-cluster-node-size") diff --git a/tests/test_collector.py b/tests/test_collector.py index 888dd0a9..2377d218 100644 --- a/tests/test_collector.py +++ b/tests/test_collector.py @@ -11,6 +11,7 @@ clean_backend_type, clean_deployment_type, clean_digitalocean_options, + clean_domains, clean_environment_distribution, clean_frontend_sentry_dsn, clean_frontend_service_slug, @@ -20,9 +21,7 @@ clean_media_storage, clean_other_k8s_options, clean_pact_broker_data, - clean_project_domain, clean_project_slug, - clean_project_urls, clean_s3_media_storage_data, clean_sentry_org, clean_service_dir, @@ -205,23 +204,13 @@ def test_clean_other_k8s_options(self): ("postgres:14", "10Gi", "", "/etc/k8s-volume-data", "redis:6"), ) - def test_clean_project_domain(self): - """Test cleaning the project domain.""" - self.assertEqual(clean_project_domain(""), None) - self.assertEqual(clean_project_domain("myproject.com"), "myproject.com") - with input("n"): - self.assertEqual(clean_project_domain(None), None) - with input("y", "myproject.com"): - self.assertEqual(clean_project_domain(None), "myproject.com") - - def test_clean_project_urls(self): - """Test cleaning the project URLs.""" + def test_clean_domains(self): + """Test cleaning the project domains.""" # project domain set with input("alpha", "beta", "www2"): self.assertEqual( - clean_project_urls( - "digitalocean-k8s", - "my-project", + clean_domains( + "projectslug", "myproject.com", False, None, @@ -232,7 +221,7 @@ def test_clean_project_urls(self): None, None, None, - None, + "test@test.com", ), ( "myproject.com", @@ -244,13 +233,12 @@ def test_clean_project_urls(self): "https://beta.myproject.com", "https://www2.myproject.com", None, - None, + "test@test.com", ), ) self.assertEqual( - clean_project_urls( - "digitalocean-k8s", - "my-project", + clean_domains( + "projectslug", "myproject.com", False, "alpha", @@ -261,7 +249,7 @@ def test_clean_project_urls(self): None, None, None, - None, + "test@test.com", ), ( "myproject.com", @@ -273,21 +261,20 @@ def test_clean_project_urls(self): "https://beta.myproject.com", "https://www2.myproject.com", None, - None, + "test@test.com", ), ) # project domain not set with input( - "N", - "https://alpha.myproject.com/", - "https://beta.myproject.com/", - "https://www2.myproject.com/", + "myproject.com", + "alpha", + "beta", + "www2", "N", ): self.assertEqual( - clean_project_urls( - "digitalocean-k8s", - "my-project", + clean_domains( + "projectslug", None, False, None, @@ -301,78 +288,10 @@ def test_clean_project_urls(self): None, ), ( - None, - None, - None, - None, - None, - "https://alpha.myproject.com", - "https://beta.myproject.com", - "https://www2.myproject.com", - None, - None, - ), - ) - with input( - "N", - ): - self.assertEqual( - clean_project_urls( - "digitalocean-k8s", - "my-project", - "", - False, - None, - None, - None, - None, - "https://alpha.myproject.com/", - "https://beta.myproject.com/", - "https://www2.myproject.com/", - "", - "", - ), - ( - None, - None, - None, - None, - None, - "https://alpha.myproject.com", - "https://beta.myproject.com", - "https://www2.myproject.com", - None, - None, - ), - ) - # other kubernetes - with input( - "https://alpha.myproject.com/", - "https://beta.myproject.com/", - "https://www2.myproject.com/", - "N", - ): - self.assertEqual( - clean_project_urls( - "other-k8s", - "my-project", - None, - False, - None, - None, - None, - None, - None, - None, - None, - None, - None, - ), - ( - None, - None, - None, - None, + "myproject.com", + "alpha", + "beta", + "www2", None, "https://alpha.myproject.com", "https://beta.myproject.com", @@ -384,9 +303,8 @@ def test_clean_project_urls(self): # monitoring enabled with input("alpha", "beta", "www2", "mylogs", "N"): self.assertEqual( - clean_project_urls( - "digitalocean-k8s", - "my-project", + clean_domains( + "projectslug", "myproject.com", True, None, @@ -411,56 +329,19 @@ def test_clean_project_urls(self): "https://mylogs.myproject.com", None, ), - ) - with input( - "https://alpha.myproject.com/", - "https://beta.myproject.com/", - "https://www2.myproject.com/", - "https://mylogs.myproject.com/", - "N", - ): - self.assertEqual( - clean_project_urls( - "digitalocean-k8s", - "my-project", - "", - True, - None, - None, - None, - None, - None, - None, - None, - None, - None, - ), - ( - None, - None, - None, - None, - None, - "https://alpha.myproject.com", - "https://beta.myproject.com", - "https://www2.myproject.com", - "https://mylogs.myproject.com", - None, - ), - ) - # Let's Encrypt certificates enabled + ) # Let's Encrypt certificates enabled with input( - "https://alpha.myproject.com/", - "https://beta.myproject.com/", - "https://www2.myproject.com/", - "https://mylogs.myproject.com/", + "myproject.com", + "alpha", + "beta", + "www2", + "mylogs", "Y", "test@test.com", ): self.assertEqual( - clean_project_urls( - "digitalocean-k8s", - "my-project", + clean_domains( + "projectslug", "", True, None, @@ -474,11 +355,11 @@ def test_clean_project_urls(self): None, ), ( - None, - None, - None, - None, - None, + "myproject.com", + "alpha", + "beta", + "www2", + "mylogs", "https://alpha.myproject.com", "https://beta.myproject.com", "https://www2.myproject.com", @@ -519,21 +400,8 @@ def test_clean_digitalocean_options(self): """Test cleaning the DigitalOcean options.""" self.assertEqual( clean_digitalocean_options( - "", - None, - "nyc1", - "nyc1", - "db-s-8vcpu-16gb", - "nyc1", - "db-s-8vcpu-16gb", - True, - ), - (None, "nyc1", "nyc1", "db-s-8vcpu-16gb", "nyc1", "db-s-8vcpu-16gb"), - ) - self.assertEqual( - clean_digitalocean_options( - "myproject.com", True, + False, "nyc1", "nyc1", "db-s-8vcpu-16gb", @@ -541,14 +409,24 @@ def test_clean_digitalocean_options(self): None, False, ), - (True, "nyc1", "nyc1", "db-s-8vcpu-16gb", None, None), + (True, False, "nyc1", "nyc1", "db-s-8vcpu-16gb", None, None), ) - with input("n", "nyc1", "nyc1", "db-s-8vcpu-16gb", "nyc1", "db-s-8vcpu-16gb"): + with input( + "y", "n", "nyc1", "nyc1", "db-s-8vcpu-16gb", "nyc1", "db-s-8vcpu-16gb" + ): self.assertEqual( clean_digitalocean_options( - "myproject.com", None, None, None, None, None, None, True + None, None, None, None, None, None, None, True + ), + ( + True, + False, + "nyc1", + "nyc1", + "db-s-8vcpu-16gb", + "nyc1", + "db-s-8vcpu-16gb", ), - (False, "nyc1", "nyc1", "db-s-8vcpu-16gb", "nyc1", "db-s-8vcpu-16gb"), ) def test_clean_broker_data(self): From c44a085a2de3da4ce7a4ce8913aede76aa7c520c Mon Sep 17 00:00:00 2001 From: daniele20tab Date: Sat, 21 May 2022 10:48:58 +0200 Subject: [PATCH 2/8] Update terraform scripts --- .../cluster/digitalocean-k8s/main.tf | 60 +------ .../cluster/digitalocean-k8s/variables.tf | 55 ------- .../modules/kubernetes/traefik/main.tf | 48 +++--- .../modules/kubernetes/traefik/values.yaml | 1 + .../modules/kubernetes/traefik/variables.tf | 6 - .../terraform/cluster/other-k8s/main.tf | 24 --- .../terraform/cluster/other-k8s/variables.tf | 50 ------ .../environment/digitalocean-k8s/main.tf | 62 +++++++- .../environment/digitalocean-k8s/variables.tf | 62 ++++++-- .../grafana/dashboards/k8s-logs.json | 0 .../kubernetes/monitoring/grafana/values.yaml | 0 .../modules/kubernetes/monitoring/main.tf | 28 ---- .../kubernetes/monitoring/variables.tf | 6 - .../modules/kubernetes/routing/main.tf | 148 ++++++++++++++++-- .../modules/kubernetes/routing/variables.tf | 22 ++- .../terraform/environment/other-k8s/main.tf | 24 ++- .../environment/other-k8s/variables.tf | 50 ++++-- 17 files changed, 354 insertions(+), 292 deletions(-) rename {{cookiecutter.project_dirname}}/terraform/{cluster => environment}/modules/kubernetes/monitoring/grafana/dashboards/k8s-logs.json (100%) rename {{cookiecutter.project_dirname}}/terraform/{cluster => environment}/modules/kubernetes/monitoring/grafana/values.yaml (100%) rename {{cookiecutter.project_dirname}}/terraform/{cluster => environment}/modules/kubernetes/monitoring/main.tf (78%) rename {{cookiecutter.project_dirname}}/terraform/{cluster => environment}/modules/kubernetes/monitoring/variables.tf (75%) diff --git a/{{cookiecutter.project_dirname}}/terraform/cluster/digitalocean-k8s/main.tf b/{{cookiecutter.project_dirname}}/terraform/cluster/digitalocean-k8s/main.tf index a108a04e..adfb9c42 100644 --- a/{{cookiecutter.project_dirname}}/terraform/cluster/digitalocean-k8s/main.tf +++ b/{{cookiecutter.project_dirname}}/terraform/cluster/digitalocean-k8s/main.tf @@ -1,13 +1,5 @@ locals { resource_name_prefix = var.stack_slug == "main" ? var.project_slug : "${var.project_slug}-${var.stack_slug}" - - monitoring_enabled = var.monitoring_url != "" && var.stack_slug == "main" - monitoring_host = local.monitoring_enabled ? regexall("https?://([^/]+)", var.monitoring_url)[0][0] : "" - - domain_prefixes = concat( - var.domain_prefixes, - local.monitoring_enabled && var.monitoring_domain_prefix != "" ? [var.monitoring_domain_prefix] : [] - ) } terraform { @@ -57,43 +49,15 @@ data "digitalocean_kubernetes_cluster" "main" { name = "${local.resource_name_prefix}-k8s-cluster" } -/* Domain */ - -resource "digitalocean_domain" "default" { - count = var.create_domain && var.stack_slug == "main" && var.project_domain != "" ? 1 : 0 - - name = var.project_domain -} - -/* Certificate */ - -resource "digitalocean_certificate" "ssl_cert" { - count = var.project_domain != "" ? 1 : 0 - - name = "${local.resource_name_prefix}-lets-encrypt-certificate" - type = "lets_encrypt" - domains = [for i in local.domain_prefixes : "${i}.${var.project_domain}"] -} - /* Traefik */ module "traefik" { source = "../modules/kubernetes/traefik" letsencrypt_certificate_email = var.letsencrypt_certificate_email - load_balancer_annotations = merge( - { - "service.beta.kubernetes.io/do-loadbalancer-name" = "${local.resource_name_prefix}-load-balancer" - }, - var.project_domain != "" ? { - "service.beta.kubernetes.io/do-loadbalancer-protocol" = "http" - "service.beta.kubernetes.io/do-loadbalancer-tls-ports" = "443" - "service.beta.kubernetes.io/do-loadbalancer-certificate-id" = digitalocean_certificate.ssl_cert[0].uuid - "service.beta.kubernetes.io/do-loadbalancer-disable-lets-encrypt-dns-records" = "false" - "service.beta.kubernetes.io/do-loadbalancer-redirect-http-to-https" = "true" - } : {} - ) - ssl_enabled = var.ssl_enabled + load_balancer_annotations = { + "service.beta.kubernetes.io/do-loadbalancer-name" = "${local.resource_name_prefix}-load-balancer" + } } /* Reloader */ @@ -103,21 +67,3 @@ resource "helm_release" "reloader" { chart = "reloader" repository = "https://stakater.github.io/stakater-charts" } - -/* Monitoring */ - -module "monitoring" { - count = local.monitoring_enabled ? 1 : 0 - - source = "../modules/kubernetes/monitoring" - - grafana_user = var.grafana_user - grafana_password = var.grafana_password - grafana_version = var.grafana_version - - host = local.monitoring_host - - depends_on = [ - module.traefik - ] -} diff --git a/{{cookiecutter.project_dirname}}/terraform/cluster/digitalocean-k8s/variables.tf b/{{cookiecutter.project_dirname}}/terraform/cluster/digitalocean-k8s/variables.tf index 610d67b1..30f45c61 100644 --- a/{{cookiecutter.project_dirname}}/terraform/cluster/digitalocean-k8s/variables.tf +++ b/{{cookiecutter.project_dirname}}/terraform/cluster/digitalocean-k8s/variables.tf @@ -1,75 +1,20 @@ -variable "create_domain" { - description = "Tell if a DigitalOcean domain should be created." - type = bool - default = true -} - variable "digitalocean_token" { description = "The DigitalOcean access token." type = string sensitive = true } -variable "domain_prefixes" { - description = "The list of domain prefixes." - type = list(string) - default = [] -} - -variable "grafana_password" { - description = "The Grafana admin password." - type = string - sensitive = true - default = "" -} - -variable "grafana_user" { - description = "The Grafana admin username." - type = string - default = "admin" -} - -variable "grafana_version" { - description = "The Grafana version." - type = string - default = "8.4.2" -} - variable "letsencrypt_certificate_email" { description = "The email used to issue the Let's Encrypt certificate." type = string default = "" } -variable "monitoring_domain_prefix" { - description = "The monitoring domain url." - type = string - default = "" -} - -variable "monitoring_url" { - description = "The full monitoring url." - type = string - default = "" -} - -variable "project_domain" { - description = "The project domain." - type = string - default = "" -} - variable "project_slug" { description = "The project slug." type = string } -variable "ssl_enabled" { - description = "Tell if SSL should be enabled." - type = bool - default = false -} - variable "stack_slug" { description = "The stack slug (e.g. 'main')." type = string diff --git a/{{cookiecutter.project_dirname}}/terraform/cluster/modules/kubernetes/traefik/main.tf b/{{cookiecutter.project_dirname}}/terraform/cluster/modules/kubernetes/traefik/main.tf index e0a55188..69ae988f 100644 --- a/{{cookiecutter.project_dirname}}/terraform/cluster/modules/kubernetes/traefik/main.tf +++ b/{{cookiecutter.project_dirname}}/terraform/cluster/modules/kubernetes/traefik/main.tf @@ -22,29 +22,31 @@ resource "helm_release" "traefik" { values = [ file("${path.module}/values.yaml"), yamlencode( - merge( - { - service = { - enabled = "true" - type = "LoadBalancer" - annotations = var.load_balancer_annotations - } - }, - var.ssl_enabled ? { - additionalArguments = concat( - [ - "--entrypoints.web.http.redirections.entryPoint.to=:443", - "--entrypoints.websecure.http.tls=true", - ], - var.letsencrypt_certificate_email != "" ? [ - "--certificatesresolvers.default.acme.tlschallenge", - "--certificatesresolvers.default.acme.email=${var.letsencrypt_certificate_email}", - "--certificatesresolvers.default.acme.storage=/data/acme.json", - "--entrypoints.websecure.http.tls.certResolver=default", - ] : [], - ) - } : {} - ) + { + service = { + enabled = "true" + type = "LoadBalancer" + annotations = var.load_balancer_annotations + } + } ) ] } + +/* Cert Manager */ + +resource "helm_release" "cert_manager" { + count = var.letsencrypt_certificate_email != "" ? 1 : 0 + + name = "cert-manager" + chart = "cert-manager" + namespace = "cert-manager" + create_namespace = true + repository = "https://charts.jetstack.io" + version = "1.7.2" + + set { + name = "installCRDs" + value = true + } +} diff --git a/{{cookiecutter.project_dirname}}/terraform/cluster/modules/kubernetes/traefik/values.yaml b/{{cookiecutter.project_dirname}}/terraform/cluster/modules/kubernetes/traefik/values.yaml index 88e6e31d..1f7a785f 100644 --- a/{{cookiecutter.project_dirname}}/terraform/cluster/modules/kubernetes/traefik/values.yaml +++ b/{{cookiecutter.project_dirname}}/terraform/cluster/modules/kubernetes/traefik/values.yaml @@ -5,5 +5,6 @@ logs: providers: kubernetesIngress: enabled: true + ingressClass: "traefik-cert-manager" kubernetesIngressRoute: enabled: true diff --git a/{{cookiecutter.project_dirname}}/terraform/cluster/modules/kubernetes/traefik/variables.tf b/{{cookiecutter.project_dirname}}/terraform/cluster/modules/kubernetes/traefik/variables.tf index d8a9c091..15768983 100644 --- a/{{cookiecutter.project_dirname}}/terraform/cluster/modules/kubernetes/traefik/variables.tf +++ b/{{cookiecutter.project_dirname}}/terraform/cluster/modules/kubernetes/traefik/variables.tf @@ -9,9 +9,3 @@ variable "load_balancer_annotations" { type = map(string) default = {} } - -variable "ssl_enabled" { - description = "Tell if SSL should be enabled." - type = bool - default = false -} diff --git a/{{cookiecutter.project_dirname}}/terraform/cluster/other-k8s/main.tf b/{{cookiecutter.project_dirname}}/terraform/cluster/other-k8s/main.tf index 701c0dc8..4d145233 100644 --- a/{{cookiecutter.project_dirname}}/terraform/cluster/other-k8s/main.tf +++ b/{{cookiecutter.project_dirname}}/terraform/cluster/other-k8s/main.tf @@ -1,8 +1,3 @@ -locals { - monitoring_enabled = var.monitoring_url != "" && var.stack_slug == "main" - monitoring_host = local.monitoring_enabled ? regexall("https?://([^/]+)", var.monitoring_url)[0][0] : "" -} - terraform { required_providers { helm = { @@ -38,7 +33,6 @@ module "traefik" { source = "../modules/kubernetes/traefik" letsencrypt_certificate_email = var.letsencrypt_certificate_email - ssl_enabled = var.ssl_enabled } /* Reloader */ @@ -48,21 +42,3 @@ resource "helm_release" "reloader" { chart = "reloader" repository = "https://stakater.github.io/stakater-charts" } - -/* Monitoring */ - -module "monitoring" { - count = local.monitoring_enabled ? 1 : 0 - - source = "../modules/kubernetes/monitoring" - - grafana_user = var.grafana_user - grafana_password = var.grafana_password - grafana_version = var.grafana_version - - host = local.monitoring_host - - depends_on = [ - module.traefik - ] -} diff --git a/{{cookiecutter.project_dirname}}/terraform/cluster/other-k8s/variables.tf b/{{cookiecutter.project_dirname}}/terraform/cluster/other-k8s/variables.tf index df24f811..8b0ae50f 100644 --- a/{{cookiecutter.project_dirname}}/terraform/cluster/other-k8s/variables.tf +++ b/{{cookiecutter.project_dirname}}/terraform/cluster/other-k8s/variables.tf @@ -1,28 +1,3 @@ -variable "domain_prefixes" { - description = "The list of domain prefixes." - type = list(string) - default = [] -} - -variable "grafana_password" { - description = "The Grafana admin password." - type = string - sensitive = true - default = "" -} - -variable "grafana_user" { - description = "The Grafana admin username." - type = string - default = "admin" -} - -variable "grafana_version" { - description = "The Grafana version." - type = string - default = "8.4.2" -} - variable "kubernetes_cluster_ca_certificate" { description = "The base64 encoded Kubernetes CA certificate." type = string @@ -46,36 +21,11 @@ variable "letsencrypt_certificate_email" { default = "" } -variable "monitoring_domain_prefix" { - description = "The monitoring domain url." - type = string - default = "" -} - -variable "monitoring_url" { - description = "The full monitoring url." - type = string - default = "" -} - -variable "project_domain" { - description = "The project domain." - type = string - default = "" -} - variable "project_slug" { description = "The project slug." type = string } -variable "ssl_enabled" { - description = "Tell if SSL should be enabled." - type = bool - default = false -} - - variable "stack_slug" { description = "The stack slug (e.g. 'main')." type = string diff --git a/{{cookiecutter.project_dirname}}/terraform/environment/digitalocean-k8s/main.tf b/{{cookiecutter.project_dirname}}/terraform/environment/digitalocean-k8s/main.tf index 1c14068a..04e753c5 100644 --- a/{{cookiecutter.project_dirname}}/terraform/environment/digitalocean-k8s/main.tf +++ b/{{cookiecutter.project_dirname}}/terraform/environment/digitalocean-k8s/main.tf @@ -3,7 +3,7 @@ locals { namespace = kubernetes_namespace_v1.main.metadata[0].name - project_host = regexall("https?://([^/]+)", var.project_url)[0][0] + domain_id = var.create_dns_records ? var.create_domain ? digitalocean_domain.main[0].id : data.digitalocean_domain.main[0].id : "" s3_host = var.digitalocean_spaces_bucket_available ? "https://${var.s3_region}.digitaloceanspaces.com" : var.s3_host s3_bucket_name = var.digitalocean_spaces_bucket_available ? "${local.base_resource_name_prefix}-s3-bucket" : var.s3_bucket_name @@ -73,6 +73,16 @@ data "digitalocean_spaces_bucket" "postgres_dump" { region = var.s3_region } +data "digitalocean_loadbalancer" "main" { + name = "${local.base_resource_name_prefix}-load-balancer" +} + +data "digitalocean_domain" "main" { + count = var.create_dns_records && !var.create_domain ? 1 : 0 + + name = var.project_domain +} + /* Database */ resource "digitalocean_database_user" "postgres" { @@ -94,6 +104,34 @@ resource "digitalocean_database_connection_pool" "postgres" { size = var.database_connection_pool_size } +/* Domain */ + +resource "digitalocean_domain" "main" { + count = var.create_dns_records && var.create_domain ? 1 : 0 + + name = var.project_domain +} + +/* DNS records */ + +resource "digitalocean_record" "main" { + for_each = toset(var.create_dns_records ? [for i in var.subdomains : i == "" ? "@" : i] : []) + + domain = local.domain_id + type = "A" + name = each.key + value = data.digitalocean_loadbalancer.main.ip +} + +resource "digitalocean_record" "monitoring" { + count = var.create_dns_records && var.monitoring_subdomain != "" ? 1 : 0 + + domain = local.domain_id + type = "A" + name = var.monitoring_subdomain + value = data.digitalocean_loadbalancer.main.ip +} + /* Namespace */ resource "kubernetes_namespace_v1" "main" { @@ -102,6 +140,18 @@ resource "kubernetes_namespace_v1" "main" { } } +/* Monitoring */ + +module "monitoring" { + count = var.monitoring_subdomain != "" ? 1 : 0 + + source = "../modules/kubernetes/monitoring" + + grafana_user = var.grafana_user + grafana_password = var.grafana_password + grafana_version = var.grafana_version +} + /* Routing */ module "routing" { @@ -109,7 +159,8 @@ module "routing" { namespace = local.namespace - project_host = local.project_host + project_domain = var.project_domain + subdomains = var.subdomains basic_auth_enabled = var.basic_auth_enabled basic_auth_username = var.basic_auth_username @@ -125,8 +176,11 @@ module "routing" { frontend_service_paths = var.frontend_service_paths frontend_service_port = var.frontend_service_port - tls_certificate_crt = var.tls_certificate_crt - tls_certificate_key = var.tls_certificate_key + letsencrypt_certificate_email = var.letsencrypt_certificate_email + tls_certificate_crt = var.tls_certificate_crt + tls_certificate_key = var.tls_certificate_key + + monitoring_subdomain = var.monitoring_subdomain } /* Secrets */ diff --git a/{{cookiecutter.project_dirname}}/terraform/environment/digitalocean-k8s/variables.tf b/{{cookiecutter.project_dirname}}/terraform/environment/digitalocean-k8s/variables.tf index 292fd874..1c6e4731 100644 --- a/{{cookiecutter.project_dirname}}/terraform/environment/digitalocean-k8s/variables.tf +++ b/{{cookiecutter.project_dirname}}/terraform/environment/digitalocean-k8s/variables.tf @@ -41,6 +41,18 @@ variable "basic_auth_username" { default = "" } +variable "create_dns_records" { + description = "Tell if DigitalOcean DNS records should be created." + type = bool + default = true +} + +variable "create_domain" { + description = "Tell if a DigitalOcean domain should be created." + type = bool + default = false +} + variable "database_connection_pool_size" { description = "The DigitalOcean database connection pool size." type = number @@ -65,12 +77,6 @@ variable "digitalocean_token" { sensitive = true } -variable "domain_prefix" { - description = "The environment domain prefix (e.g. 'www')." - type = string - default = "" -} - variable "env_slug" { description = "The environment slug (e.g. 'prod')." type = string @@ -100,17 +106,47 @@ variable "frontend_service_slug" { default = "" } -variable "project_slug" { - description = "The project slug." +variable "grafana_password" { + description = "The Grafana admin password." type = string + sensitive = true + default = "" } -variable "project_url" { - description = "The project url." +variable "grafana_user" { + description = "The Grafana admin username." + type = string + default = "admin" +} + +variable "grafana_version" { + description = "The Grafana version." + type = string + default = "8.4.2" +} + +variable "letsencrypt_certificate_email" { + description = "The email used to issue the Let's Encrypt certificate." type = string default = "" } +variable "monitoring_subdomain" { + description = "The monitoring subdomain." + type = string + default = "" +} + +variable "project_domain" { + description = "The project domain." + type = string +} + +variable "project_slug" { + description = "The project slug." + type = string +} + variable "registry_password" { description = "The Docker image registry password." type = string @@ -165,6 +201,12 @@ variable "stack_slug" { type = string } +variable "subdomains" { + description = "The subdomains associated to the environment." + type = list(string) + default = [] +} + variable "tls_certificate_crt" { description = "The TLS certificate .crt file content." type = string diff --git a/{{cookiecutter.project_dirname}}/terraform/cluster/modules/kubernetes/monitoring/grafana/dashboards/k8s-logs.json b/{{cookiecutter.project_dirname}}/terraform/environment/modules/kubernetes/monitoring/grafana/dashboards/k8s-logs.json similarity index 100% rename from {{cookiecutter.project_dirname}}/terraform/cluster/modules/kubernetes/monitoring/grafana/dashboards/k8s-logs.json rename to {{cookiecutter.project_dirname}}/terraform/environment/modules/kubernetes/monitoring/grafana/dashboards/k8s-logs.json diff --git a/{{cookiecutter.project_dirname}}/terraform/cluster/modules/kubernetes/monitoring/grafana/values.yaml b/{{cookiecutter.project_dirname}}/terraform/environment/modules/kubernetes/monitoring/grafana/values.yaml similarity index 100% rename from {{cookiecutter.project_dirname}}/terraform/cluster/modules/kubernetes/monitoring/grafana/values.yaml rename to {{cookiecutter.project_dirname}}/terraform/environment/modules/kubernetes/monitoring/grafana/values.yaml diff --git a/{{cookiecutter.project_dirname}}/terraform/cluster/modules/kubernetes/monitoring/main.tf b/{{cookiecutter.project_dirname}}/terraform/environment/modules/kubernetes/monitoring/main.tf similarity index 78% rename from {{cookiecutter.project_dirname}}/terraform/cluster/modules/kubernetes/monitoring/main.tf rename to {{cookiecutter.project_dirname}}/terraform/environment/modules/kubernetes/monitoring/main.tf index 4a1e0118..a2fc1ba5 100644 --- a/{{cookiecutter.project_dirname}}/terraform/cluster/modules/kubernetes/monitoring/main.tf +++ b/{{cookiecutter.project_dirname}}/terraform/environment/modules/kubernetes/monitoring/main.tf @@ -92,31 +92,3 @@ resource "helm_release" "grafana" { depends_on = [kubernetes_config_map_v1.k8s_logs_dashboard] } - -/* Grafana Ingress Route */ - -resource "kubernetes_manifest" "grafana_ingress_route" { - manifest = { - apiVersion = "traefik.containo.us/v1alpha1" - kind = "IngressRoute" - metadata = { - name = "grafana-ingress-route" - namespace = local.namespace - } - spec = { - entryPoints = ["web", "websecure"] - routes = [ - { - kind = "Rule" - match = "Host(`${var.host}`) && PathPrefix(`/`)" - services = [ - { - name = "grafana" - port = 80 - } - ] - } - ] - } - } -} diff --git a/{{cookiecutter.project_dirname}}/terraform/cluster/modules/kubernetes/monitoring/variables.tf b/{{cookiecutter.project_dirname}}/terraform/environment/modules/kubernetes/monitoring/variables.tf similarity index 75% rename from {{cookiecutter.project_dirname}}/terraform/cluster/modules/kubernetes/monitoring/variables.tf rename to {{cookiecutter.project_dirname}}/terraform/environment/modules/kubernetes/monitoring/variables.tf index 6a7520d3..89cbe090 100644 --- a/{{cookiecutter.project_dirname}}/terraform/cluster/modules/kubernetes/monitoring/variables.tf +++ b/{{cookiecutter.project_dirname}}/terraform/environment/modules/kubernetes/monitoring/variables.tf @@ -13,9 +13,3 @@ variable "grafana_version" { description = "The Grafana version." type = string } - -variable "host" { - description = "The monitoring host." - type = string - default = "" -} diff --git a/{{cookiecutter.project_dirname}}/terraform/environment/modules/kubernetes/routing/main.tf b/{{cookiecutter.project_dirname}}/terraform/environment/modules/kubernetes/routing/main.tf index 6fc9ebfa..08aecf12 100644 --- a/{{cookiecutter.project_dirname}}/terraform/environment/modules/kubernetes/routing/main.tf +++ b/{{cookiecutter.project_dirname}}/terraform/environment/modules/kubernetes/routing/main.tf @@ -7,9 +7,16 @@ locals { ] ) + domains = [for i in var.subdomains : i == "" ? var.project_domain : "${i}.${var.project_domain}"] + monitoring_domain = var.monitoring_subdomain != "" ? "${var.monitoring_subdomain}.${var.project_domain}" : "" + + traefik_hosts = join(", ", [for i in local.domains : "`${i}`"]) + base_middlewares = local.basic_auth_enabled ? [{ "name" : "traefik-basic-auth-middleware" }] : [] - tls_enabled = var.tls_certificate_crt != "" && var.tls_certificate_key != "" + letsencrypt_enabled = var.letsencrypt_certificate_email != "" + manual_certificate_enabled = var.tls_certificate_crt != "" && var.tls_certificate_key != "" + tls_enabled = local.manual_certificate_enabled || local.letsencrypt_enabled } terraform { @@ -58,10 +65,31 @@ resource "kubernetes_manifest" "traefik_basic_auth_middleware" { } } +/* HTTPS Redirect */ + +resource "kubernetes_manifest" "middleware_redirect_to_https" { + count = local.tls_enabled ? 1 : 0 + + manifest = { + apiVersion = "traefik.containo.us/v1alpha1" + kind = "Middleware" + metadata = { + name = "redirect-to-https" + namespace = var.namespace + } + spec = { + redirectScheme = { + scheme = "https" + permanent = true + } + } + } +} + /* TLS Secret */ resource "kubernetes_secret_v1" "tls" { - count = local.tls_enabled ? 1 : 0 + count = local.manual_certificate_enabled ? 1 : 0 metadata { name = "tls-certificate" @@ -76,6 +104,62 @@ resource "kubernetes_secret_v1" "tls" { type = "kubernetes.io/tls" } +/* Let's Encrypt Certificate */ + +resource "kubernetes_manifest" "issuer" { + count = local.letsencrypt_enabled ? 1 : 0 + + manifest = { + apiVersion = "cert-manager.io/v1" + kind = "Issuer" + metadata = { + name = "letsencrypt" + namespace = var.namespace + } + spec = { + acme = { + email = var.letsencrypt_certificate_email + server = "https://acme-staging-v02.api.letsencrypt.org/directory" + privateKeySecretRef = { + name = "issuer-private-key" + } + solvers = [ + { + http01 = { + ingress = { + class = "traefik-cert-manager" + } + } + } + ] + } + } + } +} + +resource "kubernetes_manifest" "certificate" { + count = local.letsencrypt_enabled ? 1 : 0 + + manifest = { + apiVersion = "cert-manager.io/v1" + kind = "Certificate" + metadata = { + name = "letsencrypt" + namespace = var.namespace + } + spec = { + secretName = "tls-certificate" + issuerRef = { + name = "letsencrypt" + kind = "Issuer" + } + dnsNames = concat( + local.domains, local.monitoring_domain != "" ? [local.monitoring_domain] : [] + ) + } + } +} + /* Traefik Ingress Route */ resource "kubernetes_manifest" "traefik_ingress_route" { @@ -88,16 +172,16 @@ resource "kubernetes_manifest" "traefik_ingress_route" { } spec = merge( { - entryPoints = ["web", "websecure"] + entryPoints = local.tls_enabled ? ["websecure"] : ["web"] routes = concat( # frontend routes [ for path in toset(var.frontend_service_paths) : { kind = "Rule" - match = "Host(`${var.project_host}`) && PathPrefix(`${path}`)" + match = "Host(${local.traefik_hosts}) && PathPrefix(`${path}`)" middlewares = concat( local.base_middlewares, - var.frontend_service_extra_middlewares, + [for i in var.frontend_service_extra_middlewares : {name = i}], ) services = [ { @@ -111,10 +195,10 @@ resource "kubernetes_manifest" "traefik_ingress_route" { [ for path in toset(var.backend_service_paths) : { kind = "Rule" - match = "Host(`${var.project_host}`) && PathPrefix(`${path}`)" + match = "Host(${local.traefik_hosts}) && PathPrefix(`${path}`)" middlewares = concat( local.base_middlewares, - var.backend_service_extra_middlewares, + [for i in var.backend_service_extra_middlewares : {name = i}], ) services = [ { @@ -123,14 +207,60 @@ resource "kubernetes_manifest" "traefik_ingress_route" { } ] } - ] + ], + # monitoring rule + local.monitoring_domain != "" ? [ + { + kind = "Rule" + match = "Host(`${local.monitoring_domain}`) && PathPrefix(`/`)" + services = [ + { + name = "grafana" + port = 80 + } + ] + } + ] : [] ) }, local.tls_enabled ? { tls = { - secretName = kubernetes_secret_v1.tls[0].metadata[0].name + secretName = "tls-certificate" } } : {} ) } } + +resource "kubernetes_manifest" "ingressroute_redirect_to_https" { + count = local.tls_enabled ? 1 : 0 + + manifest = { + apiVersion = "traefik.containo.us/v1alpha1" + kind = "IngressRoute" + metadata = { + name = "redirect-to-https" + namespace = var.namespace + } + spec = merge( + { + entryPoints = ["web"] + routes = [ + { + kind = "Rule" + match = "Host(${local.traefik_hosts})" + middlewares = [ + {name = "redirect-to-https"} + ] + services = [ + { + name = var.frontend_service_slug + port = var.frontend_service_port + } + ] + } + ] + } + ) + } +} diff --git a/{{cookiecutter.project_dirname}}/terraform/environment/modules/kubernetes/routing/variables.tf b/{{cookiecutter.project_dirname}}/terraform/environment/modules/kubernetes/routing/variables.tf index 1ee55ced..96d81909 100644 --- a/{{cookiecutter.project_dirname}}/terraform/environment/modules/kubernetes/routing/variables.tf +++ b/{{cookiecutter.project_dirname}}/terraform/environment/modules/kubernetes/routing/variables.tf @@ -65,16 +65,34 @@ variable "frontend_service_slug" { default = "" } +variable "letsencrypt_certificate_email" { + description = "The email used to issue the Let's Encrypt certificate." + type = string + default = "" +} + +variable "monitoring_subdomain" { + description = "The monitoring subdomain, if enabled." + type = string + default = "" +} + variable "namespace" { description = "The namespace for Kubernetes resources." type = string } -variable "project_host" { - description = "The project host." +variable "project_domain" { + description = "The project domain." type = string } +variable "subdomains" { + description = "The subdomains associated to the environment." + type = list(string) + default = [] +} + variable "tls_certificate_crt" { description = "The TLS certificate .crt file content." type = string diff --git a/{{cookiecutter.project_dirname}}/terraform/environment/other-k8s/main.tf b/{{cookiecutter.project_dirname}}/terraform/environment/other-k8s/main.tf index deb73c2e..3e5a3667 100644 --- a/{{cookiecutter.project_dirname}}/terraform/environment/other-k8s/main.tf +++ b/{{cookiecutter.project_dirname}}/terraform/environment/other-k8s/main.tf @@ -1,8 +1,6 @@ locals { namespace = kubernetes_namespace_v1.main.metadata[0].name - project_host = regexall("https?://([^/]+)", var.project_url)[0][0] - postgres_dump_enabled = alltrue( [ var.database_dumps_enabled, @@ -72,6 +70,18 @@ module "redis" { key_prefix = var.env_slug } +/* Monitoring */ + +module "monitoring" { + count = var.monitoring_subdomain != "" ? 1 : 0 + + source = "../modules/kubernetes/monitoring" + + grafana_user = var.grafana_user + grafana_password = var.grafana_password + grafana_version = var.grafana_version +} + /* Routing */ module "routing" { @@ -79,7 +89,8 @@ module "routing" { namespace = local.namespace - project_host = local.project_host + project_domain = var.project_domain + subdomains = var.subdomains basic_auth_enabled = var.basic_auth_enabled basic_auth_username = var.basic_auth_username @@ -95,8 +106,11 @@ module "routing" { frontend_service_paths = var.frontend_service_paths frontend_service_port = var.frontend_service_port - tls_certificate_crt = var.tls_certificate_crt - tls_certificate_key = var.tls_certificate_key + letsencrypt_certificate_email = var.letsencrypt_certificate_email + tls_certificate_crt = var.tls_certificate_crt + tls_certificate_key = var.tls_certificate_key + + monitoring_subdomain = var.monitoring_subdomain } /* Secrets */ diff --git a/{{cookiecutter.project_dirname}}/terraform/environment/other-k8s/variables.tf b/{{cookiecutter.project_dirname}}/terraform/environment/other-k8s/variables.tf index 4b8d7f34..531cc231 100644 --- a/{{cookiecutter.project_dirname}}/terraform/environment/other-k8s/variables.tf +++ b/{{cookiecutter.project_dirname}}/terraform/environment/other-k8s/variables.tf @@ -47,12 +47,6 @@ variable "database_dumps_enabled" { default = false } -variable "domain_prefix" { - description = "The environment domain prefix (e.g. 'www')." - type = string - default = "" -} - variable "env_slug" { description = "The environment slug (e.g. 'prod')." type = string @@ -82,6 +76,25 @@ variable "frontend_service_slug" { default = "" } +variable "grafana_password" { + description = "The Grafana admin password." + type = string + sensitive = true + default = "" +} + +variable "grafana_user" { + description = "The Grafana admin username." + type = string + default = "admin" +} + +variable "grafana_version" { + description = "The Grafana version." + type = string + default = "8.4.2" +} + variable "kubernetes_cluster_ca_certificate" { description = "The base64 encoded Kubernetes CA certificate." type = string @@ -99,6 +112,18 @@ variable "kubernetes_token" { sensitive = true } +variable "letsencrypt_certificate_email" { + description = "The email used to issue the Let's Encrypt certificate." + type = string + default = "" +} + +variable "monitoring_subdomain" { + description = "The monitoring subdomain." + type = string + default = "" +} + variable "postgres_image" { description = "The Postgres Docker image." type = string @@ -125,7 +150,6 @@ variable "postgres_persistent_volume_host_path" { variable "project_domain" { description = "The project domain." type = string - default = "" } variable "project_slug" { @@ -133,12 +157,6 @@ variable "project_slug" { type = string } -variable "project_url" { - description = "The project url." - type = string - default = "" -} - variable "redis_image" { description = "The Redis Docker image." type = string @@ -199,6 +217,12 @@ variable "stack_slug" { type = string } +variable "subdomains" { + description = "The subdomains associated to the environment." + type = list(string) + default = [] +} + variable "tls_certificate_crt" { description = "The TLS certificate .crt file content." type = string From 5001c2ff01ceb53e16ee8997d326504f2b0d6afb Mon Sep 17 00:00:00 2001 From: Filippo Morelli Date: Sun, 22 May 2022 16:09:37 +0000 Subject: [PATCH 3/8] Review Terraform files --- .../environment/digitalocean-k8s/main.tf | 1 + .../environment/digitalocean-k8s/variables.tf | 6 ++++++ .../modules/kubernetes/routing/main.tf | 16 ++++++++-------- .../modules/kubernetes/routing/variables.tf | 6 ++++++ .../terraform/environment/other-k8s/main.tf | 1 + .../terraform/environment/other-k8s/variables.tf | 6 ++++++ 6 files changed, 28 insertions(+), 8 deletions(-) diff --git a/{{cookiecutter.project_dirname}}/terraform/environment/digitalocean-k8s/main.tf b/{{cookiecutter.project_dirname}}/terraform/environment/digitalocean-k8s/main.tf index 04e753c5..9abbc157 100644 --- a/{{cookiecutter.project_dirname}}/terraform/environment/digitalocean-k8s/main.tf +++ b/{{cookiecutter.project_dirname}}/terraform/environment/digitalocean-k8s/main.tf @@ -177,6 +177,7 @@ module "routing" { frontend_service_port = var.frontend_service_port letsencrypt_certificate_email = var.letsencrypt_certificate_email + letsencrypt_server = var.letsencrypt_server tls_certificate_crt = var.tls_certificate_crt tls_certificate_key = var.tls_certificate_key diff --git a/{{cookiecutter.project_dirname}}/terraform/environment/digitalocean-k8s/variables.tf b/{{cookiecutter.project_dirname}}/terraform/environment/digitalocean-k8s/variables.tf index 1c6e4731..97d79a03 100644 --- a/{{cookiecutter.project_dirname}}/terraform/environment/digitalocean-k8s/variables.tf +++ b/{{cookiecutter.project_dirname}}/terraform/environment/digitalocean-k8s/variables.tf @@ -131,6 +131,12 @@ variable "letsencrypt_certificate_email" { default = "" } +variable "letsencrypt_server" { + description = "The Let's Encrypt server used to generate certificates." + type = string + default = "" +} + variable "monitoring_subdomain" { description = "The monitoring subdomain." type = string diff --git a/{{cookiecutter.project_dirname}}/terraform/environment/modules/kubernetes/routing/main.tf b/{{cookiecutter.project_dirname}}/terraform/environment/modules/kubernetes/routing/main.tf index 08aecf12..ec891f40 100644 --- a/{{cookiecutter.project_dirname}}/terraform/environment/modules/kubernetes/routing/main.tf +++ b/{{cookiecutter.project_dirname}}/terraform/environment/modules/kubernetes/routing/main.tf @@ -119,7 +119,7 @@ resource "kubernetes_manifest" "issuer" { spec = { acme = { email = var.letsencrypt_certificate_email - server = "https://acme-staging-v02.api.letsencrypt.org/directory" + server = coalesce(var.letsencrypt_server, "https://acme-v02.api.letsencrypt.org/directory") privateKeySecretRef = { name = "issuer-private-key" } @@ -181,7 +181,7 @@ resource "kubernetes_manifest" "traefik_ingress_route" { match = "Host(${local.traefik_hosts}) && PathPrefix(`${path}`)" middlewares = concat( local.base_middlewares, - [for i in var.frontend_service_extra_middlewares : {name = i}], + [for i in var.frontend_service_extra_middlewares : { name = i }], ) services = [ { @@ -198,7 +198,7 @@ resource "kubernetes_manifest" "traefik_ingress_route" { match = "Host(${local.traefik_hosts}) && PathPrefix(`${path}`)" middlewares = concat( local.base_middlewares, - [for i in var.backend_service_extra_middlewares : {name = i}], + [for i in var.backend_service_extra_middlewares : { name = i }], ) services = [ { @@ -247,15 +247,15 @@ resource "kubernetes_manifest" "ingressroute_redirect_to_https" { entryPoints = ["web"] routes = [ { - kind = "Rule" - match = "Host(${local.traefik_hosts})" + kind = "Rule" + match = "Host(${local.traefik_hosts})" middlewares = [ - {name = "redirect-to-https"} + { name = "redirect-to-https" } ] services = [ { - name = var.frontend_service_slug - port = var.frontend_service_port + name = coalesce(var.frontend_service_slug, var.backend_service_slug) + port = coalesce(var.frontend_service_port, var.backend_service_port) } ] } diff --git a/{{cookiecutter.project_dirname}}/terraform/environment/modules/kubernetes/routing/variables.tf b/{{cookiecutter.project_dirname}}/terraform/environment/modules/kubernetes/routing/variables.tf index 96d81909..5e7a2ebe 100644 --- a/{{cookiecutter.project_dirname}}/terraform/environment/modules/kubernetes/routing/variables.tf +++ b/{{cookiecutter.project_dirname}}/terraform/environment/modules/kubernetes/routing/variables.tf @@ -71,6 +71,12 @@ variable "letsencrypt_certificate_email" { default = "" } +variable "letsencrypt_server" { + description = "The Let's Encrypt server used to generate certificates." + type = string + default = "" +} + variable "monitoring_subdomain" { description = "The monitoring subdomain, if enabled." type = string diff --git a/{{cookiecutter.project_dirname}}/terraform/environment/other-k8s/main.tf b/{{cookiecutter.project_dirname}}/terraform/environment/other-k8s/main.tf index 3e5a3667..05be695b 100644 --- a/{{cookiecutter.project_dirname}}/terraform/environment/other-k8s/main.tf +++ b/{{cookiecutter.project_dirname}}/terraform/environment/other-k8s/main.tf @@ -107,6 +107,7 @@ module "routing" { frontend_service_port = var.frontend_service_port letsencrypt_certificate_email = var.letsencrypt_certificate_email + letsencrypt_server = var.letsencrypt_server tls_certificate_crt = var.tls_certificate_crt tls_certificate_key = var.tls_certificate_key diff --git a/{{cookiecutter.project_dirname}}/terraform/environment/other-k8s/variables.tf b/{{cookiecutter.project_dirname}}/terraform/environment/other-k8s/variables.tf index 531cc231..4d3c3415 100644 --- a/{{cookiecutter.project_dirname}}/terraform/environment/other-k8s/variables.tf +++ b/{{cookiecutter.project_dirname}}/terraform/environment/other-k8s/variables.tf @@ -118,6 +118,12 @@ variable "letsencrypt_certificate_email" { default = "" } +variable "letsencrypt_server" { + description = "The Let's Encrypt server used to generate certificates." + type = string + default = "" +} + variable "monitoring_subdomain" { description = "The monitoring subdomain." type = string From a81e6bc0077c9ff0fb509f180af7b11f6f6d0f39 Mon Sep 17 00:00:00 2001 From: Filippo Morelli Date: Sun, 22 May 2022 21:49:54 +0000 Subject: [PATCH 4/8] Fix project bootstrap --- README.md | 8 +- bootstrap/collector.py | 73 +++++++++---------- bootstrap/runner.py | 60 ++++++--------- start.py | 9 +-- tests/test_collector.py | 10 --- .../base/digitalocean-k8s/variables.tf | 6 -- 6 files changed, 64 insertions(+), 102 deletions(-) diff --git a/README.md b/README.md index 90b7e413..be430b6e 100644 --- a/README.md +++ b/README.md @@ -281,9 +281,9 @@ If you don't want DigitalOcean DNS configuration the following args are required If you want DigitalOcean DNS configuration the following args are required `--project-domain=project-domain.com`
-`--domain-prefix-dev=dev`
-`--domain-prefix-stage=test`
-`--domain-prefix-prod=www` +`--subdomain-dev=dev`
+`--subdomain-stage=test`
+`--subdomain-prod=www` #### Kubernetes cluster DigitalOcean region @@ -303,7 +303,7 @@ For enabling monitoring the following arguments are needed: if project domain is managed use -`--domain-prefix-monitoring=logs` +`--subdomain-monitoring=logs` else use diff --git a/bootstrap/collector.py b/bootstrap/collector.py index 5728a081..b8c90754 100755 --- a/bootstrap/collector.py +++ b/bootstrap/collector.py @@ -64,14 +64,13 @@ def collect( kubernetes_token, environment_distribution, project_domain, - domain_prefix_dev, - domain_prefix_stage, - domain_prefix_prod, - domain_prefix_monitoring, + subdomain_dev, + subdomain_stage, + subdomain_prod, + subdomain_monitoring, project_url_dev, project_url_stage, project_url_prod, - project_url_monitoring, letsencrypt_certificate_email, digitalocean_domain_create, digitalocean_dns_records_create, @@ -163,27 +162,25 @@ def collect( ) ( project_domain, - domain_prefix_dev, - domain_prefix_stage, - domain_prefix_prod, - domain_prefix_monitoring, + subdomain_dev, + subdomain_stage, + subdomain_prod, + subdomain_monitoring, project_url_dev, project_url_stage, project_url_prod, - project_url_monitoring, letsencrypt_certificate_email, ) = clean_domains( project_slug, project_domain, use_monitoring, - domain_prefix_dev, - domain_prefix_stage, - domain_prefix_prod, - domain_prefix_monitoring, + subdomain_dev, + subdomain_stage, + subdomain_prod, + subdomain_monitoring, project_url_dev, project_url_stage, project_url_prod, - project_url_monitoring, letsencrypt_certificate_email, ) use_redis = click.confirm(warning("Do you want to use Redis?"), default=False) @@ -304,16 +301,16 @@ def collect( "kubernetes_token": kubernetes_token, "environment_distribution": environment_distribution, "project_domain": project_domain, - "domain_prefix_dev": domain_prefix_dev, - "domain_prefix_stage": domain_prefix_stage, - "domain_prefix_prod": domain_prefix_prod, - "domain_prefix_monitoring": domain_prefix_monitoring, + "subdomain_dev": subdomain_dev, + "subdomain_stage": subdomain_stage, + "subdomain_prod": subdomain_prod, + "subdomain_monitoring": subdomain_monitoring, "project_url_dev": project_url_dev, "project_url_stage": project_url_stage, "project_url_prod": project_url_prod, - "project_url_monitoring": project_url_monitoring, "letsencrypt_certificate_email": letsencrypt_certificate_email, "digitalocean_domain_create": digitalocean_domain_create, + "digitalocean_dns_records_create": digitalocean_dns_records_create, "digitalocean_k8s_cluster_region": digitalocean_k8s_cluster_region, "digitalocean_database_cluster_region": digitalocean_database_cluster_region, "digitalocean_database_cluster_node_size": ( @@ -589,53 +586,49 @@ def clean_domains( project_slug, project_domain, use_monitoring, - domain_prefix_dev, - domain_prefix_stage, - domain_prefix_prod, - domain_prefix_monitoring, + subdomain_dev, + subdomain_stage, + subdomain_prod, + subdomain_monitoring, project_url_dev, project_url_stage, project_url_prod, - project_url_monitoring, letsencrypt_certificate_email, ): """Return project URLs.""" project_domain = validate_or_prompt_domain( "Project domain", project_domain, default=f"{project_slug}.com" ) - domain_prefix_dev = domain_prefix_dev or click.prompt( + subdomain_dev = subdomain_dev or click.prompt( "Development domain prefix", default="dev" ) - project_url_dev = f"https://{domain_prefix_dev}.{project_domain}" - domain_prefix_stage = domain_prefix_stage or click.prompt( + project_url_dev = f"https://{subdomain_dev}.{project_domain}" + subdomain_stage = subdomain_stage or click.prompt( "Staging domain prefix", default="stage" ) - project_url_stage = f"https://{domain_prefix_stage}.{project_domain}" - domain_prefix_prod = domain_prefix_prod or click.prompt( + project_url_stage = f"https://{subdomain_stage}.{project_domain}" + subdomain_prod = subdomain_prod or click.prompt( "Production domain prefix", default="www" ) - project_url_prod = f"https://{domain_prefix_prod}.{project_domain}" + project_url_prod = f"https://{subdomain_prod}.{project_domain}" if use_monitoring: - domain_prefix_monitoring = domain_prefix_monitoring or click.prompt( + subdomain_monitoring = subdomain_monitoring or click.prompt( "Monitorng domain prefix", default="logs" ) - project_url_monitoring = f"https://{domain_prefix_monitoring}.{project_domain}" else: - domain_prefix_monitoring = None - project_url_monitoring = None + subdomain_monitoring = None letsencrypt_certificate_email = clean_letsencrypt_certificate_email( letsencrypt_certificate_email ) return ( project_domain, - domain_prefix_dev, - domain_prefix_stage, - domain_prefix_prod, - domain_prefix_monitoring, + subdomain_dev, + subdomain_stage, + subdomain_prod, + subdomain_monitoring, project_url_dev, project_url_stage, project_url_prod, - project_url_monitoring, letsencrypt_certificate_email, ) diff --git a/bootstrap/runner.py b/bootstrap/runner.py index 4fac8b04..608af425 100644 --- a/bootstrap/runner.py +++ b/bootstrap/runner.py @@ -68,16 +68,16 @@ class Runner: kubernetes_token: str | None = None environment_distribution: str project_domain: str | None = None - domain_prefix_dev: str | None = None - domain_prefix_stage: str | None = None - domain_prefix_prod: str | None = None - domain_prefix_monitoring: str | None = None + subdomain_dev: str | None = None + subdomain_stage: str | None = None + subdomain_prod: str | None = None + subdomain_monitoring: str | None = None project_url_dev: str = "" project_url_stage: str = "" project_url_prod: str = "" - project_url_monitoring: str | None = None letsencrypt_certificate_email: str | None = None digitalocean_domain_create: bool | None = None + digitalocean_dns_records_create: bool | None = None digitalocean_k8s_cluster_region: str | None = None digitalocean_database_cluster_region: str | None = None digitalocean_database_cluster_node_size: str | None = None @@ -131,17 +131,17 @@ def set_stacks_environments(self): dev_env = { "name": "Development", "url": self.project_url_dev, - "prefix": self.domain_prefix_dev, + "prefix": self.subdomain_dev, } stage_env = { "name": "Staging", "url": self.project_url_stage, - "prefix": self.domain_prefix_stage, + "prefix": self.subdomain_stage, } prod_env = { "name": "Production", "url": self.project_url_prod, - "prefix": self.domain_prefix_prod, + "prefix": self.subdomain_prod, } if self.environment_distribution == "1": self.stacks_environments = { @@ -204,24 +204,22 @@ def set_tfvars(self): ("backend_service_port", None, "num"), "backend_service_slug", ) - self.project_domain and self.add_cluster_tfvars("project_domain") - self.letsencrypt_certificate_email and self.add_cluster_tfvars( - "letsencrypt_certificate_email", - ("ssl_enabled", True, "bool"), + self.project_domain and self.add_environment_tfvars("project_domain") + if self.letsencrypt_certificate_email: + self.add_cluster_tfvars("letsencrypt_certificate_email") + self.add_environment_tfvars("letsencrypt_certificate_email") + self.subdomain_monitoring and self.add_environment_tfvars( + ("monitoring_subdomain", self.subdomain_monitoring), env_slug="prod" ) if self.use_redis: self.add_base_tfvars(("use_redis", True, "bool")) self.add_environment_tfvars(("use_redis", True, "bool")) - if self.project_url_monitoring: - self.add_cluster_tfvars( - ("monitoring_url", self.project_url_monitoring), - ) - self.domain_prefix_monitoring and self.add_cluster_tfvars( - ("monitoring_domain_prefix", self.domain_prefix_monitoring), - ) if "digitalocean" in self.deployment_type: - self.project_domain and self.add_cluster_tfvars( - ("create_domain", self.digitalocean_domain_create, "bool") + self.add_environment_tfvars( + ("create_dns_records", self.digitalocean_dns_records_create, "bool"), + ) + self.digitalocean_domain_create and self.add_environment_tfvars( + ("create_domain", True, "bool"), env_slug="dev" ) self.add_base_tfvars( ("k8s_cluster_region", self.digitalocean_k8s_cluster_region), @@ -248,22 +246,10 @@ def set_tfvars(self): self.add_environment_tfvars( ("digitalocean_spaces_bucket_available", True, "bool") ) - for stack_slug, stack_envs in self.stacks_environments.items(): - domain_prefixes = [] - for env_slug, env_data in stack_envs.items(): - self.add_environment_tfvars( - ("basic_auth_enabled", env_slug != "prod", "bool"), - ("project_url", env_data["url"]), - ("stack_slug", stack_slug), - env_slug=env_slug, - ) - if env_prefix := env_data["prefix"]: - domain_prefixes.append(env_prefix) - self.add_environment_tfvars( - ("domain_prefix", env_prefix), env_slug=env_slug - ) - domain_prefixes and self.add_cluster_tfvars( - ("domain_prefixes", domain_prefixes, "list"), stack_slug=stack_slug + for env_slug in ("dev", "stage", "prod"): + self.add_environment_tfvars( + ("subdomains", [getattr(self, f"subdomain_{env_slug}")], "list"), + env_slug=env_slug, ) def init_service(self): diff --git a/start.py b/start.py index 641d857e..04434bed 100755 --- a/start.py +++ b/start.py @@ -64,14 +64,13 @@ "--environment-distribution", type=click.Choice(ENVIRONMENT_DISTRIBUTION_CHOICES) ) @click.option("--project-domain") -@click.option("--domain-prefix-dev") -@click.option("--domain-prefix-stage") -@click.option("--domain-prefix-prod") -@click.option("--domain-prefix-monitoring") +@click.option("--subdomain-dev") +@click.option("--subdomain-stage") +@click.option("--subdomain-prod") +@click.option("--subdomain-monitoring") @click.option("--project-url-dev") @click.option("--project-url-stage") @click.option("--project-url-prod") -@click.option("--project-url-monitoring") @click.option("--letsencrypt-certificate-email") # ADD TO README @click.option( "--digitalocean-domain-create/--digitalocean-domain-create-skip", diff --git a/tests/test_collector.py b/tests/test_collector.py index 2377d218..99f97443 100644 --- a/tests/test_collector.py +++ b/tests/test_collector.py @@ -220,7 +220,6 @@ def test_clean_domains(self): None, None, None, - None, "test@test.com", ), ( @@ -232,7 +231,6 @@ def test_clean_domains(self): "https://alpha.myproject.com", "https://beta.myproject.com", "https://www2.myproject.com", - None, "test@test.com", ), ) @@ -248,7 +246,6 @@ def test_clean_domains(self): None, None, None, - None, "test@test.com", ), ( @@ -260,7 +257,6 @@ def test_clean_domains(self): "https://alpha.myproject.com", "https://beta.myproject.com", "https://www2.myproject.com", - None, "test@test.com", ), ) @@ -285,7 +281,6 @@ def test_clean_domains(self): None, None, None, - None, ), ( "myproject.com", @@ -297,7 +292,6 @@ def test_clean_domains(self): "https://beta.myproject.com", "https://www2.myproject.com", None, - None, ), ) # monitoring enabled @@ -315,7 +309,6 @@ def test_clean_domains(self): None, None, None, - None, ), ( "myproject.com", @@ -326,7 +319,6 @@ def test_clean_domains(self): "https://alpha.myproject.com", "https://beta.myproject.com", "https://www2.myproject.com", - "https://mylogs.myproject.com", None, ), ) # Let's Encrypt certificates enabled @@ -352,7 +344,6 @@ def test_clean_domains(self): None, None, None, - None, ), ( "myproject.com", @@ -363,7 +354,6 @@ def test_clean_domains(self): "https://alpha.myproject.com", "https://beta.myproject.com", "https://www2.myproject.com", - "https://mylogs.myproject.com", "test@test.com", ), ) diff --git a/{{cookiecutter.project_dirname}}/terraform/base/digitalocean-k8s/variables.tf b/{{cookiecutter.project_dirname}}/terraform/base/digitalocean-k8s/variables.tf index 9f41bc66..7f18613f 100644 --- a/{{cookiecutter.project_dirname}}/terraform/base/digitalocean-k8s/variables.tf +++ b/{{cookiecutter.project_dirname}}/terraform/base/digitalocean-k8s/variables.tf @@ -140,12 +140,6 @@ variable "stack_slug" { type = string } -variable "ssl_enabled" { - description = "Tell if SSL should be enabled." - type = bool - default = false -} - variable "use_redis" { description = "Tell if a Redis service is used." type = bool From 45e2ad60ba0450a24d28531434f0cbd7f01e483a Mon Sep 17 00:00:00 2001 From: daniele20tab Date: Mon, 23 May 2022 20:22:38 +0200 Subject: [PATCH 5/8] Hotfix --- bootstrap/runner.py | 2 +- .../scripts/terraform.sh | 1 - .../traefik/conf/dynamic.yaml | 14 +++++++------- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/bootstrap/runner.py b/bootstrap/runner.py index 608af425..9cadb4c6 100644 --- a/bootstrap/runner.py +++ b/bootstrap/runner.py @@ -404,7 +404,7 @@ def get_gitlab_variables(self): gitlab_group_variables.update( TFC_TOKEN='{value = "%s", masked = true}' % self.terraform_cloud_token, ) - if self.project_url_monitoring: + if self.subdomain_monitoring: gitlab_project_variables.update( GRAFANA_PASSWORD='{value = "%s", masked = true}' % secrets.token_urlsafe(12), diff --git a/{{cookiecutter.project_dirname}}/scripts/terraform.sh b/{{cookiecutter.project_dirname}}/scripts/terraform.sh index 1f99c1fd..26c4dab6 100755 --- a/{{cookiecutter.project_dirname}}/scripts/terraform.sh +++ b/{{cookiecutter.project_dirname}}/scripts/terraform.sh @@ -49,7 +49,6 @@ case "${TERRAFORM_BACKEND}" in export TF_VAR_CI_PROJECT_NAME="${TF_VAR_CI_PROJECT_NAME:-${CI_PROJECT_NAME}}" export TF_VAR_CI_PROJECT_NAMESPACE="${TF_VAR_CI_PROJECT_NAMESPACE:-${CI_PROJECT_NAMESPACE}}" export TF_VAR_CI_PROJECT_PATH="${TF_VAR_CI_PROJECT_PATH:-${CI_PROJECT_PATH}}" - export TF_VAR_CI_PROJECT_URL="${TF_VAR_CI_PROJECT_URL:-${CI_PROJECT_URL}}" ;; "terraform-cloud") export TF_CLI_CONFIG_FILE="${TF_ROOT}/cloud.tfc" diff --git a/{{cookiecutter.project_dirname}}/traefik/conf/dynamic.yaml b/{{cookiecutter.project_dirname}}/traefik/conf/dynamic.yaml index 713dbf2a..5ba87544 100644 --- a/{{cookiecutter.project_dirname}}/traefik/conf/dynamic.yaml +++ b/{{cookiecutter.project_dirname}}/traefik/conf/dynamic.yaml @@ -1,25 +1,25 @@ http: routers:{% if cookiecutter.frontend_type != 'none' %}{% if cookiecutter.backend_type != 'none' %} {{ cookiecutter.backend_service_slug }}-admin: - rule: "PathPrefix(`/admin`)" + rule: "PathPrefix(`/admin`)" service: {{ cookiecutter.backend_service_slug }} {{ cookiecutter.backend_service_slug }}-static: - rule: "PathPrefix(`/static`)" + rule: "PathPrefix(`/static`)" service: {{ cookiecutter.backend_service_slug }} {{ cookiecutter.backend_service_slug }}-api: - rule: "PathPrefix(`/api`)" + rule: "PathPrefix(`/api`)" service: {{ cookiecutter.backend_service_slug }} {{ cookiecutter.backend_service_slug }}-debug: - rule: "PathPrefix(`/__debug__`)" + rule: "PathPrefix(`/__debug__`)" service: {{ cookiecutter.backend_service_slug }}{% endif %} {{ cookiecutter.frontend_service_slug }}: - rule: "PathPrefix(`/`)" + rule: "PathPrefix(`/`)" service: {{ cookiecutter.frontend_service_slug }}{% if cookiecutter.frontend_type == 'nextjs' %} {{ cookiecutter.frontend_service_slug }}-sockjs-node: - rule: "PathPrefix(`/sockjs-node`)" + rule: "PathPrefix(`/sockjs-node`)" service: {{ cookiecutter.frontend_service_slug }}{% endif %}{% else %} {{ cookiecutter.backend_service_slug }}: - rule: "PathPrefix(`/`)" + rule: "PathPrefix(`/`)" service: {{ cookiecutter.backend_service_slug }}{% endif %} services:{% if cookiecutter.backend_type != 'none' %} {{ cookiecutter.backend_service_slug }}: From 6de45a271e29ea0338cf2be73670a82908c4e864 Mon Sep 17 00:00:00 2001 From: Filippo Morelli Date: Mon, 23 May 2022 20:28:05 +0200 Subject: [PATCH 6/8] Restore stack slug and basic auth in TF vars --- bootstrap/runner.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/bootstrap/runner.py b/bootstrap/runner.py index 9cadb4c6..e6a4d0b4 100644 --- a/bootstrap/runner.py +++ b/bootstrap/runner.py @@ -246,11 +246,14 @@ def set_tfvars(self): self.add_environment_tfvars( ("digitalocean_spaces_bucket_available", True, "bool") ) - for env_slug in ("dev", "stage", "prod"): - self.add_environment_tfvars( - ("subdomains", [getattr(self, f"subdomain_{env_slug}")], "list"), - env_slug=env_slug, - ) + for stack_slug, stack_envs in self.stacks_environments.items(): + for env_slug, env_data in stack_envs.items(): + self.add_environment_tfvars( + ("basic_auth_enabled", env_slug != "prod", "bool"), + ("stack_slug", stack_slug), + ("subdomains", [getattr(self, f"subdomain_{env_slug}")], "list"), + env_slug=env_slug, + ) def init_service(self): """Initialize the service.""" From 16a831dbab177e1eaaa45005bbb2006d3ed8d728 Mon Sep 17 00:00:00 2001 From: Filippo Morelli Date: Tue, 24 May 2022 11:14:06 +0200 Subject: [PATCH 7/8] Add Pact support to cookiecutter --- bootstrap/runner.py | 1 + cookiecutter.json | 1 + {{cookiecutter.project_dirname}}/.env_template | 3 +++ {{cookiecutter.project_dirname}}/docker-compose.yaml | 4 +++- 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/bootstrap/runner.py b/bootstrap/runner.py index e6a4d0b4..74eea54c 100644 --- a/bootstrap/runner.py +++ b/bootstrap/runner.py @@ -270,6 +270,7 @@ def init_service(self): "frontend_service_slug": self.frontend_service_slug, "frontend_type": self.frontend_type, "media_storage": self.media_storage, + "pact_enabled": bool(self.pact_broker_url), "project_dirname": self.project_dirname, "project_domain": self.project_domain, "project_name": self.project_name, diff --git a/cookiecutter.json b/cookiecutter.json index 5789b1ae..6f9fffa3 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -11,6 +11,7 @@ "terraform_backend": "gitlab", "terraform_cloud_organization": "", "media_storage": ["digitalocean-s3", "aws-s3", "local", "none"], + "pact_enabled": false, "project_domain": "", "stacks": { "main": { diff --git a/{{cookiecutter.project_dirname}}/.env_template b/{{cookiecutter.project_dirname}}/.env_template index 57fb2cb7..0cdfb0cf 100644 --- a/{{cookiecutter.project_dirname}}/.env_template +++ b/{{cookiecutter.project_dirname}}/.env_template @@ -19,5 +19,8 @@ PYTHONBREAKPOINT=IPython.core.debugger.set_trace # PROJECT_URL=https://localhost:8443 # INTERNAL_BACKEND_URL=http://{{ cookiecutter.backend_service_slug }}:{{ cookiecutter.backend_service_port }} # REACT_ENVIRONMENT=Development +{% endif %}{% if cookiecutter.pact_enabled %}# pact +PACT_BROKER_URL=https://user:password@broker.pact.com +PACT_PROVIDER_NAME={{ cookiecutter.project_slug }} {% endif %}# orchestrator COMPOSE_FILE=docker-compose.yaml diff --git a/{{cookiecutter.project_dirname}}/docker-compose.yaml b/{{cookiecutter.project_dirname}}/docker-compose.yaml index 325f1eb5..019031c4 100644 --- a/{{cookiecutter.project_dirname}}/docker-compose.yaml +++ b/{{cookiecutter.project_dirname}}/docker-compose.yaml @@ -24,7 +24,9 @@ services: - DJANGO_SUPERUSER_EMAIL - DJANGO_SUPERUSER_PASSWORD - DJANGO_SUPERUSER_USERNAME - - EMAIL_URL + - EMAIL_URL{% if cookiecutter.pact_enabled %} + - PACT_BROKER_URL + - PACT_PROVIDER_NAME{% endif %} - PYTHONBREAKPOINT user: ${USER:-appuser} volumes: From b1c005cbe49186fe9c440bc0870f13bdd3e61433 Mon Sep 17 00:00:00 2001 From: Filippo Morelli Date: Tue, 24 May 2022 13:22:37 +0200 Subject: [PATCH 8/8] Fix Pact provider name --- {{cookiecutter.project_dirname}}/.env_template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_dirname}}/.env_template b/{{cookiecutter.project_dirname}}/.env_template index 0cdfb0cf..cdde1722 100644 --- a/{{cookiecutter.project_dirname}}/.env_template +++ b/{{cookiecutter.project_dirname}}/.env_template @@ -21,6 +21,6 @@ PYTHONBREAKPOINT=IPython.core.debugger.set_trace # REACT_ENVIRONMENT=Development {% endif %}{% if cookiecutter.pact_enabled %}# pact PACT_BROKER_URL=https://user:password@broker.pact.com -PACT_PROVIDER_NAME={{ cookiecutter.project_slug }} +PACT_PROVIDER_NAME={{ cookiecutter.project_slug }}-{{ cookiecutter.backend_service_slug }} {% endif %}# orchestrator COMPOSE_FILE=docker-compose.yaml