Skip to content

Commit f843099

Browse files
Support installing cert-manager and using a ClusterIssuer for TLS
1 parent ffa11d8 commit f843099

File tree

9 files changed

+249
-166
lines changed

9 files changed

+249
-166
lines changed

docs/footer.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,20 @@ By default, Network Load Balancers are created for each Materialize instance, wi
1717

1818
The DNS name and ARN for the NLBs will be in the `terraform output` as `nlb_details`.
1919

20+
#### TLS support
21+
22+
For example purposes, optional TLS support is provided by using `cert-manager` and a self-signed `ClusterIssuer`.
23+
24+
More advanced TLS support using user-provided CAs or per-Materialize `Issuer`s are out of scope of this Terraform module. Please refer to the [cert-manager documentation](https://cert-manager.io/docs/configuration/) for detailed guidance on more advanced usage.
25+
26+
###### To enable installation of `cert-manager` and configuration of the self-signed `ClusterIssuer`
27+
* Set `install_cert_manager` to `true`.
28+
* Run `terraform apply`.
29+
* Set `use_self_signed_cluster_issuer` to `true`.
30+
* Run `terraform apply`.
31+
32+
Due to limitations in Terraform, it cannot plan Kubernetes resources using CRDs that do not exist yet. We need to first install `cert-manager` in the first `terraform apply`, before defining any `ClusterIssuer` or `Certificate` resources which get created in the second `terraform apply`.
33+
2034
## Upgrade Notes
2135

2236
#### v0.3.0

docs/operator-tls-setup.md

Lines changed: 0 additions & 166 deletions
This file was deleted.

examples/simple/main.tf

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ module "materialize_infrastructure" {
7979
enable_monitoring = true
8080
metrics_retention_days = 3
8181

82+
# Certificates
83+
install_cert_manager = var.install_cert_manager
84+
use_self_signed_cluster_issuer = var.use_self_signed_cluster_issuer
85+
8286
# Enable and configure Materialize operator
8387
install_materialize_operator = true
8488
operator_version = var.operator_version
@@ -155,6 +159,18 @@ variable "helm_values" {
155159
default = {}
156160
}
157161

162+
variable "install_cert_manager" {
163+
description = "Whether to install cert-manager."
164+
type = bool
165+
default = false
166+
}
167+
168+
variable "use_self_signed_cluster_issuer" {
169+
description = "Whether to install and use a self-signed ClusterIssuer for TLS. Due to limitations in Terraform, this may not be enabled before the cert-manager CRDs are installed."
170+
type = bool
171+
default = false
172+
}
173+
158174
# Outputs
159175
output "vpc_id" {
160176
description = "VPC ID"

main.tf

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,24 @@ module "database" {
107107
]
108108
}
109109

110+
module "certificates" {
111+
source = "./modules/certificates"
112+
113+
install_cert_manager = var.install_cert_manager
114+
use_self_signed_cluster_issuer = var.use_self_signed_cluster_issuer
115+
cert_manager_namespace = var.cert_manager_namespace
116+
name_prefix = local.name_prefix
117+
118+
depends_on = [
119+
module.eks,
120+
# The AWS LBC installs webhooks, and all other K8S stuff can fail
121+
# if they are deployed, but the AWS LBC pods aren't up yet.
122+
# This doesn't actually need the LBC,
123+
# but we want to avoid concurrently updating these.
124+
module.aws_lbc,
125+
]
126+
}
127+
110128
module "operator" {
111129
source = "github.com/MaterializeInc/terraform-helm-materialize?ref=v0.1.8"
112130

@@ -119,6 +137,12 @@ module "operator" {
119137
module.database,
120138
module.storage,
121139
module.networking,
140+
module.certificates,
141+
# The AWS LBC installs webhooks, and all other K8S stuff can fail
142+
# if they are deployed, but the AWS LBC pods aren't up yet.
143+
# This doesn't actually need the LBC,
144+
# but we want to avoid concurrently updating these.
145+
module.aws_lbc,
122146
]
123147

124148
namespace = var.namespace
@@ -198,6 +222,34 @@ locals {
198222
parameters = local.disk_config.storage_class_parameters
199223
}
200224
} : {}
225+
tls = var.use_self_signed_cluster_issuer ? {
226+
defaultCertificateSpecs = {
227+
balancerdExternal = {
228+
dnsNames = [
229+
"balancerd",
230+
]
231+
issuerRef = {
232+
name = module.certificates.cluster_issuer_name
233+
kind = "ClusterIssuer"
234+
}
235+
}
236+
consoleExternal = {
237+
dnsNames = [
238+
"console",
239+
]
240+
issuerRef = {
241+
name = module.certificates.cluster_issuer_name
242+
kind = "ClusterIssuer"
243+
}
244+
}
245+
internal = {
246+
issuerRef = {
247+
name = module.certificates.cluster_issuer_name
248+
kind = "ClusterIssuer"
249+
}
250+
}
251+
}
252+
} : {}
201253
}
202254

203255
merged_helm_values = merge(local.default_helm_values, var.helm_values)

modules/certificates/main.tf

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
resource "kubernetes_namespace" "cert_manager" {
2+
count = var.install_cert_manager ? 1 : 0
3+
4+
metadata {
5+
name = var.cert_manager_namespace
6+
}
7+
}
8+
9+
resource "helm_release" "cert_manager" {
10+
count = var.install_cert_manager ? 1 : 0
11+
12+
# cert-manager is a singleton resource for the cluster,
13+
# so not using name prefixes here.
14+
name = "cert-manager"
15+
namespace = kubernetes_namespace.cert_manager[0].metadata[0].name
16+
repository = "https://charts.jetstack.io"
17+
chart = "cert-manager"
18+
version = "v1.17.1"
19+
20+
set {
21+
name = "crds.enabled"
22+
value = "true"
23+
}
24+
25+
depends_on = [
26+
kubernetes_namespace.cert_manager,
27+
]
28+
}
29+
30+
resource "kubernetes_manifest" "self_signed_cluster_issuer" {
31+
# only create these after cert manager is installed
32+
count = var.use_self_signed_cluster_issuer ? 1 : 0
33+
34+
manifest = {
35+
"apiVersion" = "cert-manager.io/v1"
36+
"kind" = "ClusterIssuer"
37+
"metadata" = {
38+
"name" = "${var.name_prefix}-self-signed"
39+
}
40+
"spec" = {
41+
"selfSigned" = {}
42+
}
43+
}
44+
45+
depends_on = [
46+
helm_release.cert_manager,
47+
]
48+
}
49+
50+
resource "kubernetes_manifest" "self_signed_root_ca_certificate" {
51+
count = var.use_self_signed_cluster_issuer ? 1 : 0
52+
53+
manifest = {
54+
"apiVersion" = "cert-manager.io/v1"
55+
"kind" = "Certificate"
56+
"metadata" = {
57+
"name" = "${var.name_prefix}-self-signed-ca"
58+
"namespace" = var.cert_manager_namespace
59+
}
60+
"spec" = {
61+
"isCA" = true
62+
"commonName" = "${var.name_prefix}-self-signed-ca"
63+
"secretName" = "${var.name_prefix}-root-ca"
64+
"privateKey" = {
65+
"algorithm" = "RSA"
66+
"encoding" = "PKCS8"
67+
"size" = 4096
68+
"rotationPolicy" = "Always"
69+
}
70+
"issuerRef" = {
71+
"name" = "${var.name_prefix}-self-signed"
72+
"kind" = "ClusterIssuer"
73+
"group" = "cert-manager.io"
74+
}
75+
}
76+
}
77+
78+
depends_on = [
79+
helm_release.cert_manager,
80+
kubernetes_manifest.self_signed_cluster_issuer,
81+
]
82+
}
83+
84+
resource "kubernetes_manifest" "root_ca_cluster_issuer" {
85+
count = var.use_self_signed_cluster_issuer ? 1 : 0
86+
87+
manifest = {
88+
"apiVersion" = "cert-manager.io/v1"
89+
"kind" = "ClusterIssuer"
90+
"metadata" = {
91+
"name" = "${var.name_prefix}-root-ca"
92+
}
93+
"spec" = {
94+
"ca" = {
95+
"secretName" = "${var.name_prefix}-root-ca"
96+
}
97+
}
98+
}
99+
100+
depends_on = [
101+
helm_release.cert_manager,
102+
kubernetes_manifest.self_signed_root_ca_certificate,
103+
]
104+
}

0 commit comments

Comments
 (0)