# Deploy a per-cluster cert-manager local kube = import "../../../kube/kube.libsonnet"; { local cm = self, Environment: { local env = self, local cfg = env.cfg, cfg:: { namespace: "cert-manager", leaderElectionNamespace: "kube-system", enableWebhook: false, version: "v1.5.0", }, metadata:: { namespace: cfg.namespace, }, namespace: kube.Namespace(cfg.namespace) { metadata+: { labels: { "certmanager.k8s.io/disable-validation": "true" }, }, }, sas: { cainjector: kube.ServiceAccount("cert-manager-cainjector") { metadata+: env.metadata, }, webhook: kube.ServiceAccount("cert-manager-webhook") { metadata+: env.metadata, }, certManager: kube.ServiceAccount("cert-manager") { metadata+: env.metadata, }, }, crds: (std.native("parseYaml"))(importstr "./cert-manager.crds.yaml"), rbac: (import "./cert-manager-rbac.libsonnet") { env:: env, sas:: env.sas, }, deployments: { cainjector: kube.Deployment("cert-manager-cainjector") { metadata+: env.metadata, spec+: { replicas: 1, template+: { spec+: { serviceAccountName: env.sas.cainjector.metadata.name, containers_: { cainjector: kube.Container("cainjector") { image: "quay.io/jetstack/cert-manager-cainjector:" + cfg.version, args: [ "--v=2", "--leader-election-namespace=%s" % [cfg.leaderElectionNamespace], ], env_: { POD_NAMESPACE: kube.FieldRef("metadata.namespace"), }, }, }, }, }, }, }, webhook: kube.Deployment("cert-manager-webhook") { metadata+: env.metadata { labels: { app: "webhook", }, }, spec+: { replicas: if cfg.enableWebhook then 1 else 0, template+: { spec+: { serviceAccountName: env.sas.webhook.metadata.name, containers_: { webhook: kube.Container("webhook") { image: "quay.io/jetstack/cert-manager-webhook:" + cfg.version, args: [ "--v=2", "--secure-port=10250", "--dynamic-serving-ca-secret-namespace=$(POD_NAMESPACE)", "--dynamic-serving-ca-secret-name=cert-manager-webhook-ca", "--dynamic-serving-dns-names=cert-manager-webhook,cert-manager-webhook.cert-manager,cert-manager-webhook.cert-manager.svc", ], env_: { POD_NAMESPACE: kube.FieldRef("metadata.namespace"), }, ports_: { https: { containerPort: 10250 }, }, }, }, }, }, }, }, certmanager: kube.Deployment("cert-manager") { metadata+: env.metadata, spec+: { replicas: 1, template+: { spec+: { serviceAccountName: env.sas.certManager.metadata.name, dnsPolicy: "None", dnsConfig: { nameservers: ["8.8.8.8"], }, # TODO: liveness probe, readiness probe containers_: { webhook: kube.Container("cert-manager") { image: "quay.io/jetstack/cert-manager-controller:" + cfg.version, args: [ "--v=2", "--cluster-resource-namespace=%s" % [cfg.namespace], "--leader-election-namespace=%s" % [cfg.leaderElectionNamespace], ], env_: { POD_NAMESPACE: kube.FieldRef("metadata.namespace"), }, ports_: { metrics: { containerPort: 9402 }, }, resources: { requests: { cpu: "10m", memory: "32Mi", }, }, }, }, }, }, }, }, }, services: { certmanager: kube.Service("cert-manager") { metadata+: env.metadata, target:: env.deployments.certmanager, spec+: { type: "ClusterIP", ports: [ { name: "tcp-prometheus-servicemonitor", port: 9402, targetPort: 9402, protocol: "TCP"}, ], }, }, webhook: kube.Service("cert-manager-webhook") { metadata+: env.metadata, target:: env.deployments.webhook, spec+: { type: "ClusterIP", ports: [ { name: "https", port: 443, targetPort: 10250, protocol: "TCP" }, ], }, }, }, apiservice: if cfg.enableWebhook then kube._Object("apiregistration.k8s.io/v1beta1", "APIService", "v1beta1.admission.certmanager.k8s.io") { spec+: { version: "v1beta1", group: "admission.certmanager.k8s.io", groupPriorityMinimum: 1000, versionPriority: 15, service: { name: env.service.metadata.name, namespace: cfg.namespace, }, }, }, webhooks: if cfg.enableWebhook then { mutating: kube._Object("admissionregistration.k8s.io/v1", "MutatingWebhookConfiguration", "cert-manager-webhook") { metadata+: { annotations: { "cert-manager.io/inject-ca-from-secret": "%s/cert-manager-webhook-ca" % [cfg.namespace], }, }, webhooks: [ { name: "webhook.cert-manager.io", rules: [ { apiGRoups: ["cert-manager.io", "acme.cert-manager.io"], apiVersions: ["v1"], operations: ["CREATE", "UPDATE"], resources: ["*/*"], } ], admissionReviewVersions: ["v1", "v1beta1"], matchPolicy: "Equivalent", timeoutSeconds: 10, failurePolicy: "Fail", sideEffects: "None", clientConfig: { service: { name: "cert-manager-webhook", namespace: cfg.namespace, path: "/mutate", }, }, } ], }, validating: kube._Object("admissionregistration.k8s.io/v1", "ValidatingWebhookConfiguration", "cert-manager-webhook") { metadata+: { annotations: { "cert-manager.io/inject-ca-from-secret": "%s/cert-manager-webhook-ca" % [cfg.namespace], }, }, // Copied from official yaml webhooks: [ { name: "webhook.cert-manager.io", namespaceSelector: { matchExpressions: [ { key: "cert-manager.io/disable-validation", operator: "NotIn", values: ["true"], }, { key: "name", operator: "NotIn", values: ["cert-manager"], }, ], }, rules: [ { apiGroups: ["cert-manager.io", "acme.cert-manager.io"], apiVersions: ["v1"], operations: ["CREATE", "UPDATE"], resources: ["*/*"], } ], admissionReviewVersions: ["v1", "v1beta1"], matchPolicy: "Equivalent", timeoutSeconds: 10, failurePolicy: "Fail", sideEffects: "None", clientConfig: { service: { name: "cert-manager-webhook", namespace: cfg.namespace, path: "/validate", }, }, }, ], }, }, }, }