diff --git a/modules/chart_cert_manager/kube_objects/clusterissuer.dns01.webhook.ovh.yaml b/modules/chart_cert_manager/kube_objects/clusterissuer.dns01.webhook.ovh.yaml new file mode 100644 index 0000000..63e9078 --- /dev/null +++ b/modules/chart_cert_manager/kube_objects/clusterissuer.dns01.webhook.ovh.yaml @@ -0,0 +1,34 @@ +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: letsencrypt-prod +spec: + acme: + server: https://acme-v02.api.letsencrypt.org/directory + email: ${certificate_email} + privateKeySecretRef: + name: letsencrypt-prod + solvers: + - dns01: + webhook: + groupName: $group_name + solverName: ovh + config: + endpoint: ovh-eu + applicationKey: $application_key + applicationSecretRef: + key: applicationSecret + name: dns-challenge + consumerKey: $consumer_key + podTemplate: + metadata: + labels: + networking/traffic-allowed: "yes" + spec: + tolerations: + - key: "vendor" + operator: "Equal" + value: "cosmotech" + effect: "NoSchedule" + nodeSelector: + "cosmotech.com/tier": "services" \ No newline at end of file diff --git a/modules/chart_cert_manager/main.tf b/modules/chart_cert_manager/main.tf index ade92e7..f277fe7 100644 --- a/modules/chart_cert_manager/main.tf +++ b/modules/chart_cert_manager/main.tf @@ -17,9 +17,9 @@ resource "time_sleep" "wait_certmanager_crds" { } -# 1. CERT-MANAGER -data "template_file" "cert_values" { - template = file("${path.module}/values.yaml") +# 1-0. CERT-MANAGER +data "template_file" "chart_values_cert_manager" { + template = file("${path.module}/values-cert_manager.yaml") vars = { service_annotations = yamlencode(var.service_annotations) } @@ -34,13 +34,43 @@ resource "helm_release" "cert_manager" { create_namespace = true values = [ - data.template_file.cert_values.rendered + data.template_file.chart_values_cert_manager.rendered ] } +# 1-1. (SITUATIONAL) CERT-MANAGER ADDITIONAL CONFIG FOR SPECIFICS PROVIDERS +# - OVH: install Helm Chart cert-manager-webhooks-ovh +data "template_file" "chart_values_webhook_ovh" { + count = (var.cloud_provider == "kob" && var.dns_challenge_provider == "ovh") ? 1 : 0 + + template = file("${path.module}/values-cert_manager_webhook_ovh.yaml") + vars = { + group_name = kubernetes_secret.dns_challenge[0].data["groupName"] + certificate_email = var.certificate_email + } +} + +resource "helm_release" "cert_manager_webhook_ovh" { + count = (var.cloud_provider == "kob" && var.dns_challenge_provider == "ovh") ? 1 : 0 + + name = "cert-manager-webhook-ovh" + repository = "https://aureq.github.io/cert-manager-webhook-ovh/" + chart = "cert-manager-webhook-ovh" + version = "0.9.5" + namespace = "cert-manager" + create_namespace = true + + values = [ + data.template_file.chart_values_webhook_ovh[0].rendered + ] + + depends_on = [helm_release.cert_manager] +} + + # 2. (MAIN) CLUSTER ISSUER HTTP-01 -# HTTP-01 challenges : https://cert-manager.io/docs/configuration/acme/http01/ +# HTTP-01 challenges : https://cert-manager.io/docs/configuration/acme/http01 data "template_file" "clusterissuer_prod_http01" { count = var.cloud_provider == "kob" ? 0 : 1 @@ -62,11 +92,20 @@ resource "kubectl_manifest" "letsencrypt_prod_http01" { # 2. (BIS) CLUSTER ISSUER DNS-01 -# DNS-01 challenges : https://cert-manager.io/docs/configuration/acme/dns01/2 +# DNS-01 challenges : https://cert-manager.io/docs/configuration/acme/dns01 # # Trick here is to duplicate the dns-challenge secret from terraform-onprem from default namespace to cert-manager namespace # cert-manager requires to have this secret in its namespace. # This is to avoid creating namespace cert-manager in terraform-onprem +# +# Workflow is: +# -> [terraform-onprem] create DNS01 challenge requirements (examples: API keys, Azure App registration etc...) +# -> [terraform-onprem] create a secret in default/dns-challenge-terraform-onprem which contains the needed values to run a DNS01 challenge with the given provider +# -> [terraform-shared] create the cert-manager namespace +# -> [terraform-shared] copy the secret default/dns-challenge-terraform-onprem to cert-manager/default/dns-challenge +# -> [terraform-shared] optionnally install custom webhooks +# -> [terraform-shared] create ClusterIssuer with specifics provider values stored in the cert-manager/default/dns-challenge +# -> [terraform-shared] run cert-manager to get a certificate data "kubernetes_secret" "dns_challenge_terraform_onprem" { metadata { name = "dns-challenge-terraform-onprem" @@ -87,6 +126,7 @@ resource "kubernetes_secret" "dns_challenge" { type = "Opaque" } +# ------ AZURE DNS ------ data "template_file" "clusterissuer_prod_dns01_azuredns" { count = (var.cloud_provider == "kob" && var.dns_challenge_provider == "azure") ? 1 : 0 @@ -102,7 +142,7 @@ data "template_file" "clusterissuer_prod_dns01_azuredns" { } resource "kubectl_manifest" "letsencrypt_prod_dns01_azuredns" { - count = var.cloud_provider == "kob" ? 1 : 0 + count = (var.cloud_provider == "kob" && var.dns_challenge_provider == "azure") ? 1 : 0 yaml_body = data.template_file.clusterissuer_prod_dns01_azuredns[0].rendered @@ -110,6 +150,32 @@ resource "kubectl_manifest" "letsencrypt_prod_dns01_azuredns" { helm_release.cert_manager ] } +# ------ AZURE DNS ------ + +# ------ WEBHOOK OVH ------ +data "template_file" "clusterissuer_prod_dns01_webhook_ovh" { + count = (var.cloud_provider == "kob" && var.dns_challenge_provider == "ovh") ? 1 : 0 + + template = file("${path.module}/kube_objects/clusterissuer.dns01.webhook.ovh.yaml") + vars = { + certificate_email = var.certificate_email + group_name = kubernetes_secret.dns_challenge[0].data["groupName"] + application_key = kubernetes_secret.dns_challenge[0].data["applicationKey"] + application_secret = kubernetes_secret.dns_challenge[0].data["applicationSecret"] + consumer_key = kubernetes_secret.dns_challenge[0].data["consumerKey"] + } +} + +resource "kubectl_manifest" "letsencrypt_prod_dns01_webhook_ovh" { + count = (var.cloud_provider == "kob" && var.dns_challenge_provider == "ovh") ? 1 : 0 + + yaml_body = data.template_file.clusterissuer_prod_dns01_webhook_ovh[0].rendered + + depends_on = [ + helm_release.cert_manager + ] +} +# ------ WEBHOOK OVH ------ # 3. CERTIFICATE @@ -120,22 +186,29 @@ data "template_file" "certificate" { } } +# depends on HTTP01 resource "kubectl_manifest" "certificate" { count = var.cloud_provider == "kob" ? 0 : 1 yaml_body = data.template_file.certificate.rendered - depends_on = [ - kubectl_manifest.letsencrypt_prod_http01[0] - ] + depends_on = [kubectl_manifest.letsencrypt_prod_http01[0]] } +# depends on DNS01 AzureDNS resource "kubectl_manifest" "certificate_dns01_azuredns" { - count = var.cloud_provider == "kob" ? 1 : 0 + count = (var.cloud_provider == "kob" && var.dns_challenge_provider == "azure") ? 1 : 0 yaml_body = data.template_file.certificate.rendered - depends_on = [ - kubectl_manifest.letsencrypt_prod_dns01_azuredns[0] - ] + depends_on = [kubectl_manifest.letsencrypt_prod_dns01_azuredns[0]] +} + +# depends on DNS01 Webhook OVH +resource "kubectl_manifest" "certificate_dns01_webhook_ovh" { + count = (var.cloud_provider == "kob" && var.dns_challenge_provider == "ovh") ? 1 : 0 + + yaml_body = data.template_file.certificate.rendered + + depends_on = [kubectl_manifest.letsencrypt_prod_dns01_webhook_ovh[0]] } diff --git a/modules/chart_cert_manager/values.yaml b/modules/chart_cert_manager/values-cert_manager.yaml similarity index 100% rename from modules/chart_cert_manager/values.yaml rename to modules/chart_cert_manager/values-cert_manager.yaml diff --git a/modules/chart_cert_manager/values-cert_manager_webhook_ovh.yaml b/modules/chart_cert_manager/values-cert_manager_webhook_ovh.yaml new file mode 100644 index 0000000..f00eca8 --- /dev/null +++ b/modules/chart_cert_manager/values-cert_manager_webhook_ovh.yaml @@ -0,0 +1,32 @@ +# https://github.com/aureq/cert-manager-webhook-ovh/blob/main/charts/cert-manager-webhook-ovh/values.yaml +groupName: ${group_name} +certManager: + namespace: cert-manager + serviceAccountName: cert-manager +issuers: + - name: letsencrypt-prod + create: false + kind: ClusterIssuer + acmeServerUrl: https://acme-v02.api.letsencrypt.org/directory + email: ${certificate_email} + ovhEndpointName: ovh-eu + ovhAuthenticationMethod: application + ovhAuthenticationRef: + applicationKeyRef: + name: dns-challenge + key: applicationKey + applicationSecretRef: + name: dns-challenge + key: applicationSecret + +# podLabels: +# networking/traffic-allowed: "yes" +# nodeSelector: +# cosmotech.com/tier: services +# resources: +# requests: +# cpu: 100m +# memory: 128Mi +# limits: +# cpu: 500m +# memory: 512Mi \ No newline at end of file diff --git a/terraform.tfvars b/terraform.tfvars index 794ab87..8588a28 100644 --- a/terraform.tfvars +++ b/terraform.tfvars @@ -16,12 +16,13 @@ # ## VARIABLES EXAMPLE FOR KOB (= On-Premise) -# cloud_provider = "kob" -# cluster_region = "" -# cluster_name = "kob-dev-devops" -# domain_zone = "onpremise.platform.cosmotech.com" +# cloud_provider = "kob" +# cluster_region = "" +# cluster_name = "kob-dev-devops" +# domain_zone = "onpremise.platform.cosmotech.com" +# state_host = "https://cosmotechstates.onpremise.platform.cosmotech.com" +# # DNS01 challenge provider can be "azure", "ovh" # dns_challenge_provider = "azure" -# state_host = "https://cosmotechstates.onpremise.platform.cosmotech.com" ## COMMON VARIABLES EXAMPLE