--- # Drops a HelmChart CR for cert-manager, plus a ClusterIssuer and the DNS # credentials it solves with, into k3s's auto-deploying manifests directory; # k3s's bundled helm-controller and deploy controller reconcile them — same # mechanism and same two-manifest shape as roles/k3s_metallb (chart CR + # plain config manifest referencing CRDs the chart hasn't installed yet). # # The ClusterIssuer is exactly that case: cert-manager.io/v1 doesn't exist # until the chart has installed, so this manifest is unappliable at the # moment it's written. That's fine and deliberate — k3s's deploy controller # retries a manifest referencing not-yet-existing CRDs until they show up, # rather than failing once and giving up. - name: Fail fast if cert-manager is not configured ansible.builtin.assert: that: - k3s_cert_manager_acme_email | length > 0 - k3s_cert_manager_solver | length > 0 fail_msg: >- k3s_cert_manager_acme_email and/or k3s_cert_manager_solver are unset — set both in inventory/group_vars/k3s_cluster.yml before running playbooks/k3s.yml. An ACME account is registered against the email, and without a solver the ClusterIssuer would be created but never able to prove domain control, leaving every Certificate pending indefinitely rather than failing loudly. quiet: true run_once: true - name: Deploy the cert-manager HelmChart manifest ansible.builtin.template: src: cert-manager.helmchart.yaml.j2 dest: /var/lib/rancher/k3s/server/manifests/cert-manager.yaml owner: root group: root mode: "0644" become: true # Before the ClusterIssuer, because that's what references it. Ordering # between files isn't actually enforced (see the header) — this is for the # reader, not the controller. - name: Look up the DNS provider credentials from Vault when: k3s_cert_manager_vault_path | length > 0 ansible.builtin.set_fact: cert_manager_vault_secrets: >- {{ lookup('community.hashi_vault.vault_kv2_get', k3s_cert_manager_vault_path, engine_mount_point=vault_kv_mount, url=vault_addr, auth_method=vault_auth_method, role_id=vault_role_id | default(omit), secret_id=vault_secret_id | default(omit)).secret }} no_log: true # Separate file and mode from everything else here, same split # roles/k3s_postgres makes: this is the only manifest carrying a credential, # so it's the only one that isn't safe at 0644. - name: Deploy the DNS provider credentials Secret when: k3s_cert_manager_vault_path | length > 0 ansible.builtin.template: src: dns-credentials.yaml.j2 dest: /var/lib/rancher/k3s/server/manifests/cert-manager-dns-credentials.yaml owner: root group: root mode: "0600" become: true no_log: true - name: Deploy the ClusterIssuer manifest ansible.builtin.template: src: cluster-issuer.yaml.j2 dest: /var/lib/rancher/k3s/server/manifests/cert-manager-cluster-issuer.yaml owner: root group: root mode: "0644" become: true