543 lines
17 KiB
YAML
543 lines
17 KiB
YAML
---
|
|
# Install cert-manager operator and configure LetsEncrypt certificates.
|
|
#
|
|
# Installs the Red Hat cert-manager operator via OLM, creates a ClusterIssuer
|
|
# for LetsEncrypt with DNS-01 challenges via DNS Made Easy, and provisions
|
|
# certificates for the ingress wildcard and API server.
|
|
|
|
# ------------------------------------------------------------------
|
|
# Step 1: Install cert-manager operator via OLM
|
|
# ------------------------------------------------------------------
|
|
- name: Ensure cert-manager-operator namespace exists
|
|
kubernetes.core.k8s:
|
|
state: present
|
|
definition:
|
|
apiVersion: v1
|
|
kind: Namespace
|
|
metadata:
|
|
name: cert-manager-operator
|
|
|
|
- name: Create OperatorGroup for cert-manager-operator
|
|
kubernetes.core.k8s:
|
|
state: present
|
|
definition:
|
|
apiVersion: operators.coreos.com/v1
|
|
kind: OperatorGroup
|
|
metadata:
|
|
name: cert-manager-operator
|
|
namespace: cert-manager-operator
|
|
spec:
|
|
targetNamespaces:
|
|
- cert-manager-operator
|
|
|
|
- name: Subscribe to cert-manager operator
|
|
kubernetes.core.k8s:
|
|
state: present
|
|
definition:
|
|
apiVersion: operators.coreos.com/v1alpha1
|
|
kind: Subscription
|
|
metadata:
|
|
name: openshift-cert-manager-operator
|
|
namespace: cert-manager-operator
|
|
spec:
|
|
channel: "{{ sno_deploy_certmanager_channel }}"
|
|
installPlanApproval: Automatic
|
|
name: openshift-cert-manager-operator
|
|
source: "{{ sno_deploy_certmanager_source }}"
|
|
sourceNamespace: openshift-marketplace
|
|
|
|
# ------------------------------------------------------------------
|
|
# Step 2: Wait for cert-manager to be ready
|
|
# ------------------------------------------------------------------
|
|
- name: Wait for cert-manager CRDs to be available
|
|
kubernetes.core.k8s_info:
|
|
api_version: apiextensions.k8s.io/v1
|
|
kind: CustomResourceDefinition
|
|
name: certificates.cert-manager.io
|
|
register: __sno_deploy_certmanager_crd
|
|
until: __sno_deploy_certmanager_crd.resources | length > 0
|
|
retries: "{{ (sno_deploy_certmanager_wait_timeout / 10) | int }}"
|
|
delay: 10
|
|
|
|
- name: Wait for cert-manager deployment to be ready
|
|
kubernetes.core.k8s_info:
|
|
api_version: apps/v1
|
|
kind: Deployment
|
|
namespace: cert-manager
|
|
name: cert-manager
|
|
register: __sno_deploy_certmanager_deploy
|
|
until: >-
|
|
__sno_deploy_certmanager_deploy.resources | length > 0 and
|
|
(__sno_deploy_certmanager_deploy.resources[0].status.readyReplicas | default(0)) >= 1
|
|
retries: "{{ (sno_deploy_certmanager_wait_timeout / 10) | int }}"
|
|
delay: 10
|
|
|
|
# ------------------------------------------------------------------
|
|
# Step 3: Create DNS Made Easy API credentials for DNS-01 challenges
|
|
# ------------------------------------------------------------------
|
|
- name: Create DNS Made Easy API credentials secret
|
|
kubernetes.core.k8s:
|
|
state: present
|
|
definition:
|
|
apiVersion: v1
|
|
kind: Secret
|
|
metadata:
|
|
name: dme-api-credentials
|
|
namespace: cert-manager
|
|
type: Opaque
|
|
stringData:
|
|
api-key: "{{ dme_account_key }}"
|
|
secret-key: "{{ dme_account_secret }}"
|
|
no_log: true
|
|
|
|
# ------------------------------------------------------------------
|
|
# Step 4: Deploy DNS Made Easy webhook solver
|
|
# ------------------------------------------------------------------
|
|
- name: Create webhook namespace
|
|
kubernetes.core.k8s:
|
|
state: present
|
|
definition:
|
|
apiVersion: v1
|
|
kind: Namespace
|
|
metadata:
|
|
name: cert-manager-webhook-dnsmadeeasy
|
|
|
|
- name: Create webhook ServiceAccount
|
|
kubernetes.core.k8s:
|
|
state: present
|
|
definition:
|
|
apiVersion: v1
|
|
kind: ServiceAccount
|
|
metadata:
|
|
name: cert-manager-webhook-dnsmadeeasy
|
|
namespace: cert-manager-webhook-dnsmadeeasy
|
|
|
|
- name: Create webhook ClusterRole
|
|
kubernetes.core.k8s:
|
|
state: present
|
|
definition:
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: ClusterRole
|
|
metadata:
|
|
name: cert-manager-webhook-dnsmadeeasy
|
|
rules:
|
|
- apiGroups: [""]
|
|
resources: ["secrets"]
|
|
verbs: ["get", "list", "watch"]
|
|
- apiGroups: ["flowcontrol.apiserver.k8s.io"]
|
|
resources: ["flowschemas", "prioritylevelconfigurations"]
|
|
verbs: ["list", "watch"]
|
|
|
|
- name: Create webhook ClusterRoleBinding
|
|
kubernetes.core.k8s:
|
|
state: present
|
|
definition:
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: ClusterRoleBinding
|
|
metadata:
|
|
name: cert-manager-webhook-dnsmadeeasy
|
|
roleRef:
|
|
apiGroup: rbac.authorization.k8s.io
|
|
kind: ClusterRole
|
|
name: cert-manager-webhook-dnsmadeeasy
|
|
subjects:
|
|
- kind: ServiceAccount
|
|
name: cert-manager-webhook-dnsmadeeasy
|
|
namespace: cert-manager-webhook-dnsmadeeasy
|
|
|
|
- name: Create auth-delegator ClusterRoleBinding for webhook
|
|
kubernetes.core.k8s:
|
|
state: present
|
|
definition:
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: ClusterRoleBinding
|
|
metadata:
|
|
name: cert-manager-webhook-dnsmadeeasy:auth-delegator
|
|
roleRef:
|
|
apiGroup: rbac.authorization.k8s.io
|
|
kind: ClusterRole
|
|
name: system:auth-delegator
|
|
subjects:
|
|
- kind: ServiceAccount
|
|
name: cert-manager-webhook-dnsmadeeasy
|
|
namespace: cert-manager-webhook-dnsmadeeasy
|
|
|
|
- name: Create authentication-reader RoleBinding for webhook
|
|
kubernetes.core.k8s:
|
|
state: present
|
|
definition:
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: RoleBinding
|
|
metadata:
|
|
name: cert-manager-webhook-dnsmadeeasy:webhook-authentication-reader
|
|
namespace: kube-system
|
|
roleRef:
|
|
apiGroup: rbac.authorization.k8s.io
|
|
kind: Role
|
|
name: extension-apiserver-authentication-reader
|
|
subjects:
|
|
- kind: ServiceAccount
|
|
name: cert-manager-webhook-dnsmadeeasy
|
|
namespace: cert-manager-webhook-dnsmadeeasy
|
|
|
|
- name: Create domain-solver ClusterRole for cert-manager
|
|
kubernetes.core.k8s:
|
|
state: present
|
|
definition:
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: ClusterRole
|
|
metadata:
|
|
name: cert-manager-webhook-dnsmadeeasy:domain-solver
|
|
rules:
|
|
- apiGroups: ["{{ sno_deploy_webhook_group_name }}"]
|
|
resources: ["*"]
|
|
verbs: ["create"]
|
|
|
|
- name: Bind domain-solver to cert-manager ServiceAccount
|
|
kubernetes.core.k8s:
|
|
state: present
|
|
definition:
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: ClusterRoleBinding
|
|
metadata:
|
|
name: cert-manager-webhook-dnsmadeeasy:domain-solver
|
|
roleRef:
|
|
apiGroup: rbac.authorization.k8s.io
|
|
kind: ClusterRole
|
|
name: cert-manager-webhook-dnsmadeeasy:domain-solver
|
|
subjects:
|
|
- kind: ServiceAccount
|
|
name: cert-manager
|
|
namespace: cert-manager
|
|
|
|
- name: Create self-signed Issuer for webhook TLS
|
|
kubernetes.core.k8s:
|
|
state: present
|
|
definition:
|
|
apiVersion: cert-manager.io/v1
|
|
kind: Issuer
|
|
metadata:
|
|
name: cert-manager-webhook-dnsmadeeasy-selfsign
|
|
namespace: cert-manager-webhook-dnsmadeeasy
|
|
spec:
|
|
selfSigned: {}
|
|
|
|
- name: Create webhook TLS certificate
|
|
kubernetes.core.k8s:
|
|
state: present
|
|
definition:
|
|
apiVersion: cert-manager.io/v1
|
|
kind: Certificate
|
|
metadata:
|
|
name: cert-manager-webhook-dnsmadeeasy-tls
|
|
namespace: cert-manager-webhook-dnsmadeeasy
|
|
spec:
|
|
secretName: cert-manager-webhook-dnsmadeeasy-tls
|
|
duration: 8760h
|
|
renewBefore: 720h
|
|
issuerRef:
|
|
name: cert-manager-webhook-dnsmadeeasy-selfsign
|
|
kind: Issuer
|
|
dnsNames:
|
|
- cert-manager-webhook-dnsmadeeasy
|
|
- cert-manager-webhook-dnsmadeeasy.cert-manager-webhook-dnsmadeeasy
|
|
- cert-manager-webhook-dnsmadeeasy.cert-manager-webhook-dnsmadeeasy.svc
|
|
|
|
- name: Deploy webhook solver
|
|
kubernetes.core.k8s:
|
|
state: present
|
|
definition:
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: cert-manager-webhook-dnsmadeeasy
|
|
namespace: cert-manager-webhook-dnsmadeeasy
|
|
spec:
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
app: cert-manager-webhook-dnsmadeeasy
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: cert-manager-webhook-dnsmadeeasy
|
|
spec:
|
|
serviceAccountName: cert-manager-webhook-dnsmadeeasy
|
|
containers:
|
|
- name: webhook
|
|
image: "{{ sno_deploy_webhook_image }}"
|
|
args:
|
|
- --tls-cert-file=/tls/tls.crt
|
|
- --tls-private-key-file=/tls/tls.key
|
|
- --secure-port=8443
|
|
ports:
|
|
- containerPort: 8443
|
|
name: https
|
|
protocol: TCP
|
|
env:
|
|
- name: GROUP_NAME
|
|
value: "{{ sno_deploy_webhook_group_name }}"
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /healthz
|
|
port: https
|
|
scheme: HTTPS
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 10
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /healthz
|
|
port: https
|
|
scheme: HTTPS
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 10
|
|
resources:
|
|
requests:
|
|
cpu: 10m
|
|
memory: 32Mi
|
|
limits:
|
|
memory: 64Mi
|
|
volumeMounts:
|
|
- name: certs
|
|
mountPath: /tls
|
|
readOnly: true
|
|
volumes:
|
|
- name: certs
|
|
secret:
|
|
secretName: cert-manager-webhook-dnsmadeeasy-tls
|
|
|
|
- name: Create webhook Service
|
|
kubernetes.core.k8s:
|
|
state: present
|
|
definition:
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: cert-manager-webhook-dnsmadeeasy
|
|
namespace: cert-manager-webhook-dnsmadeeasy
|
|
spec:
|
|
type: ClusterIP
|
|
ports:
|
|
- port: 443
|
|
targetPort: https
|
|
protocol: TCP
|
|
name: https
|
|
selector:
|
|
app: cert-manager-webhook-dnsmadeeasy
|
|
|
|
- name: Register webhook APIService
|
|
kubernetes.core.k8s:
|
|
state: present
|
|
definition:
|
|
apiVersion: apiregistration.k8s.io/v1
|
|
kind: APIService
|
|
metadata:
|
|
name: "v1alpha1.{{ sno_deploy_webhook_group_name }}"
|
|
spec:
|
|
group: "{{ sno_deploy_webhook_group_name }}"
|
|
groupPriorityMinimum: 1000
|
|
versionPriority: 15
|
|
service:
|
|
name: cert-manager-webhook-dnsmadeeasy
|
|
namespace: cert-manager-webhook-dnsmadeeasy
|
|
version: v1alpha1
|
|
insecureSkipTLSVerify: true
|
|
|
|
- name: Wait for webhook deployment to be ready
|
|
kubernetes.core.k8s_info:
|
|
api_version: apps/v1
|
|
kind: Deployment
|
|
namespace: cert-manager-webhook-dnsmadeeasy
|
|
name: cert-manager-webhook-dnsmadeeasy
|
|
register: __sno_deploy_webhook_deploy
|
|
until: >-
|
|
__sno_deploy_webhook_deploy.resources | length > 0 and
|
|
(__sno_deploy_webhook_deploy.resources[0].status.readyReplicas | default(0)) >= 1
|
|
retries: 30
|
|
delay: 10
|
|
|
|
# ------------------------------------------------------------------
|
|
# Step 5: Create ClusterIssuer for LetsEncrypt
|
|
# ------------------------------------------------------------------
|
|
- name: Create LetsEncrypt ClusterIssuer
|
|
kubernetes.core.k8s:
|
|
state: present
|
|
definition:
|
|
apiVersion: cert-manager.io/v1
|
|
kind: ClusterIssuer
|
|
metadata:
|
|
name: letsencrypt-production
|
|
spec:
|
|
acme:
|
|
email: "{{ sno_deploy_letsencrypt_email }}"
|
|
server: "{{ __sno_deploy_letsencrypt_server_url }}"
|
|
privateKeySecretRef:
|
|
name: letsencrypt-production-account-key
|
|
solvers:
|
|
- dns01:
|
|
webhook:
|
|
groupName: "{{ sno_deploy_webhook_group_name }}"
|
|
solverName: dnsmadeeasy
|
|
config:
|
|
apiKeySecretRef:
|
|
name: dme-api-credentials
|
|
key: api-key
|
|
secretKeySecretRef:
|
|
name: dme-api-credentials
|
|
key: secret-key
|
|
|
|
- name: Wait for ClusterIssuer to be ready
|
|
kubernetes.core.k8s_info:
|
|
api_version: cert-manager.io/v1
|
|
kind: ClusterIssuer
|
|
name: letsencrypt-production
|
|
register: __sno_deploy_clusterissuer
|
|
until: >-
|
|
__sno_deploy_clusterissuer.resources | length > 0 and
|
|
(__sno_deploy_clusterissuer.resources[0].status.conditions | default([])
|
|
| selectattr('type', '==', 'Ready')
|
|
| selectattr('status', '==', 'True') | list | length > 0)
|
|
retries: 12
|
|
delay: 10
|
|
|
|
# ------------------------------------------------------------------
|
|
# Step 6: Create Certificate resources
|
|
# ------------------------------------------------------------------
|
|
- name: Create apps wildcard certificate
|
|
kubernetes.core.k8s:
|
|
state: present
|
|
definition:
|
|
apiVersion: cert-manager.io/v1
|
|
kind: Certificate
|
|
metadata:
|
|
name: apps-wildcard-cert
|
|
namespace: openshift-ingress
|
|
spec:
|
|
secretName: apps-wildcard-tls
|
|
issuerRef:
|
|
name: letsencrypt-production
|
|
kind: ClusterIssuer
|
|
dnsNames:
|
|
- "{{ __sno_deploy_apps_wildcard }}"
|
|
duration: 2160h
|
|
renewBefore: 720h
|
|
|
|
- name: Create API server certificate
|
|
kubernetes.core.k8s:
|
|
state: present
|
|
definition:
|
|
apiVersion: cert-manager.io/v1
|
|
kind: Certificate
|
|
metadata:
|
|
name: api-server-cert
|
|
namespace: openshift-config
|
|
spec:
|
|
secretName: api-server-tls
|
|
issuerRef:
|
|
name: letsencrypt-production
|
|
kind: ClusterIssuer
|
|
dnsNames:
|
|
- "{{ __sno_deploy_api_hostname }}"
|
|
duration: 2160h
|
|
renewBefore: 720h
|
|
|
|
# ------------------------------------------------------------------
|
|
# Step 7: Wait for certificates to be issued
|
|
# ------------------------------------------------------------------
|
|
- name: Wait for apps wildcard certificate to be ready
|
|
kubernetes.core.k8s_info:
|
|
api_version: cert-manager.io/v1
|
|
kind: Certificate
|
|
namespace: openshift-ingress
|
|
name: apps-wildcard-cert
|
|
register: __sno_deploy_apps_cert
|
|
until: >-
|
|
__sno_deploy_apps_cert.resources | length > 0 and
|
|
(__sno_deploy_apps_cert.resources[0].status.conditions | default([])
|
|
| selectattr('type', '==', 'Ready')
|
|
| selectattr('status', '==', 'True') | list | length > 0)
|
|
retries: "{{ (sno_deploy_certificate_wait_timeout / 10) | int }}"
|
|
delay: 10
|
|
|
|
- name: Wait for API server certificate to be ready
|
|
kubernetes.core.k8s_info:
|
|
api_version: cert-manager.io/v1
|
|
kind: Certificate
|
|
namespace: openshift-config
|
|
name: api-server-cert
|
|
register: __sno_deploy_api_cert
|
|
until: >-
|
|
__sno_deploy_api_cert.resources | length > 0 and
|
|
(__sno_deploy_api_cert.resources[0].status.conditions | default([])
|
|
| selectattr('type', '==', 'Ready')
|
|
| selectattr('status', '==', 'True') | list | length > 0)
|
|
retries: "{{ (sno_deploy_certificate_wait_timeout / 10) | int }}"
|
|
delay: 10
|
|
|
|
# ------------------------------------------------------------------
|
|
# Step 8: Patch IngressController and APIServer to use the certs
|
|
# ------------------------------------------------------------------
|
|
- name: Patch default IngressController to use LetsEncrypt cert
|
|
kubernetes.core.k8s:
|
|
state: present
|
|
merge_type: merge
|
|
definition:
|
|
apiVersion: operator.openshift.io/v1
|
|
kind: IngressController
|
|
metadata:
|
|
name: default
|
|
namespace: openshift-ingress-operator
|
|
spec:
|
|
defaultCertificate:
|
|
name: apps-wildcard-tls
|
|
|
|
- name: Patch APIServer to use LetsEncrypt cert
|
|
kubernetes.core.k8s:
|
|
state: present
|
|
merge_type: merge
|
|
definition:
|
|
apiVersion: config.openshift.io/v1
|
|
kind: APIServer
|
|
metadata:
|
|
name: cluster
|
|
spec:
|
|
servingCerts:
|
|
namedCertificates:
|
|
- names:
|
|
- "{{ __sno_deploy_api_hostname }}"
|
|
servingCertificate:
|
|
name: api-server-tls
|
|
|
|
# ------------------------------------------------------------------
|
|
# Step 9: Wait for rollouts
|
|
# ------------------------------------------------------------------
|
|
- name: Wait for API server to begin restart
|
|
ansible.builtin.pause:
|
|
seconds: 30
|
|
|
|
- name: Wait for router pods to restart with new cert
|
|
kubernetes.core.k8s_info:
|
|
api_version: apps/v1
|
|
kind: Deployment
|
|
namespace: openshift-ingress
|
|
name: router-default
|
|
register: __sno_deploy_router
|
|
until: >-
|
|
__sno_deploy_router.resources is defined and
|
|
__sno_deploy_router.resources | length > 0 and
|
|
(__sno_deploy_router.resources[0].status.updatedReplicas | default(0)) ==
|
|
(__sno_deploy_router.resources[0].status.replicas | default(1)) and
|
|
(__sno_deploy_router.resources[0].status.readyReplicas | default(0)) ==
|
|
(__sno_deploy_router.resources[0].status.replicas | default(1))
|
|
retries: 60
|
|
delay: 10
|
|
|
|
- name: Display cert-manager configuration summary
|
|
ansible.builtin.debug:
|
|
msg:
|
|
- "cert-manager configuration complete!"
|
|
- " ClusterIssuer : letsencrypt-production"
|
|
- " Apps wildcard : {{ __sno_deploy_apps_wildcard }}"
|
|
- " API cert : {{ __sno_deploy_api_hostname }}"
|
|
verbosity: 1
|