feat(cert-manager): Add Cloudns issuer and DNS-01 challenge support

- Introduced a new Cloudns issuer configuration for cert-manager.
- Created separate tasks for DNS-01 and HTTP-01 challenge issuers.
- Updated cert-manager tasks to include Cloudns provider and manage secrets.
- Refactored existing LetsEncrypt issuer registration to use new task structure.
- Added necessary Kubernetes resources for Cloudns integration, including RBAC and certificates.
- Updated Terraform configurations to support new DNS records and service changes.
- Adjusted deployment strategies for CoreDNS and Open WebUI applications.
This commit is contained in:
2025-06-07 20:39:38 +02:00
parent 3cda0b5624
commit 01bf71f8d2
25 changed files with 590 additions and 17396 deletions
@@ -113,8 +113,14 @@ microk8s_allowed_hosts:
- 10.5.5.5
microk8s_alt_names: "{{ hostname }}"
# Let's encrypt issuer
microk8s_lets_encrypt_issuer: false
microk8s_certmgr_letsencrypt_issuer_email: c.alexandre.pires@alexpires.me
# HTTP-01 Let's encrypt issuer is disable in dev
microk8s_certmgr_letsencrypt_http01: false
# DNS-01 issuer is enabled in dev
microk8s_certmgr_letsencrypt_dns01: true
microk8s_cloudns_auth_id: "{{ lookup('env', 'CLOUDNS_AUTH_ID') }}"
microk8s_cloudns_auth_password: "{{ lookup('env', 'CLOUDNS_PASSWORD') }}"
microk8s_encryption_secret: "{{ lookup('env', 'MICROK8S_ENCRYPTION_SECRET') }}"
microk8s_users:
- username: operator
+1 -1
View File
@@ -145,7 +145,7 @@ microk8s_allowed_hosts:
microk8s_alt_names: "{{ hostname }}"
# Let's encrypt issuer
microk8s_issuer_email: c.alexandre.pires@alexpires.me
microk8s_certmgr_letsencrypt_issuer_email: c.alexandre.pires@alexpires.me
microk8s_encryption_cfg: /mnt/microk8s_config/microk8s_encryption.yaml
microk8s_encryption_secret: "{{ lookup('env', 'MICROK8S_ENCRYPTION_SECRET') }}"
microk8s_encryption_kms_socket: /var/run/kmsplugin/socket.sock
@@ -231,3 +231,10 @@ virt_machines:
slot: "0x00",
function: "0x0",
}
cloudns_auth_id: "{{ lookup('env', 'CLOUDNS_AUTH_ID') }}"
cloudns_auth_password: "{{ lookup('env', 'CLOUDNS_PASSWORD') }}"
cloudns_nameserver: "109.201.133.111"
certbot_email: c.alexandre.pires@alexpires.me
certbot_domains:
- "vh-01.lab.alexpires.me"
+61
View File
@@ -0,0 +1,61 @@
---
- name: Obtain Let's Encrypt SSL certificate using ClouDNS
hosts: certbot
become: true
tasks:
- name: Set required facts
ansible.builtin.set_fact:
cloudns_credentials_path: "/etc/letsencrypt/cloudns.ini"
- name: Check if cloudDNS credentials are set or fail
when: not (cloudns_auth_id is defined and cloudns_auth_password is defined)
ansible.builtin.fail:
msg: "CloudDNS credentials are not set"
- name: Check if cloudDNS nameserver is set or fail
when: not (cloudns_nameserver is defined)
ansible.builtin.fail:
msg: "CloudDNS nameserver is not set"
- name: Install Certbot and dependencies
when: ansible_os_family == "RedHat"
ansible.builtin.dnf:
name:
- certbot
state: present
- name: Install cloudDNS plugin dependencies
ansible.builtin.pip:
name:
- certbot-dns-cloudns
state: present
- name: Create ClouDNS credentials file
ansible.builtin.copy:
dest: "{{ cloudns_credentials_path }}"
content: |
dns_cloudns_auth_id={{ cloudns_auth_id }}
dns_cloudns_auth_password={{ cloudns_auth_password }}
owner: root
group: root
mode: '0600'
- name: Obtain SSL certificate using Certbot with ClouDNS plugin
ansible.builtin.command: >
certbot certonly --authenticator dns-cloudns
--non-interactive
--agree-tos
--email {{ certbot_email }}
--dns-cloudns-credentials {{ cloudns_credentials_path }}
--dns-cloudns-nameserver {{ cloudns_nameserver }} -d {{ item }}
args:
creates: "/etc/letsencrypt/live/{{ item }}/fullchain.pem"
loop: "{{ certbot_domains }}"
- name: Set up automatic certificate renewal
ansible.builtin.cron:
name: "Renew Let's Encrypt certificates"
job: "certbot renew --quiet"
minute: 0
hour: 3
-3
View File
@@ -1,3 +0,0 @@
fwknopd_keys_dir: /etc/fwknop
fwknopd_key_base64: "<REPLACE_WITH_YOUR_KEY>"
fwknopd_hmac_key_base64: "<REPLACE_WITH_YOUR_HMAC>"
-39
View File
@@ -1,39 +0,0 @@
---
galaxy_info:
author: Alexandre Pires
description: Manage fwknopd on Linux
company: A13Labs
role_name: fwknopd
namespace: a13labs
# If the issue tracker for your role is not on github, uncomment the
# next line and provide a value
# issue_tracker_url: http://example.com/issue/tracker
# Choose a valid license ID from https://spdx.org - some suggested licenses:
# - BSD-3-Clause (default)
# - MIT
# - GPL-2.0-or-later
# - GPL-3.0-only
# - Apache-2.0
# - CC-BY-4.0
license: MIT
min_ansible_version: "2.1"
# If this a Container Enabled role, provide the minimum Ansible Container version.
# min_ansible_container_version:
galaxy_tags:
[]
# List tags for your role here, one per line. A tag is a keyword that describes
# and categorizes the role. Users find roles by searching for tags. Be sure to
# remove the '[]' above, if you add tags to this list.
#
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
# Maximum 20 tags per role.
dependencies:
[]
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
# if you add dependencies to this list.
@@ -1,8 +0,0 @@
---
- name: Converge
hosts: all
gather_facts: false
tasks:
- name: Include role fwknopd
ansible.builtin.include_role:
name: fwknopd
@@ -1,23 +0,0 @@
---
dependency:
name: galaxy
driver:
name: podman
platforms:
- name: instance
image: nmusatti/ubuntu2204-pys-systemd:latest
pre_build_image: true
privileged: true
tmpfs:
- /run
- /tmp
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
provisioner:
name: ansible
options:
vvv: true
env:
ANSIBLE_ROLES_PATH: ../../../
verifier:
name: ansible
@@ -1,30 +0,0 @@
---
- name: Prepare
hosts: all
gather_facts: false
tasks:
- name: Update cache # noqa no-changed-when
ansible.builtin.raw: apt update
- name: Install required packages # noqa no-changed-when
ansible.builtin.raw: apt install -y python3 sudo
- name: Install required packages # noqa no-changed-when
ansible.builtin.shell: |
set -o pipefail
apt install -y systemd
find /etc/systemd/system/*.wants /lib/systemd/system/multi-user.target.wants /lib/systemd/system/local-fs.target.wants /lib/systemd/system/sockets.target.wants -type f -name '*initctl*' -delete
find /lib/systemd/system/sysinit.target.wants -type f ! -name '*systemd-tmpfiles-setup*' -delete
find /lib/systemd -type f -name systemd-update-utmp-runlevel.service -delete
rm -vf /usr/share/systemd/tmp.mount
sed -ri '/^IPAddressDeny/d' /lib/systemd/system/systemd-journald.service
for MATCH in plymouth-start.service plymouth-quit-wait.service syslog.socket syslog.service display-manager.service systemd-sysusers.service tmp.mount systemd-udevd.service; do \
grep -rn --binary-files=without-match ${MATCH} /lib/systemd/ | cut -d: -f1 | xargs -r sed -ri 's/(.*=.*)'${MATCH}'(.*)/\1\2/'; \
done
systemctl disable ondemand.service
systemctl set-default multi-user.target
become: true
args:
executable: /bin/bash
environment:
DEBIAN_FRONTEND: noninteractive
-25
View File
@@ -1,25 +0,0 @@
---
- name: Install fwknop
ansible.builtin.package:
name: fwknop-server
state: present
update_cache: true
- name: Enable and start fwknopd
ansible.builtin.systemd:
name: fwknopd
enabled: true
state: started
- name: Generate fwknop key pair
ansible.builtin.command: fwknop --key-gen
args:
creates: "{{ fwknopd_keys_dir }}/access.conf"
- name: Copy access.conf
ansible.builtin.template:
src: access.conf.j2
dest: "{{ fwknopd_keys_dir }}/access.conf"
owner: root
group: root
mode: '0600'
@@ -1,6 +0,0 @@
SOURCE ANY
KEY_BASE64 {{ fwknopd_key_base64 }}
HMAC_KEY_BASE64 {{ fwknopd_hmac_key_base64 }}
ALLOW_IP ANY
OPEN_PORTS tcp/22
FW_ACCESS_TIMEOUT 30
+7 -3
View File
@@ -9,9 +9,13 @@ microk8s_lb_https_port: 443
microk8s_metallb_version: 0.14.9
# certificate manager
microk8s_issuer_email: webmaster@localhost.localdomain
microk8s_certmgr_letsencrypt_issuer_email: webmaster@localhost.localdomain
microk8s_certmgr_version: 1.14.5
microk8s_lets_encrypt_issuer: true
microk8s_certmgr_letsencrypt_http01: true
microk8s_certmgr_letsencrypt_dns01: false
microk8s_certmgr_letsencrypt_dns01_provider: "cloudns"
microk8s_cloudns_auth_id:
microk8s_cloudns_auth_password:
# microk8s specific
microk8s_channel: "{{ microk8s_k8s_version }}/stable"
@@ -38,6 +42,6 @@ microk8s_allowed_hosts: []
microk8s_iac_user: "provision"
microk8s_encryption_secret: "a13labs"
microk8s_encryption_secret: "UGIzZ0w5UENaOVp2YkttWDdDNlNtaDdNYUJVd0ttUTY="
microk8s_encryption_cfg: "/etc/microk8s_encryption.yaml"
microk8s_encryption_kms_socket: ""
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,322 @@
---
# Source: cert-manager-webhook-cloudns/templates/rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: cert-manager-webhook-cloudns
namespace: "cert-manager"
labels:
app: cert-manager-webhook-cloudns
---
# Source: cert-manager-webhook-cloudns/templates/rbac.yaml
# Grant cert-manager permission to validate using our apiserver
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cert-manager-webhook-cloudns:domain-solver
labels:
app: cert-manager-webhook-cloudns
rules:
- apiGroups:
- acme.ixon.cloud
resources:
- "*"
verbs:
- "create"
---
# Source: cert-manager-webhook-cloudns/templates/rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cert-manager-webhook-cloudns:flowcontrol-solver
labels:
app: cert-manager-webhook-cloudns
chart: cert-manager-webhook-cloudns-1.1.1
release: cert-manager-webhook-cloudns
heritage: Helm
rules:
- apiGroups:
- "flowcontrol.apiserver.k8s.io"
resources:
- "prioritylevelconfigurations"
- "flowschemas"
verbs:
- "list"
- "watch"
---
# Source: cert-manager-webhook-cloudns/templates/secret-rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cert-manager-webhook-cloudns:cloudns-api-secret-access
labels:
app: cert-manager-webhook-cloudns
rules:
- apiGroups: [""]
resources:
- secrets
resourceNames:
- cert-manager-webhook-cloudns-api-secret
verbs:
- "get"
---
# Source: cert-manager-webhook-cloudns/templates/rbac.yaml
# apiserver gets the auth-delegator role to delegate auth decisions to
# the core apiserver
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cert-manager-webhook-cloudns:auth-delegator
labels:
app: cert-manager-webhook-cloudns
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:auth-delegator
subjects:
- apiGroup: ""
kind: ServiceAccount
name: cert-manager-webhook-cloudns
namespace: cert-manager
---
# Source: cert-manager-webhook-cloudns/templates/rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cert-manager-webhook-cloudns:domain-solver
labels:
app: cert-manager-webhook-cloudns
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cert-manager-webhook-cloudns:domain-solver
subjects:
- apiGroup: ""
kind: ServiceAccount
name: cert-manager
namespace: cert-manager
---
# Source: cert-manager-webhook-cloudns/templates/rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cert-manager-webhook-cloudns:flowcontrol-solver
labels:
app: cert-manager-webhook-cloudns
chart: cert-manager-webhook-cloudns-1.1.1
release: cert-manager-webhook-cloudns
heritage: Helm
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cert-manager-webhook-cloudns:flowcontrol-solver
subjects:
- apiGroup: ""
kind: ServiceAccount
name: cert-manager-webhook-cloudns
namespace: "cert-manager"
---
# Source: cert-manager-webhook-cloudns/templates/secret-rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cert-manager-webhook-cloudns:api-secret-access
labels:
app: cert-manager-webhook-cloudns
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cert-manager-webhook-cloudns:api-secret-access
subjects:
- apiGroup: ""
kind: ServiceAccount
namespace: default
name: cert-manager-webhook-cloudns
---
# Source: cert-manager-webhook-cloudns/templates/rbac.yaml
# Grant the webhook permission to read the ConfigMap containing the Kubernetes
# apiserver's requestheader-ca-certificate.
# This ConfigMap is automatically created by the Kubernetes apiserver.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: cert-manager-webhook-cloudns:webhook-authentication-reader
namespace: kube-system
labels:
app: cert-manager-webhook-cloudns
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: extension-apiserver-authentication-reader
subjects:
- apiGroup: ""
kind: ServiceAccount
name: cert-manager-webhook-cloudns
namespace: cert-manager
---
# Source: cert-manager-webhook-cloudns/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: cert-manager-webhook-cloudns
namespace: "cert-manager"
labels:
app: cert-manager-webhook-cloudns
spec:
type: ClusterIP
ports:
- port: 443
targetPort: https
protocol: TCP
name: https
selector:
app: cert-manager-webhook-cloudns
---
# Source: cert-manager-webhook-cloudns/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: cert-manager-webhook-cloudns
namespace: "cert-manager"
labels:
app: cert-manager-webhook-cloudns
spec:
replicas: 1
selector:
matchLabels:
app: cert-manager-webhook-cloudns
template:
metadata:
labels:
app: cert-manager-webhook-cloudns
spec:
serviceAccountName: cert-manager-webhook-cloudns
containers:
- name: cert-manager-webhook-cloudns
image: "mschirrmeister/cert-manager-webhook-cloudns:latest-alpine"
imagePullPolicy: IfNotPresent
args:
- --tls-cert-file=/certs/tls.crt
- --tls-private-key-file=/certs/tls.key
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: GROUP_NAME
value: "acme.ixon.cloud"
- name: CLOUDNS_AUTH_ID_FILE
value: "/creds/auth_id"
- name: CLOUDNS_AUTH_PASSWORD_FILE
value: "/creds/auth_password"
- name: CLOUDNS_AUTH_ID_TYPE
value: auth-id
ports:
- name: https
containerPort: 443
protocol: TCP
livenessProbe:
httpGet:
scheme: HTTPS
path: /healthz
port: https
readinessProbe:
httpGet:
scheme: HTTPS
path: /healthz
port: https
volumeMounts:
- name: certs
mountPath: /certs
readOnly: true
- name: creds
mountPath: /creds
readOnly: true
resources: {}
volumes:
- name: certs
secret:
secretName: cert-manager-webhook-cloudns-webhook-tls
- name: creds
secret:
secretName: cert-manager-webhook-cloudns-api-secret
---
# Source: cert-manager-webhook-cloudns/templates/apiservice.yaml
apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
name: v1alpha1.acme.ixon.cloud
labels:
app: cert-manager-webhook-cloudns
annotations:
cert-manager.io/inject-ca-from: "cert-manager/cert-manager-webhook-cloudns-webhook-tls"
spec:
group: acme.ixon.cloud
groupPriorityMinimum: 1000
versionPriority: 15
service:
name: cert-manager-webhook-cloudns
namespace: cert-manager
version: v1alpha1
---
# Source: cert-manager-webhook-cloudns/templates/pki.yaml
# Generate a CA Certificate used to sign certificates for the webhook
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: cert-manager-webhook-cloudns-ca
namespace: "cert-manager"
labels:
app: cert-manager-webhook-cloudns
spec:
secretName: cert-manager-webhook-cloudns-ca
duration: 43800h # 5y
issuerRef:
name: cert-manager-webhook-cloudns-selfsign
commonName: "ca.cert-manager-webhook-cloudns.cert-manager"
isCA: true
---
# Source: cert-manager-webhook-cloudns/templates/pki.yaml
# Finally, generate a serving certificate for the webhook to use
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: cert-manager-webhook-cloudns-webhook-tls
namespace: "cert-manager"
labels:
app: cert-manager-webhook-cloudns
spec:
secretName: cert-manager-webhook-cloudns-webhook-tls
duration: 8760h # 1y
issuerRef:
name: cert-manager-webhook-cloudns-ca
dnsNames:
- cert-manager-webhook-cloudns
- cert-manager-webhook-cloudns.cert-manager
- cert-manager-webhook-cloudns.cert-manager.svc
---
# Source: cert-manager-webhook-cloudns/templates/pki.yaml
# Create a selfsigned Issuer, in order to create a root CA certificate for
# signing webhook serving certificates
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: cert-manager-webhook-cloudns-selfsign
namespace: "cert-manager"
labels:
app: cert-manager-webhook-cloudns
spec:
selfSigned: {}
---
# Source: cert-manager-webhook-cloudns/templates/pki.yaml
# Create an Issuer that uses the above generated CA certificate to issue certs
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: cert-manager-webhook-cloudns-ca
namespace: "cert-manager"
labels:
app: cert-manager-webhook-cloudns
spec:
ca:
secretName: cert-manager-webhook-cloudns-ca
+6 -60
View File
@@ -15,64 +15,10 @@
src: "{{ k8s_etc }}/k8s-certmanager.yaml"
wait: true
- name: CertManager | Register LetsEncrypt (prod)
when: microk8s_lets_encrypt_issuer is true
environment:
PATH: "{{ k8s_venv }}/bin:{{ ansible_env.PATH }}"
vars:
ansible_python_interpreter: "{{ k8s_venv }}/bin/python"
kubernetes.core.k8s:
state: present
kubeconfig: "{{ k8s_kubeconfig }}"
wait: true
definition:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
namespace: cert-manager
spec:
acme:
# The ACME server URL
server: https://acme-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: "{{ microk8s_issuer_email }}"
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-prod
# Enable the HTTP-01 challenge provider
solvers:
- http01:
ingress:
class: public
- name: CertManager | LetsEncrypt DNS-01 issuer
ansible.builtin.include_tasks: issuers/dns-01.yml
when: microk8s_certmgr_letsencrypt_dns01 is true
- name: CertManager | Register LetsEncrypt (staging)
when: microk8s_lets_encrypt_issuer is true
environment:
PATH: "{{ k8s_venv }}/bin:{{ ansible_env.PATH }}"
vars:
ansible_python_interpreter: "{{ k8s_venv }}/bin/python"
kubernetes.core.k8s:
state: present
kubeconfig: "{{ k8s_kubeconfig }}"
wait: true
definition:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
namespace: cert-manager
spec:
acme:
# The ACME server URL
server: https://acme-staging-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: "{{ microk8s_issuer_email }}"
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-staging
# Enable the HTTP-01 challenge provider
solvers:
- http01:
ingress:
class: public
- name: CertManager | LetsEncrypt HTTP-01 issuer
ansible.builtin.include_tasks: issuers/http-01.yml
when: microk8s_certmgr_letsencrypt_http01 is true
@@ -0,0 +1,64 @@
- name: CertManager | LetsEncrypt DNS-01 provider
ansible.builtin.include_tasks: "providers/{{ microk8s_certmgr_letsencrypt_dns01_provider }}.yml"
- name: CertManager | Register LetsEncrypt (prod)
environment:
PATH: "{{ k8s_venv }}/bin:{{ ansible_env.PATH }}"
vars:
ansible_python_interpreter: "{{ k8s_venv }}/bin/python"
kubernetes.core.k8s:
state: present
kubeconfig: "{{ k8s_kubeconfig }}"
wait: true
definition:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
namespace: cert-manager
spec:
acme:
# The ACME server URL
server: https://acme-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: "{{ microk8s_certmgr_letsencrypt_issuer_email }}"
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-prod
# Enable the HTTP-01 challenge provider
solvers:
- dns01:
webhook:
groupName: acme.ixon.cloud
solverName: cloudns
- name: CertManager | Register LetsEncrypt (staging)
environment:
PATH: "{{ k8s_venv }}/bin:{{ ansible_env.PATH }}"
vars:
ansible_python_interpreter: "{{ k8s_venv }}/bin/python"
kubernetes.core.k8s:
state: present
kubeconfig: "{{ k8s_kubeconfig }}"
wait: true
definition:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
namespace: cert-manager
spec:
acme:
# The ACME server URL
server: https://acme-staging-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: "{{ microk8s_certmgr_letsencrypt_issuer_email }}"
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-staging
# Enable the HTTP-01 challenge provider
solvers:
- dns01:
webhook:
groupName: acme.ixon.cloud
solverName: cloudns
@@ -0,0 +1,59 @@
- name: CertManager | Register LetsEncrypt (prod)
environment:
PATH: "{{ k8s_venv }}/bin:{{ ansible_env.PATH }}"
vars:
ansible_python_interpreter: "{{ k8s_venv }}/bin/python"
kubernetes.core.k8s:
state: present
kubeconfig: "{{ k8s_kubeconfig }}"
wait: true
definition:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
namespace: cert-manager
spec:
acme:
# The ACME server URL
server: https://acme-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: "{{ microk8s_certmgr_letsencrypt_issuer_email }}"
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-prod
# Enable the HTTP-01 challenge provider
solvers:
- http01:
ingress:
class: public
- name: CertManager | Register LetsEncrypt (staging)
environment:
PATH: "{{ k8s_venv }}/bin:{{ ansible_env.PATH }}"
vars:
ansible_python_interpreter: "{{ k8s_venv }}/bin/python"
kubernetes.core.k8s:
state: present
kubeconfig: "{{ k8s_kubeconfig }}"
wait: true
definition:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
namespace: cert-manager
spec:
acme:
# The ACME server URL
server: https://acme-staging-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: "{{ microk8s_certmgr_letsencrypt_issuer_email }}"
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-staging
# Enable the HTTP-01 challenge provider
solvers:
- http01:
ingress:
class: public
@@ -0,0 +1,35 @@
- name: Cermanager | Create cloudns credentials
environment:
PATH: "{{ k8s_venv }}/bin:{{ ansible_env.PATH }}"
vars:
ansible_python_interpreter: "{{ k8s_venv }}/bin/python"
kubernetes.core.k8s:
state: present
kubeconfig: "{{ k8s_kubeconfig }}"
definition:
apiVersion: v1
kind: Secret
metadata:
name: cert-manager-webhook-cloudns-api-secret
namespace: cert-manager
type: Opaque
data:
auth_id: "{{ microk8s_cloudns_auth_id | b64encode }}"
auth_password: "{{ microk8s_cloudns_auth_password | b64encode }}"
- name: CertManager | Copy clouDNS issuer manifest to Kubernetes cluster
ansible.builtin.copy:
src: "cert-manager/cloudns-issuer.yaml"
dest: "{{ k8s_etc }}/k8s-certmanager-cloudns.yaml"
mode: "0600"
- name: CertManager | Apply clouDNS issuer manifests
environment:
PATH: "{{ k8s_venv }}/bin:{{ ansible_env.PATH }}"
vars:
ansible_python_interpreter: "{{ k8s_venv }}/bin/python"
kubernetes.core.k8s:
state: present
kubeconfig: "{{ k8s_kubeconfig }}"
src: "{{ k8s_etc }}/k8s-certmanager-cloudns.yaml"
wait: true
+2
View File
@@ -11,3 +11,5 @@ KMS_ACCESS_KEY=$KMS_ACCESS_KEY
KMS_SECRET_KEY=$KMS_SECRET_KEY
KMS_KEY_ARN=$KMS_KEY_ARN
GITEA_APP_TOKEN=$GITEA_APP_TOKEN
CLOUDNS_AUTH_ID=$CLOUDNS_AUTH_ID
CLOUDNS_PASSWORD=$CLOUDNS_PASSWORD
+3
View File
@@ -80,3 +80,6 @@ dev-01.lab.alexpires.me
[mcp]
dev-01.lab.alexpires.me
[certbot]
vh-01.lab.alexpires.me
+5
View File
@@ -20,6 +20,11 @@ locals {
{
fqdn = "${local.lab_domain}"
records = [
{
name = "vh-01"
type = "A"
content = "10.19.4.109"
},
{
name = "gpu-01"
type = "A"
+1 -1
View File
@@ -45,7 +45,7 @@ resource "kubernetes_deployment" "dns" {
}
strategy {
type = "RollingUpdate"
type = "Recreate"
}
template {
+1 -4
View File
@@ -1,8 +1,5 @@
locals {
persistent_folder = var.persistent_folder
app_path = "${local.persistent_folder}/open-webui"
app_version = var.tag
app_fqdn = var.fqdn
openwebui_data = "${local.persistent_folder}/open-webui"
}
+8 -27
View File
@@ -13,28 +13,6 @@ resource "kubernetes_service_account" "openwebui" {
automount_service_account_token = false
}
resource "kubernetes_manifest" "internal_cert" {
manifest = {
apiVersion = "cert-manager.io/v1"
kind = "Certificate"
metadata = {
name = "internal-cert"
namespace = kubernetes_namespace.openwebui.metadata[0].name
}
spec = {
secretName = "internal-cert"
issuerRef = {
name = var.issuer
kind = "ClusterIssuer"
}
commonName = var.fqdn
dnsNames = [var.fqdn]
}
}
}
resource "kubernetes_deployment" "openwebui" {
metadata {
name = "openwebui"
@@ -70,7 +48,7 @@ resource "kubernetes_deployment" "openwebui" {
container {
name = "openwebui-container"
image = "ghcr.io/open-webui/open-webui:${local.app_version}"
image = "ghcr.io/open-webui/open-webui:${var.tag}"
security_context {
allow_privilege_escalation = false
@@ -99,7 +77,7 @@ resource "kubernetes_deployment" "openwebui" {
volume {
name = "openwebui-data"
host_path {
path = local.app_path
path = local.openwebui_data
}
}
}
@@ -140,16 +118,19 @@ resource "kubernetes_ingress_v1" "openwebui" {
namespace = kubernetes_namespace.openwebui.metadata[0].name
annotations = {
"kubernetes.io/ingress.class" = "public"
"cert-manager.io/cluster-issuer" = "letsencrypt-prod"
"kubernetes.io/tls-acme" = "true"
"nginx.ingress.kubernetes.io/ssl-redirect" = "true"
}
}
spec {
tls {
hosts = [local.app_fqdn]
secret_name = "internal-cert"
hosts = [var.fqdn]
secret_name = "openwebui-tls"
}
rule {
host = local.app_fqdn
host = var.fqdn
http {
path {
backend {