Skip to content

Commit b9dc125

Browse files
Merge pull request #27 from MaterializeInc/certificates
Certificates
2 parents 98e204d + becc224 commit b9dc125

File tree

9 files changed

+311
-8
lines changed

9 files changed

+311
-8
lines changed

README.md

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,10 @@ No providers.
8585
| Name | Source | Version |
8686
|------|--------|---------|
8787
| <a name="module_aks"></a> [aks](#module\_aks) | ./modules/aks | n/a |
88+
| <a name="module_certificates"></a> [certificates](#module\_certificates) | ./modules/certificates | n/a |
8889
| <a name="module_database"></a> [database](#module\_database) | ./modules/database | n/a |
8990
| <a name="module_networking"></a> [networking](#module\_networking) | ./modules/networking | n/a |
90-
| <a name="module_operator"></a> [operator](#module\_operator) | github.com/MaterializeInc/terraform-helm-materialize | v0.1.8 |
91+
| <a name="module_operator"></a> [operator](#module\_operator) | github.com/MaterializeInc/terraform-helm-materialize | v0.1.9 |
9192
| <a name="module_storage"></a> [storage](#module\_storage) | ./modules/storage | n/a |
9293

9394
## Resources
@@ -99,21 +100,26 @@ No resources.
99100
| Name | Description | Type | Default | Required |
100101
|------|-------------|------|---------|:--------:|
101102
| <a name="input_aks_config"></a> [aks\_config](#input\_aks\_config) | AKS cluster configuration | <pre>object({<br/> vm_size = string<br/> disk_size_gb = number<br/> min_nodes = number<br/> max_nodes = number<br/> })</pre> | <pre>{<br/> "disk_size_gb": 100,<br/> "max_nodes": 5,<br/> "min_nodes": 1,<br/> "vm_size": "Standard_E8ps_v6"<br/>}</pre> | no |
103+
| <a name="input_cert_manager_chart_version"></a> [cert\_manager\_chart\_version](#input\_cert\_manager\_chart\_version) | Version of the cert-manager helm chart to install. | `string` | `"v1.17.1"` | no |
104+
| <a name="input_cert_manager_install_timeout"></a> [cert\_manager\_install\_timeout](#input\_cert\_manager\_install\_timeout) | Timeout for installing the cert-manager helm chart, in seconds. | `number` | `300` | no |
105+
| <a name="input_cert_manager_namespace"></a> [cert\_manager\_namespace](#input\_cert\_manager\_namespace) | The name of the namespace in which cert-manager is or will be installed. | `string` | `"cert-manager"` | no |
102106
| <a name="input_database_config"></a> [database\_config](#input\_database\_config) | Azure Database for PostgreSQL configuration | <pre>object({<br/> sku_name = optional(string, "GP_Standard_D2s_v3")<br/> postgres_version = optional(string, "15")<br/> password = string<br/> username = optional(string, "materialize")<br/> db_name = optional(string, "materialize")<br/> })</pre> | n/a | yes |
103107
| <a name="input_helm_chart"></a> [helm\_chart](#input\_helm\_chart) | Chart name from repository or local path to chart. For local charts, set the path to the chart directory. | `string` | `"materialize-operator"` | no |
104108
| <a name="input_helm_values"></a> [helm\_values](#input\_helm\_values) | Additional Helm values to merge with defaults | `any` | `{}` | no |
109+
| <a name="input_install_cert_manager"></a> [install\_cert\_manager](#input\_install\_cert\_manager) | Whether to install cert-manager. | `bool` | `false` | no |
105110
| <a name="input_install_materialize_operator"></a> [install\_materialize\_operator](#input\_install\_materialize\_operator) | Whether to install the Materialize operator | `bool` | `true` | no |
106111
| <a name="input_location"></a> [location](#input\_location) | The location where resources will be created | `string` | `"eastus2"` | no |
107112
| <a name="input_materialize_instances"></a> [materialize\_instances](#input\_materialize\_instances) | Configuration for Materialize instances | <pre>list(object({<br/> name = string<br/> namespace = optional(string)<br/> database_name = string<br/> environmentd_version = optional(string, "v0.130.4")<br/> cpu_request = optional(string, "1")<br/> memory_request = optional(string, "1Gi")<br/> memory_limit = optional(string, "1Gi")<br/> create_database = optional(bool, true)<br/> in_place_rollout = optional(bool, false)<br/> request_rollout = optional(string)<br/> force_rollout = optional(string)<br/> balancer_memory_request = optional(string, "256Mi")<br/> balancer_memory_limit = optional(string, "256Mi")<br/> balancer_cpu_request = optional(string, "100m")<br/> }))</pre> | `[]` | no |
108113
| <a name="input_namespace"></a> [namespace](#input\_namespace) | Namespace for all resources, usually the organization or project name | `string` | `"materialize"` | no |
109114
| <a name="input_network_config"></a> [network\_config](#input\_network\_config) | Network configuration for the AKS cluster | <pre>object({<br/> vnet_address_space = string<br/> subnet_cidr = string<br/> postgres_subnet_cidr = string<br/> service_cidr = string<br/> docker_bridge_cidr = string<br/> })</pre> | n/a | yes |
110115
| <a name="input_operator_namespace"></a> [operator\_namespace](#input\_operator\_namespace) | Namespace for the Materialize operator | `string` | `"materialize"` | no |
111116
| <a name="input_operator_version"></a> [operator\_version](#input\_operator\_version) | Version of the Materialize operator to install | `string` | `null` | no |
112-
| <a name="input_orchestratord_version"></a> [orchestratord\_version](#input\_orchestratord\_version) | Version of the Materialize orchestrator to install | `string` | `"v0.130.4"` | no |
117+
| <a name="input_orchestratord_version"></a> [orchestratord\_version](#input\_orchestratord\_version) | Version of the Materialize orchestrator to install | `string` | `null` | no |
113118
| <a name="input_prefix"></a> [prefix](#input\_prefix) | Prefix to be used for resource names | `string` | `"materialize"` | no |
114119
| <a name="input_resource_group_name"></a> [resource\_group\_name](#input\_resource\_group\_name) | The name of the resource group | `string` | n/a | yes |
115120
| <a name="input_tags"></a> [tags](#input\_tags) | Tags to apply to all resources | `map(string)` | `{}` | no |
116121
| <a name="input_use_local_chart"></a> [use\_local\_chart](#input\_use\_local\_chart) | Whether to use a local chart instead of one from a repository | `bool` | `false` | no |
122+
| <a name="input_use_self_signed_cluster_issuer"></a> [use\_self\_signed\_cluster\_issuer](#input\_use\_self\_signed\_cluster\_issuer) | 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. | `bool` | `false` | no |
117123

118124
## Outputs
119125

@@ -138,4 +144,26 @@ az aks get-credentials --resource-group $(terraform output -raw resource_group_n
138144
```
139145

140146
This command retrieves the AKS cluster credentials and merges them into the `~/.kube/config` file. You can now interact with the AKS cluster using `kubectl`.
147+
148+
## Connecting to Materialize instances
149+
150+
Access to the database is through the balancerd pods on:
151+
* Port 6875 for SQL connections.
152+
* Port 6876 for HTTP(S) connections.
153+
154+
Access to the web console is through the console pods on port 8080.
155+
156+
#### TLS support
157+
158+
For example purposes, optional TLS support is provided by using `cert-manager` and a self-signed `ClusterIssuer`.
159+
160+
More advanced TLS support using user-provided CAs or per-Materialize `Issuer`s are out of scope for this Terraform module. Please refer to the [cert-manager documentation](https://cert-manager.io/docs/configuration/) for detailed guidance on more advanced usage.
161+
162+
###### To enable installation of `cert-manager` and configuration of the self-signed `ClusterIssuer`
163+
1. Set `install_cert_manager` to `true`.
164+
1. Run `terraform apply`.
165+
1. Set `use_self_signed_cluster_issuer` to `true`.
166+
1. Run `terraform apply`.
167+
168+
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`.
141169
<!-- END_TF_DOCS -->

docs/footer.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,25 @@ az aks get-credentials --resource-group $(terraform output -raw resource_group_n
77
```
88

99
This command retrieves the AKS cluster credentials and merges them into the `~/.kube/config` file. You can now interact with the AKS cluster using `kubectl`.
10+
11+
## Connecting to Materialize instances
12+
13+
Access to the database is through the balancerd pods on:
14+
* Port 6875 for SQL connections.
15+
* Port 6876 for HTTP(S) connections.
16+
17+
Access to the web console is through the console pods on port 8080.
18+
19+
#### TLS support
20+
21+
For example purposes, optional TLS support is provided by using `cert-manager` and a self-signed `ClusterIssuer`.
22+
23+
More advanced TLS support using user-provided CAs or per-Materialize `Issuer`s are out of scope for this Terraform module. Please refer to the [cert-manager documentation](https://cert-manager.io/docs/configuration/) for detailed guidance on more advanced usage.
24+
25+
###### To enable installation of `cert-manager` and configuration of the self-signed `ClusterIssuer`
26+
1. Set `install_cert_manager` to `true`.
27+
1. Run `terraform apply`.
28+
1. Set `use_self_signed_cluster_issuer` to `true`.
29+
1. Run `terraform apply`.
30+
31+
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`.

examples/simple/main.tf

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ module "materialize" {
8181
operator_version = var.operator_version
8282
orchestratord_version = var.orchestratord_version
8383

84+
install_cert_manager = var.install_cert_manager
85+
use_self_signed_cluster_issuer = var.use_self_signed_cluster_issuer
86+
8487
materialize_instances = var.materialize_instances
8588

8689
database_config = {
@@ -130,7 +133,7 @@ variable "operator_version" {
130133
variable "orchestratord_version" {
131134
description = "Version of the Materialize orchestrator to install"
132135
type = string
133-
default = "v0.130.4"
136+
default = null
134137
}
135138

136139
variable "tags" {
@@ -162,6 +165,18 @@ variable "materialize_instances" {
162165
default = []
163166
}
164167

168+
variable "install_cert_manager" {
169+
description = "Whether to install cert-manager."
170+
type = bool
171+
default = false
172+
}
173+
174+
variable "use_self_signed_cluster_issuer" {
175+
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."
176+
type = bool
177+
default = false
178+
}
179+
165180
# Output the Materialize instance details
166181
output "aks_cluster" {
167182
description = "AKS cluster details"

main.tf

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,27 @@ module "storage" {
7272
tags = local.common_labels
7373
}
7474

75+
module "certificates" {
76+
source = "./modules/certificates"
77+
78+
install_cert_manager = var.install_cert_manager
79+
cert_manager_install_timeout = var.cert_manager_install_timeout
80+
cert_manager_chart_version = var.cert_manager_chart_version
81+
use_self_signed_cluster_issuer = var.use_self_signed_cluster_issuer
82+
cert_manager_namespace = var.cert_manager_namespace
83+
name_prefix = var.prefix
84+
85+
depends_on = [
86+
module.aks,
87+
]
88+
}
89+
7590
locals {
7691
default_helm_values = {
7792
operator = {
78-
image = {
93+
image = var.orchestratord_version == null ? {} : {
7994
tag = var.orchestratord_version
80-
}
95+
},
8196
cloudProvider = {
8297
type = "azure"
8398
region = var.location
@@ -88,6 +103,34 @@ locals {
88103
enabled = true
89104
}
90105
}
106+
tls = var.use_self_signed_cluster_issuer ? {
107+
defaultCertificateSpecs = {
108+
balancerdExternal = {
109+
dnsNames = [
110+
"balancerd",
111+
]
112+
issuerRef = {
113+
name = module.certificates.cluster_issuer_name
114+
kind = "ClusterIssuer"
115+
}
116+
}
117+
consoleExternal = {
118+
dnsNames = [
119+
"console",
120+
]
121+
issuerRef = {
122+
name = module.certificates.cluster_issuer_name
123+
kind = "ClusterIssuer"
124+
}
125+
}
126+
internal = {
127+
issuerRef = {
128+
name = module.certificates.cluster_issuer_name
129+
kind = "ClusterIssuer"
130+
}
131+
}
132+
}
133+
} : {}
91134
}
92135

93136
merged_helm_values = merge(local.default_helm_values, var.helm_values)
@@ -131,14 +174,15 @@ locals {
131174
}
132175

133176
module "operator" {
134-
source = "github.com/MaterializeInc/terraform-helm-materialize?ref=v0.1.8"
177+
source = "github.com/MaterializeInc/terraform-helm-materialize?ref=v0.1.9"
135178

136179
count = var.install_materialize_operator ? 1 : 0
137180

138181
depends_on = [
139182
module.aks,
140183
module.database,
141-
module.storage
184+
module.storage,
185+
module.certificates,
142186
]
143187

144188
namespace = var.namespace

modules/certificates/main.tf

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
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 = var.cert_manager_chart_version
19+
timeout = var.cert_manager_install_timeout
20+
21+
set {
22+
name = "crds.enabled"
23+
value = "true"
24+
}
25+
26+
depends_on = [
27+
kubernetes_namespace.cert_manager,
28+
]
29+
}
30+
31+
resource "kubernetes_manifest" "self_signed_cluster_issuer" {
32+
# only create these after cert manager is installed
33+
count = var.use_self_signed_cluster_issuer ? 1 : 0
34+
35+
manifest = {
36+
"apiVersion" = "cert-manager.io/v1"
37+
"kind" = "ClusterIssuer"
38+
"metadata" = {
39+
"name" = "${var.name_prefix}-self-signed"
40+
}
41+
"spec" = {
42+
"selfSigned" = {}
43+
}
44+
}
45+
46+
depends_on = [
47+
helm_release.cert_manager,
48+
]
49+
}
50+
51+
resource "kubernetes_manifest" "self_signed_root_ca_certificate" {
52+
count = var.use_self_signed_cluster_issuer ? 1 : 0
53+
54+
manifest = {
55+
"apiVersion" = "cert-manager.io/v1"
56+
"kind" = "Certificate"
57+
"metadata" = {
58+
"name" = "${var.name_prefix}-self-signed-ca"
59+
"namespace" = var.cert_manager_namespace
60+
}
61+
"spec" = {
62+
"isCA" = true
63+
"commonName" = "${var.name_prefix}-self-signed-ca"
64+
"secretName" = "${var.name_prefix}-root-ca"
65+
"privateKey" = {
66+
"algorithm" = "RSA"
67+
"encoding" = "PKCS8"
68+
"size" = 4096
69+
"rotationPolicy" = "Always"
70+
}
71+
"issuerRef" = {
72+
"name" = "${var.name_prefix}-self-signed"
73+
"kind" = "ClusterIssuer"
74+
"group" = "cert-manager.io"
75+
}
76+
}
77+
}
78+
79+
depends_on = [
80+
helm_release.cert_manager,
81+
kubernetes_manifest.self_signed_cluster_issuer,
82+
]
83+
}
84+
85+
resource "kubernetes_manifest" "root_ca_cluster_issuer" {
86+
count = var.use_self_signed_cluster_issuer ? 1 : 0
87+
88+
manifest = {
89+
"apiVersion" = "cert-manager.io/v1"
90+
"kind" = "ClusterIssuer"
91+
"metadata" = {
92+
"name" = "${var.name_prefix}-root-ca"
93+
}
94+
"spec" = {
95+
"ca" = {
96+
"secretName" = "${var.name_prefix}-root-ca"
97+
}
98+
}
99+
}
100+
101+
depends_on = [
102+
helm_release.cert_manager,
103+
kubernetes_manifest.self_signed_root_ca_certificate,
104+
]
105+
}

modules/certificates/outputs.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
output "cluster_issuer_name" {
2+
description = "Name of the ClusterIssuer"
3+
value = var.use_self_signed_cluster_issuer ? kubernetes_manifest.root_ca_cluster_issuer[0].object.metadata.name : null
4+
}

modules/certificates/variables.tf

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
variable "install_cert_manager" {
2+
description = "Whether to install cert-manager."
3+
type = bool
4+
}
5+
6+
variable "use_self_signed_cluster_issuer" {
7+
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."
8+
type = bool
9+
}
10+
11+
variable "cert_manager_namespace" {
12+
description = "The name of the namespace in which cert-manager is or will be installed."
13+
type = string
14+
}
15+
16+
variable "name_prefix" {
17+
description = "The name prefix to use for Kubernetes resources. Does not apply to cert-manager itself, as that is a singleton per cluster."
18+
type = string
19+
}
20+
21+
variable "cert_manager_install_timeout" {
22+
description = "Timeout for installing the cert-manager helm chart, in seconds."
23+
type = number
24+
}
25+
26+
variable "cert_manager_chart_version" {
27+
description = "Version of the cert-manager helm chart to install."
28+
type = string
29+
}

modules/certificates/versions.tf

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
terraform {
2+
required_version = ">= 1.0"
3+
4+
required_providers {
5+
6+
azurerm = {
7+
source = "hashicorp/azurerm"
8+
version = ">= 3.75.0"
9+
}
10+
11+
azuread = {
12+
source = "hashicorp/azuread"
13+
version = ">= 2.45.0"
14+
}
15+
16+
kubernetes = {
17+
source = "hashicorp/kubernetes"
18+
version = "~> 2.0"
19+
}
20+
21+
helm = {
22+
source = "hashicorp/helm"
23+
version = "~> 2.0"
24+
}
25+
}
26+
}

0 commit comments

Comments
 (0)