Skip to content

Commit

Permalink
Add issuing certificate feature (#8)
Browse files Browse the repository at this point in the history
* Add certificate feature.

* add description about Certificates feature

* Fixed: name space cannot be specified.

* Fixed: Missing Type in Certificate

* change to use var.namespace as the default
  • Loading branch information
megumish authored Jan 28, 2022
1 parent 980e9b5 commit 30948f3
Show file tree
Hide file tree
Showing 7 changed files with 262 additions and 1 deletion.
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ module "cert_manager" {
| 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 | <pre>list(object({<br> name = string<br> value = string<br> type = string // Optional<br> }))</pre> | `[]` | no |
| solvers | Alternate way of providing just the solvers section of the cluster issuer | `list[object(any)]` | <pre>- http01:<br> ingress:<br> class: nginx</pre>| no |
| certificates | List of certificates | `any` | refer to ["Certificates"](#certificates) |

### Solvers
An example of a complex solver that uses different methods `http01` and `DNS01` as well as selectors for different domains would be
Expand Down Expand Up @@ -103,13 +104,52 @@ solvers = [
]
```


### Certificates

```hcl
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 | 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 | ["server auth", "client auth"] | list(string) | 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

Expand Down
36 changes: 36 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,39 @@ resource "kubectl_manifest" "cluster_issuer" {

depends_on = [kubernetes_namespace.cert_manager, helm_release.cert_manager, time_sleep.wait]
}

module "certificates" {
for_each = { for k, v in var.certificates : k => v }
source = "./modules/_certificate"

name = each.key
namespace = try(each.value.namespace, var.namespace_name)
secret_name = try(each.value.secret_name, "${each.key}-tls")
secret_annotations = try(each.value.secret_annotations, {})
secret_labels = try(each.value.secret_labels, {})
duration = try(each.value.duration, "2160h")
renew_before = try(each.value.renew_before, "360h")
organizations = try(each.value.organizations, [])
is_ca = try(each.value.is_ca, false)
private_key_algorithm = try(each.value.private_key_algorithm, "RSA")
private_key_encoding = try(each.value.private_key_encoding, "PKCS1")
private_key_size = try(each.value.private_key_size, 2048)
usages = try(each.value.usages, ["server auth", "client auth", ])
dns_names = each.value.dns_names
uris = try(each.value.uris, [])
ip_addresses = try(each.value.ip_addresses, [])
issuer_name = try(each.value.issuer_name, var.cluster_issuer_name)
issuer_kind = try(each.value.issuer_kind, "ClusterIssuer")
issuer_group = try(each.value.issuer_group, "")
}


resource "kubectl_manifest" "certificates" {
for_each = { for k, cc in module.certificates : k => cc }

validate_schema = false

yaml_body = yamlencode(each.value.map)

depends_on = [kubectl_manifest.cluster_issuer]
}
24 changes: 24 additions & 0 deletions modules/_certificate/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
locals {
name = var.name
namespace = var.namespace
secret_name = var.secret_name
secret_annotations = var.secret_annotations
secret_labels = var.secret_labels
duration = var.duration
renew_before = var.renew_before
organizations = var.organizations
# The use of the common name field has been deprecated sicne 2000 and is
# discouraged from being used
# common_name = var.common_name
is_ca = var.is_ca
private_key_algorithm = var.private_key_algorithm
private_key_encoding = var.private_key_encoding
private_key_size = var.private_key_size
usages = var.usages
dns_names = var.dns_names
uris = var.uris
ip_addresses = var.ip_addresses
issuer_name = var.issuer_name
issuer_kind = var.issuer_kind
issuer_group = var.issuer_group
}
43 changes: 43 additions & 0 deletions modules/_certificate/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
output "map" {
value = {
apiVersion = "cert-manager.io/v1"
kind = "Certificate"
metadata = {
name = var.name
namespace = var.namespace
}
spec = {
secretName = var.secret_name

secretTemplate = {
annotations = var.secret_annotations
labels = var.secret_labels
}

duration = var.duration
renewBefore = var.renew_before
subject = {
organizations = var.organizations
}
isCA = var.is_ca
private_key = {
algorithm = var.private_key_algorithm
encoding = var.private_key_encoding
size = var.private_key_size
}
usages = var.usages
dnsNames = var.dns_names
uris = var.uris
ipAddresses = var.ip_addresses
issuerRef = {
name = var.issuer_name
kind = var.issuer_kind
group = var.issuer_group
}
}
}
}

output "secret_name" {
value = var.secret_name
}
108 changes: 108 additions & 0 deletions modules/_certificate/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
variable "name" {
type = string
description = "certificate resource name"
}

variable "namespace" {
type = string
description = "certificate resource namespace"
default = "cert-manager"
}

variable "secret_name" {
type = string
description = "certificate secret name"
}

variable "secret_annotations" {
type = map(string)
description = "certificate secret annotations"
default = {}
}

variable "secret_labels" {
type = map(string)
description = "certificate secret labels"
default = {}
}

variable "duration" {
type = string
description = "certificate duration"
default = "2160h" # 90d
}

variable "renew_before" {
type = string
description = "certificate renew before"
default = "360h" # 15d
}

variable "organizations" {
type = list(string)
description = "certificate organizations"
default = []
}

variable "is_ca" {
type = bool
description = "is CA certificate"
default = false
}

variable "private_key_algorithm" {
type = string
description = "certificate private key algorithm"
default = "RSA"
}

variable "private_key_encoding" {
type = string
description = "certificate private key encoding"
default = "PKCS1"
}

variable "private_key_size" {
type = number
description = "certificate private key size"
default = 2048
}

variable "usages" {
type = list(string)
description = "certificate usages"
default = ["server auth", "client auth"]
}

variable "dns_names" {
type = list(string)
description = "certificate dns names"
}

variable "uris" {
type = list(string)
description = "certificate uris"
default = []
}

variable "ip_addresses" {
type = list(string)
description = "certificate ip addresses"
default = []
}

variable "issuer_name" {
type = string
description = "issuer name"
}

variable "issuer_kind" {
type = string
description = "issuer name"
}

variable "issuer_group" {
type = string
description = "issuer group"
default = ""
}
6 changes: 5 additions & 1 deletion outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,8 @@ output "cluster_issuer_server" {
}
output "cluster_issuer_private_key_name" {
value = var.cluster_issuer_private_key_secret_name
}
}

output "certificates" {
value = module.certificates
}
6 changes: 6 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,9 @@ variable "solvers" {
}
}]
}

variable "certificates" {
description = "List of Certificates"
type = any
default = {}
}

0 comments on commit 30948f3

Please sign in to comment.