Skip to content

Commit fbd09b6

Browse files
committed
Modularize cert-manager and ingress, update LGTM, and add deployment docs
1 parent 9e94ae6 commit fbd09b6

17 files changed

+587
-97
lines changed

cert-manager/README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Cert-Manager Component
2+
3+
This directory contains the necessary configurations for **Cert-Manager**, which handles certificate management and issuance for the observability stack.
4+
5+
## Deployment Options
6+
7+
You can deploy Cert-Manager using one of the following methods:
8+
9+
### 1. Terraform (Automated)
10+
This method uses the Terraform configuration located in the `terraform/` directory. It is the recommended approach for integration with the full observability stack.
11+
12+
- [**Terraform Deployment Guide**](../docs/cert-manager-terraform-deployment.md)
13+
14+
### 2. Manual (Helm & Kubectl)
15+
If you prefer to deploy manually using CLI tools, you can follow the manual guide.
16+
17+
- [**Manual Deployment Guide**](../docs/cert-manager-manual-deployment.md)

cert-manager/terraform/main.tf

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
resource "helm_release" "cert_manager" {
2+
count = var.install_cert_manager ? 1 : 0
3+
4+
name = "cert-manager"
5+
repository = "https://charts.jetstack.io"
6+
chart = "cert-manager"
7+
namespace = var.namespace
8+
create_namespace = var.create_namespace
9+
version = var.cert_manager_version
10+
11+
set {
12+
name = "installCRDs"
13+
value = var.install_crds
14+
}
15+
16+
wait = true
17+
timeout = 600
18+
}
19+
20+
# Issuer for Let's Encrypt
21+
resource "kubernetes_manifest" "letsencrypt_issuer" {
22+
count = var.install_cert_manager ? 1 : 0
23+
24+
manifest = {
25+
apiVersion = "cert-manager.io/v1"
26+
kind = var.cert_issuer_kind
27+
metadata = merge(
28+
{
29+
name = var.cert_issuer_name
30+
},
31+
# Only add namespace if Kind is Issuer.
32+
# If issuer_namespace is set, use it. Otherwise fallback to var.namespace.
33+
var.cert_issuer_kind == "Issuer" ? {
34+
namespace = coalesce(var.issuer_namespace, var.namespace)
35+
} : {}
36+
)
37+
spec = {
38+
acme = {
39+
server = var.issuer_server
40+
email = var.letsencrypt_email
41+
privateKeySecretRef = {
42+
name = "${var.cert_issuer_name}-key"
43+
}
44+
solvers = [
45+
{
46+
http01 = {
47+
ingress = {
48+
class = var.ingress_class_name
49+
}
50+
}
51+
}
52+
]
53+
}
54+
}
55+
}
56+
57+
depends_on = [helm_release.cert_manager]
58+
}

