GithubHelp home page GithubHelp logo

terraform-kubernetes-cert-manager's Introduction

Terraform module for Kubernetes Cert Manager

Terraform module used to create Cert Manager in Kubernetes, with auto http validation issuer. With simple syntax.

Usage

You should to add into your terraform, kubectl & helm provider configuration:

provider "kubectl" {
  # Same config as in kubernetes provider
}
provider "helm" {
  kubernetes {
    # Same config as in kubernetes provider
  }
}
provider "kubernetes" {
  # configuration
}
terraform {
  required_providers {
    kubectl = {
      source  = "alekc/kubectl"
      version = ">= 2.0.2"
    }
    helm = {
      source  = "hashicorp/helm"
      version = "2.5.0"
    }
    kubernetes = {
      source  = "hashicorp/kubernetes"
      version = "2.0.1"
    }
  }
}

To activate TLS auto generation, please add this annotation to ingress:

cert-manager.io/cluster-issuer = module.cert_manager.cluster_issuer_name

Terraform example

module "cert_manager" {
  source        = "terraform-iaac/cert-manager/kubernetes"

  cluster_issuer_email                   = "[email protected]"
  cluster_issuer_name                    = "cert-manager-global"
  cluster_issuer_private_key_secret_name = "cert-manager-private-key"
}

Inputs

Name Description Type Default - Required
namespace_name Name of created namespace string cert-manager no
chart_version HELM Chart Version for cert-manager ( It is not recommended to change ) string 1.11.0 no
create_namespace Create namespace or use exist bool true no
cluster_issuer_server The ACME server URL string https://acme-v02.api.letsencrypt.org/directory no
cluster_issuer_preferred_chain Preferred chain for ClusterIssuer string ISRG Root X1 no
cluster_issuer_email Email address used for ACME registration string n/a yes
cluster_issuer_private_key_secret_name Name of a secret used to store the ACME account private key string cert-manager-private-key no
cluster_issuer_name Cluster Issuer Name, used for annotations string cert-manager no
cluster_issuer_create Create Cluster Issuer? Note: you should create your own issuer if value false bool true no
cluster_issuer_yaml Create Cluster Issuer with your yaml. NOTE: some variables stop to work in case when you using this parameter string null no
additional_set Additional sets to Helm
list(object({
name = string
value = string
type = string // Optional
}))
[] no
solvers Alternate way of providing just the solvers section of the cluster issuer list[object(any)]
- http01:
ingress:
class: nginx
no
certificates List of certificates any refer to "Certificates" no

Solvers

An example of a complex solver that uses different methods http01 and DNS01 as well as selectors for different domains would be

solvers = [
  {
    dns01 = {
      route53 = {
        region  = "us-east-1"
        ambient = "true"
      }
    },
    selector = {
      dnsZones = [
        "internal.example.com"
      ]
    }
  },
  {
    dns01 = {
      cloudflare = {
        email = "[email protected]"
        apiKeySecretRef = {
          name = "cloudflare-api-key-secret"
          key  = "API"
        }
      },
    },
    selector = {
      dnsZones = [
        "public.example.com"
      ]
    }
  },
  {
    http01 = {
      ingress = {
        class = "nginx"
      }
    }
  }
]

Certificates

module "cert_manager" {
  ...
  certificates = {
    "my_certificate" = {
      dns_names = ["my.example.com"]
    }
  }
}
Name Description Type Default Required
namespace certificate resource namespace string uses var.namespace_name of this module no
secret_name certificate secret name. Note: for AKS/AGIC ensure cert and secret have the same name string ${Certificate Name}-tls no
secret_annotations certificate secret annotations map(string) {} no
secret_labels certificate secret labels map(string) {} no
duration certificate validity period map(string) "2160h" no
renew_before It will reissue the certificate before this date from the due date string "360h" no
organizations Organization of issuing certificate list(string) [] no
is_ca Whether the certificate is a CA or not bool false no
private_key_algorithm It will generate a private key with this algorithm string "RSA" no
private_key_encoding It will generate a private key with this encoding string "PKCS1" no
private_key_size It will generate a private key of this lengh number 2048 no
usages certificate usages list(string) ["server auth", "client auth"] no
dns_names Domain names for which the certificate is intended list(string) n/a yes
uris certificate URIs list(string) [] no
ip_addresses certificate ip address list(string) [] no
issuer_name issuer name. string Default is the name of the ClusterIssuer created by this module no
issuer_kind issuer kind string "ClusterIssuer" no
issuer_group issuer group string "" no

Outputs

Name Description
namespace Namespace used by cert manager
cluster_issuer_name Created cluster issuer
cluster_issuer_server ACME Server used by Cluster Issuer
cluster_issuer_private_key_name Name of secrets, where cert manager stores private key
certificates[*].map Certificate settings applied to k8s
certificates[*].secret_name Secret name of the certificate

Terraform Requirements

Name Version
terraform >= 1.0.0
kubernetes >= 2.0.1
helm >= 2.5.0
alekc/kubectl >= 2.0.2

Cert Manager Version: v1.11.0

Source: https://github.com/jetstack/cert-manager

Tutorials: https://cert-manager.io/docs/

terraform-kubernetes-cert-manager's People

Contributors

ajostergaard avatar asafo avatar bohdantverdyi avatar greyscaled avatar megumish avatar timothyclarke avatar tobimichael96 avatar vadimdidenko avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

terraform-kubernetes-cert-manager's Issues

Cert manager unable to update certs

We are using the Kubernetes cert manager, version 2.4.2, along with Let's Encrypt.

Our cert expires in the next few days, and cert-manager is unable to update.

These logs are from the cert-manager-webhook pod.

I am seeing this vague error but I am not sure where to go next for further debugging.

2023-03-15T04:43:55-04:00 I0315 08:43:55.000294       1 dynamic_source.go:169] cert-manager/webhook "msg"="Serving certificate requires renewal, regenerating"  
2023-03-15T04:43:55-04:00 I0315 08:43:55.035562       1 dynamic_source.go:267] cert-manager/webhook "msg"="Updated serving TLS certificate"  
2023-03-15T20:43:54-04:00 I0316 00:43:54.473908       1 authority.go:312] cert-manager/webhook "msg"="Root CA certificate is nearing expiry. Regenerating..."  
2023-03-15T20:43:54-04:00 I0316 00:43:54.519234       1 dynamic_source.go:160] cert-manager/webhook "msg"="Detected root CA rotation - regenerating serving certificates"  
2023-03-15T20:43:54-04:00 I0316 00:43:54.551889       1 dynamic_source.go:267] cert-manager/webhook "msg"="Updated serving TLS certificate"  
2023-03-16T06:43:57-04:00 W0316 10:43:57.028777       1 reflector.go:442] external/io_k8s_client_go/tools/cache/reflector.go:167: watch of *v1.Secret ended with: an error on the server ("unable to decode an event from the watch stream: http2: client connection lost") has prevented the request from succeeding
2023-03-20T12:43:54-04:00 I0320 16:43:54.001357       1 dynamic_source.go:169] cert-manager/webhook "msg"="Serving certificate requires renewal, regenerating"  
2023-03-20T12:43:54-04:00 I0320 16:43:54.035635       1 dynamic_source.go:267] cert-manager/webhook "msg"="Updated serving TLS certificate"

Wrong url has been occurred while running terraform apply.


│ Error: failed to create kubernetes rest client for read of resource: Get "https://localhost/api?timeout=32s": x509: certificate is valid for *.dev.tappy.stage-codal.net, dev.tappy.stage-codal.net, not localhost