cert-manager/terraform/outputs.tf

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
output "namespace" {
2+
description = "Namespace where cert-manager was installed"
3+
value = var.namespace
4+
}
5+
6+
output "issuer_name" {
7+
description = "Name of the created Issuer"
8+
value = var.install_cert_manager ? var.cert_issuer_name : ""
9+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
variable "install_cert_manager" {
2+
description = "Whether to install cert-manager"
3+
type = bool
4+
default = false
5+
}
6+
7+
variable "cert_manager_version" {
8+
description = "Version of cert-manager chart"
9+
type = string
10+
default = "v1.15.0"
11+
}
12+
13+
variable "namespace" {
14+
description = "Namespace to install cert-manager into"
15+
type = string
16+
default = "cert-manager"
17+
}
18+
19+
variable "create_namespace" {
20+
description = "Whether to create the namespace"
21+
type = bool
22+
default = true
23+
}
24+
25+
variable "install_crds" {
26+
description = "Whether to install CRDs"
27+
type = bool
28+
default = true
29+
}
30+
31+
variable "letsencrypt_email" {
32+
description = "Email address for Let's Encrypt certificate notifications"
33+
type = string
34+
}
35+
36+
variable "cert_issuer_name" {
37+
description = "Name of the ClusterIssuer or Issuer to create"
38+
type = string
39+
default = "letsencrypt-prod"
40+
}
41+
42+
variable "cert_issuer_kind" {
43+
description = "Kind of Issuer to create (ClusterIssuer or Issuer)"
44+
type = string
45+
default = "ClusterIssuer"
46+
validation {
47+
condition = contains(["ClusterIssuer", "Issuer"], var.cert_issuer_kind)
48+
error_message = "cert_issuer_kind must be either 'ClusterIssuer' or 'Issuer'."
49+
}
50+
}
51+
52+
variable "issuer_namespace" {
53+
description = "Namespace for the Issuer (required if cert_issuer_kind is Issuer). Defaults to the installation namespace if not provided."
54+
type = string
55+
default = ""
56+
}
57+
58+
variable "issuer_server" {
59+
description = "ACME server URL"
60+
type = string
61+
default = "https://acme-v02.api.letsencrypt.org/directory"
62+
}
63+
64+
variable "ingress_class_name" {
65+
description = "Ingress class to solve challenges"
66+
type = string
67+
default = "nginx"
68+
}

cert-manager/terraform/versions.tf

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
terraform {
2+
required_version = ">= 1.0"
3+
required_providers {
4+
kubernetes = {
5+
source = "hashicorp/kubernetes"
6+
version = "~> 2.0"
7+
}
8+
helm = {
9+
source = "hashicorp/helm"
10+
version = "~> 2.12"
11+
}
12+
}
13+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Manual Cert-Manager Deployment (Helm & Kubectl)
2+
3+
This guide explains how to manually deploy **Cert-Manager** and configure a **ClusterIssuer** without using Terraform.
4+
5+
## Prerequisites
6+
7+
- **Helm** 3.x installed
8+
- **kubectl** installed and configured
9+
10+
## 1. Verify Context
11+
12+
Ensure you are targeting the correct Kubernetes cluster:
13+
14+
```bash
15+
kubectl config current-context
16+
```
17+
18+
## 2. Install Cert-Manager via Helm
19+
20+
1. **Add the Jetstack Helm repository**:
21+
```bash
22+
helm repo add jetstack https://charts.jetstack.io
23+
helm repo update
24+
```
25+
26+
2. **Install Cert-Manager**:
27+
```bash
28+
helm install cert-manager jetstack/cert-manager \
29+
--namespace cert-manager \ # You can change this to your preferred namespace
30+
--create-namespace \
31+
--version v1.15.0 \
32+
--set installCRDs=true
33+
```
34+
35+
3. **Verify Installation**:
36+
```bash
37+
kubectl get pods --namespace cert-manager # Adjust namespace if changed above
38+
```
39+
40+
## 3. Configure ClusterIssuer
41+
42+
1. **Create the manifest file**:
43+
Create a file named `cluster-issuer.yaml` in your current directory:
44+
45+
```yaml
46+
apiVersion: cert-manager.io/v1
47+
kind: ClusterIssuer
48+
metadata:
49+
name: letsencrypt-prod
50+
spec:
51+
acme:
52+
server: https://acme-v02.api.letsencrypt.org/directory
53+
email: your-email@example.com # REPLACE THIS
54+
privateKeySecretRef:
55+
name: letsencrypt-prod-key
56+
solvers:
57+
- http01:
58+
ingress:
59+
class: nginx
60+
```
61+
62+
2. **Apply the manifest**:
63+
```bash
64+
kubectl apply -f cluster-issuer.yaml
65+
```
66+
67+
## 4. Verification
68+
69+
Check the status of the ClusterIssuer:
70+
71+
```bash
72+
kubectl get clusterissuer letsencrypt-prod -o wide
73+
```
74+
It should say `True` in the `READY` column.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Cert-Manager Deployment (Terraform)
2+
3+
This guide explains how to deploy **Cert-Manager** using the standalone Terraform configuration.
4+
5+
## Prerequisites
6+
7+
- **Terraform** >= 1.0
8+
- **Kubernetes Cluster** (GKE, etc.)
9+
- **kubectl** configured to context
10+
11+
## Deployment Steps
12+
13+
1. **Verify Context**:
14+
Ensure you are pointing to the correct cluster before running Terraform.
15+
```bash
16+
kubectl config current-context
17+
```
18+
19+
2. **Navigate to the directory**:
20+
From the project root:
21+
```bash
22+
cd cert-manager/terraform
23+
```
24+
25+
3. **Initialize Terraform**:
26+
```bash
27+
terraform init
28+
```
29+
30+
4. **Create a `terraform.tfvars` file**:
31+
Create a file named `terraform.tfvars` with your specific configuration:
32+
```hcl
33+
letsencrypt_email = "your-email@example.com"
34+
cert_issuer_name = "letsencrypt-prod"
35+
install_cert_manager = true # Must be set to true explicitly
36+
37+
# Optional:
38+
# cert_issuer_kind = "ClusterIssuer" # or "Issuer"
39+
# namespace = "cert-manager"
40+
```
41+
42+
5. **Review the Plan**:
43+
```bash
44+
terraform plan
45+
```
46+
47+
6. **Apply**:
48+
```bash
49+
terraform apply
50+
```
51+
52+
## Variables
53+
54+
| Name | Description | Default |
55+
|------|-------------|---------|
56+
| `install_cert_manager` | Install Cert-Manager via Helm | `false` |
57+
| `cert_manager_version` | Chart version | `v1.15.0` |
58+
| `namespace` | Namespace to install into | `cert-manager` |
59+
| `letsencrypt_email` | Email for ACME registration | **Required** |
60+
| `cert_issuer_name` | Name of ClusterIssuer/Issuer | `letsencrypt-prod` |
61+
| `cert_issuer_kind` | Kind of Issuer (`ClusterIssuer` or `Issuer`) | `ClusterIssuer` |
62+
| `issuer_namespace` | Namespace for Issuer (if Kind is Issuer). Defaults to install namespace. | `null` |
63+
| `ingress_class_name` | Ingress class for solving challenges | `nginx` |
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Manual NGINX Ingress Controller Deployment (Helm)
2+
3+
This guide explains how to manually deploy the **NGINX Ingress Controller** using Helm.
4+
5+
## Prerequisites
6+
7+
- **Helm** 3.x installed
8+
- **kubectl** installed and configured
9+
10+
## 1. Verify Context
11+
12+
Ensure you are targeting the correct Kubernetes cluster:
13+
14+
```bash
15+
kubectl config current-context
16+
```
17+
18+
## 2. Installation
19+
20+
1. **Add the Kubernetes Ingress Nginx repository**:
21+
```bash
22+
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
23+
helm repo update
24+
```
25+
26+
2. **Install the Controller**:
27+
```bash
28+
helm install nginx-monitoring ingress-nginx/ingress-nginx \
29+
--namespace ingress-nginx \ # You can change this to your preferred namespace
30+
--create-namespace \
31+
--version 4.10.1 \
32+
--set controller.ingressClassResource.name=nginx \
33+
--set controller.ingressClass=nginx \
34+
--set controller.ingressClassResource.controllerValue=k8s.io/nginx \
35+
--set controller.ingressClassResource.enabled=true \
36+
--set controller.ingressClassByName=true
37+
```
38+
39+
## 3. Verification
40+
41+
1. **Check Pods**:
42+
```bash
43+
kubectl get pods -n ingress-nginx # Adjust namespace if changed above
44+
```
45+
46+
2. **Check LoadBalancer Service**:
47+
```bash
48+
kubectl get svc -n ingress-nginx # Adjust namespace if changed above
49+
```
50+
Wait for the `EXTERNAL-IP` to be assigned.

0 commit comments

Comments
 (0)