│ with module.cert_manager.kubectl_manifest.cluster_issuer[0],
│ on .terraform/modules/cert_manager/main.tf line 42, in resource "kubectl_manifest" "cluster_issuer":
│ 42: resource "kubectl_manifest" "cluster_issuer" {

Working fine in local machine where kubectl, helm, kubectl config and providers are configured.

Not working in jenkins server where only kubectl command is installed.

Unable to pass startupapicheck.podLabels within additional_set

additional_set = [
    {
      name = "global.leaderElection.namespace"
      value = module.cert_manager.namespace
    },
    {
      name = "startupapicheck.podLabels.sidecar\\.istio\\.io/inject"
      value = false
    }
  ]

Retruned error is:

Error: failed post-install: warning: Hook post-install cert-manager/templates/startupapicheck-job.yaml failed: Job in version "v1" cannot be handled as a Job: json: cannot unmarshal bool into Go struct field ObjectMeta.spec.template.metadata.labels of type string

I've tried multiple different escape sequences, none of them have worked.

I suppose it is related with escaping. And is related with following issue hashicorp/terraform-provider-helm#64

Any advice how to proceed is welcome.

No custom-fields can be add to the certificate

I have a use case when using venafi as issuer.

My venafi is set to enforce some mandatory custom fields on each new certificate. When applying using yaml file, custom fields can be set inside metadata like this

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: cert-manager-xxxx
namespace: xxxx
annotations:
venafi.cert-manager.io/custom-fields: |-
[
]

Can we add this "custom field" feature in the module? Or can we add a way to specify a yaml file directly for certificate just like what we are doing for cluster issuer?

Thanks!

Feature request: add dns01 into template

was wondering if template could be upgrades to support dns1 configs such as

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
  namespace: cert-manager
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email:  __cloudflareemail__
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
    - selector:
        dnsNames:
        - '*.vinsonjewellers.com'
        - vinsonjewellers.com
      dns01:
        cloudflare:
          email: __cloudflareemail__
          apiKeySecretRef:
            name: cloudflare-api-key-secret
            key: API

Installation error trying to acess namespaces endpoint

I'm getting this error after trying to set it up

│ Error: Post "http://localhost/api/v1/namespaces": dial tcp [::1]:80: connect: connection refused

│ with module.cert_manager.kubernetes_namespace.cert_manager[0],
│ on .terraform/modules/cert_manager/main.tf line 1, in resource "kubernetes_namespace" "cert_manager":
│ 1: resource "kubernetes_namespace" "cert_manager" {

my tf files look like

module "cert_manager" {
  source = "terraform-iaac/cert-manager/kubernetes"

  cluster_issuer_email = "[email protected]"

	certificates = {
		"example-cert" = {
			dns_names = ["example.com", "*.example.com"]
		}
	}
}

resource "helm_release" "ingress-nginx" {
  name             = "ingress-nginx"

  repository       = "https://kubernetes.github.io/ingress-nginx"
  chart            = "ingress-nginx"

  create_namespace = true
  namespace       = "gitlab-managed-apps"


  set {
    name  = "controller.annotations.cert-manager\\.io/cluster-issuer"
    value = module.cert_manager.cluster_issuer_name
  }
}

Am I missing anything?

New typing doesn't support different solvers

The typing introduced in #25, broke the solvers configuration we have (that's working in 2.6.0)

The given value is not suitable for module.cert_manager.var.solvers declared at .terraform/modules/cert_manager/variables.tf:58,1-19: all list elements must have the same type.

Our configured solvers:

  solvers = [
    {
      dns01 = {
        cloudflare = {
          apiTokenSecretRef = {
            name = "cloudflare-api-key-secret"
            key  = "DNS_KEY"
          }
        },
      },
      selector = {
        matchLabels = {
          "use-dns01" = "cloudflare"
        }
      }
    },
    {
      http01 = {
        ingress = {
          class = "nginx"
        }
      }
    }
  ]

Timeout while creating cluster issuer

Hi I am getting timeout error while implementing this module error is attached below.


│ Error: letsencrypt-prod failed to create kubernetes rest client for update of resource: Get "https://xxxxxx.gr7.us-east-1.eks.amazonaws.com/api?timeout=32s": dial tcp: lookup xxxxxxxxxxx.gr7.us-east-1.eks.amazonaws.com on 8.8.8.8:53: no such host

│ with module.cert-manager.kubectl_manifest.cluster_issuer[0],
│ on .terraform/modules/cert-manager/main.tf line 42, in resource "kubectl_manifest" "cluster_issuer":
│ 42: resource "kubectl_manifest" "cluster_issuer" {

as this is my first time implementing this a little help on how to resolve this would be appreciated.

Thanks.

invalid configuration: no configuration has been provided

Hi,

I'm trying to use the module on an existing cluster. I already have other kubernetes resources being created but I can't get this one to run.

Here's the config:

module "cert_manager" {
  source        = "terraform-iaac/cert-manager/kubernetes"
  cluster_issuer_email                   = "[email protected]"
}

Here's the error message:

 Error: Kubernetes cluster unreachable: invalid configuration: no configuration has been provided, try setting KUBERNETES_MASTER environment variable
│ 
│   with module.civo-cluster.module.cert_manager.helm_release.cert_manager,
│   on .terraform/modules/civo-cluster.cert_manager/main.tf line 10, in resource "helm_release" "cert_manager":10: resource "helm_release" "cert_manager" {

"no matches for kind "ClusterIssuer" in group "cert-manager.io"" With terraform plan

Hi, I am getting the following error when creating the helm_release for the cert-manager with the ClusterIssuer in the same terraform apply because the plan fails.

I did a bit of Googling around and it seems that it's because in the plan state, the CRDs are not yet installed so the error happens.

Is this a known issue and is there a way to circumvent it?

│ Error: Failed to determine GroupVersionResource for manifest
│ 
│   with module.k8s_base.kubernetes_manifest.cluster_issuer,
│   on ../../modules/k8s_base/main.tf line 35, in resource "kubernetes_manifest" "cluster_issuer":35: resource "kubernetes_manifest" "cluster_issuer" {
│ 
│ no matches for kind "ClusterIssuer" in group "cert-manager.io"

setting KUBERNETES_MASTER environment variable

This is what I used:

module "cert_manager" {
  source        = "terraform-iaac/cert-manager/kubernetes"

  cluster_issuer_email                   = "[email protected]"
  cluster_issuer_name                    = "cert-manager-global"
  cluster_issuer_private_key_secret_name = "cert-manager-private-key"
}

This is what I got:

╷
│ Error: Kubernetes cluster unreachable: invalid configuration: no configuration has been provided, try setting KUBERNETES_MASTER environment variable
│ 
│   with module.cert_manager.helm_release.cert_manager,
│   on .terraform/modules/cert_manager/main.tf line 12, in resource "helm_release" "cert_manager":
│   12: resource "helm_release" "cert_manager" {
│ 

Did I miss a step?

Example to use additional_set

hello,

I'm trying to add multiple sets, but I don't understand how it would look in HCL, it always gives me an error.

Thanks in advance.

failed to download chart

Hey there,

Using the module leads to this error:

module.cert_manager.helm_release.cert_manager: Creating...
╷
│ Error: failed to download "https://charts.jetstack.io/charts/cert-manager-v1.6.1.tgz" at version "1.6.1"
│ 
│   with module.cert_manager.helm_release.cert_manager,
│   on .terraform/modules/cert_manager/main.tf line 12, in resource "helm_release" "cert_manager":
│   12: resource "helm_release" "cert_manager" {

change variable chart_version from 1.6.1 to v1.6.1 in .terraform/modules/cert_manager/variables.tf seems to do the job

what could i have done?

EKS 1.20, terraform 1.0.1, kubectl 1.21

  required_providers {
    aws = {
      source = "hashicorp/aws"
    }
    kubernetes = {
      source  = "hashicorp/kubernetes"
      version = "2.6.1"
    }
    kubectl = {
      source  = "gavinbunney/kubectl"
      version = "1.13.1"
    }
  }
  required_version = ">= 1.0.1"

Thanks!

Edit: my bad, doesn't work either with v1.6.1

why use helm?

Hi,

I wonder if you plan to rework this module to use kubectl provider directly without helm?

I guess this should be the main point of creating a terraform module for this to have a better / fine granularity control over certman resources and avoid helm overhead.

In fact terraform does what helm does only a bit better.

cannot init terraform with an ARM64

Hey folks !
I have this issue with this module and a M1 MacOS when initializing terraform

Error: Incompatible provider version
 
Provider registry.terraform.io/hashicorp/template v2.2.0 does not have a package available for your current platform, darwin_arm64.
 
Provider releases are separate from Terraform CLI releases, so not all providers are available for all platforms.
Other versions of this provider may have different platforms supported.

Regarding Hashicorp's documentation, this is related to "template_file" that is deprecated, follow this link

Have you ever seen this and already consider a solution?

Thanks!

Error: cert-manager failed to create kubernetes rest client for update of resource: resource [cert-manager.io/v1/ClusterIssuer] isn't valid for cluster, check the APIVersion and Kind fields are valid

Hi there,

I have an eks-cluster deployed and upon applying this module. I receive this error:

│ Error: cert-manager failed to create kubernetes rest client for update of resource: resource [cert-manager.io/v1/ClusterIssuer] isn't valid for cluster, check the APIVersion and Kind fields are valid

│ with module.cert_manager.kubectl_manifest.cluster_issuer[0],
│ on .terraform/modules/cert_manager/main.tf line 42, in resource "kubectl_manifest" "cluster_issuer":
│ 42: resource "kubectl_manifest" "cluster_issuer" {

To solve the issue, I can deactivate the issuer creation cluster_issuer_create = false and apply a ClusterIssuer in a second step (due to dependency constraints, like discussed here).

Any chance that I can get this module working as planned?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.