From 95a191ac68c38232e7bd8dfbd49d39358d14cb13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98ystein=20Bedin?= Date: Fri, 11 Sep 2020 11:45:55 -0600 Subject: [PATCH] Cert Management: Adding OCP v4 templates for use with OpenShift Applier (#403) * Adding OCP v4 templates for use with OpenShift Applier * Fixing Typo * Updated filestructure * Updated filestructure * Updated filestructure * Updated namespaces * Fixing namespace template processing * Updating README with references to the new OpenShift template based approach * Updating README with references to the new OpenShift template based approach * Updating README with references to the new OpenShift template based approach --- .../.applier/group_vars/seed-hosts.yml | 53 ++++++++ .../.applier/host_vars/localhost.yml | 3 + cert-manager-configs/.applier/hosts | 3 + .../.openshift/cert-manager.yml | 56 +++++++++ .../.openshift/cert-utils-operator.yml | 30 +++++ .../.openshift/ocpv4-certs.yml | 116 ++++++++++++++++++ cert-manager-configs/README.md | 59 ++++++++- 7 files changed, 317 insertions(+), 3 deletions(-) create mode 100644 cert-manager-configs/.applier/group_vars/seed-hosts.yml create mode 100644 cert-manager-configs/.applier/host_vars/localhost.yml create mode 100644 cert-manager-configs/.applier/hosts create mode 100644 cert-manager-configs/.openshift/cert-manager.yml create mode 100644 cert-manager-configs/.openshift/cert-utils-operator.yml create mode 100644 cert-manager-configs/.openshift/ocpv4-certs.yml diff --git a/cert-manager-configs/.applier/group_vars/seed-hosts.yml b/cert-manager-configs/.applier/group_vars/seed-hosts.yml new file mode 100644 index 000000000..64e4a0d24 --- /dev/null +++ b/cert-manager-configs/.applier/group_vars/seed-hosts.yml @@ -0,0 +1,53 @@ +--- + +openshift_templates_url: "https://raw.githubusercontent.com/redhat-cop/openshift-templates" +openshift_templates_version: "master" + +openshift_domain: "my.cluster.example.com" +cert_mgmt_namespace: "cert-mgmt" + +cert_mgmt_namespace_params: + NAMESPACE: "{{ cert_mgmt_namespace }}" + NAMESPACE_DISPLAY_NAME: "Certificate Management Namespace" + NAMESPACE_DESCRIPTION: "Where a cluster certificate management is hosted" + +cert_manager_params: + NAMESPACE: "{{ cert_mgmt_namespace }}" + DNS_DOMAIN: "{{ openshift_domain }}" + AWS_ACCESS_KEY_ID: "ASDF321ADF63" + AWS_SECRET_ACCESS_KEY: "$#%DASFSDF#24SRT@#$DFFSVSDFG@#$@#$==" + ACME_EMAIL: "my-email@example.com" + +cert_utils_operator_params: + NAMESPACE: "{{ cert_mgmt_namespace }}" + +openshift_cert_params: + DNS_DOMAIN: "{{ openshift_domain }}" + +openshift_cluster_content: +- object: namespace + content: + - name: CertMgmtNamespace + template: "{{ openshift_templates_url }}/{{ openshift_templates_version }}/project-requests/create-project.yml" + params_from_vars: "{{ cert_mgmt_namespace_params }}" + action: create +- object: CertificateManagement + content: + - name: CertManager + template: "{{ inventory_dir }}/../.openshift/cert-manager.yml" + params_from_vars: "{{ cert_manager_params }}" + namespace: "{{ cert_mgmt_namespace }}" + tags: + - cert-manager + - name: CertUtilsOperator + template: "{{ inventory_dir }}/../.openshift/cert-utils-operator.yml" + params_from_vars: "{{ cert_utils_operator_params }}" + namespace: "{{ cert_mgmt_namespace }}" + tags: + - cert-utils-operator + - name: OCPv4-Certs + template: "{{ inventory_dir }}/../.openshift/ocpv4-certs.yml" + params_from_vars: "{{ openshift_cert_params }}" + # namespace: ... No namespace here - it will break the implementation + tags: + - ocpv4-certs diff --git a/cert-manager-configs/.applier/host_vars/localhost.yml b/cert-manager-configs/.applier/host_vars/localhost.yml new file mode 100644 index 000000000..cb8d9aa13 --- /dev/null +++ b/cert-manager-configs/.applier/host_vars/localhost.yml @@ -0,0 +1,3 @@ +--- + +ansible_connection: local diff --git a/cert-manager-configs/.applier/hosts b/cert-manager-configs/.applier/hosts new file mode 100644 index 000000000..9c51ac6f0 --- /dev/null +++ b/cert-manager-configs/.applier/hosts @@ -0,0 +1,3 @@ + +[seed-hosts] +localhost diff --git a/cert-manager-configs/.openshift/cert-manager.yml b/cert-manager-configs/.openshift/cert-manager.yml new file mode 100644 index 000000000..52a580478 --- /dev/null +++ b/cert-manager-configs/.openshift/cert-manager.yml @@ -0,0 +1,56 @@ +--- +kind: Template +apiVersion: v1 +metadata: + annotations: + description: Cert Manager Deployment to support Acme Certificates + name: cert-manager-template +labels: + template: cert-manager-template +objects: + - kind: Secret + apiVersion: v1 + data: + aws-secret-access-key: ${AWS_SECRET_ACCESS_KEY} + metadata: + name: aws-secret-access-key-secret + type: Opaque + - kind: ClusterIssuer + apiVersion: cert-manager.io/v1alpha2 + metadata: + name: "${NAME}-production" + spec: + acme: + email: "${ACME_EMAIL}" + server: https://acme-v02.api.letsencrypt.org/directory + privateKeySecretRef: + name: letsencrypt-account-private-key + solvers: + - selector: + dnsZones: + - "${DNS_DOMAIN}" + dns01: + route53: + region: ${AWS_REGION} + accessKeyID: ${AWS_ACCESS_KEY_ID} + secretAccessKeySecretRef: + name: "aws-secret-access-key-secret" + key: "aws-secret-access-key" +parameters: + - name: NAME + description: Name of the Deployment + value: letsencrypt + - name: NAMESPACE + value: cert-mgmt + - name: DNS_DOMAIN + description: The DNS domain whereas the certificates are to be created + required: true + - name: AWS_REGION + value: us-east-1 + required: true + - name: AWS_ACCESS_KEY_ID + required: true + - name: AWS_SECRET_ACCESS_KEY + required: true + - name: ACME_EMAIL + required: true diff --git a/cert-manager-configs/.openshift/cert-utils-operator.yml b/cert-manager-configs/.openshift/cert-utils-operator.yml new file mode 100644 index 000000000..a8bf37f90 --- /dev/null +++ b/cert-manager-configs/.openshift/cert-utils-operator.yml @@ -0,0 +1,30 @@ +--- +kind: Template +apiVersion: v1 +metadata: + annotations: + description: Cert Manager Deployment to support Acme Certificates + name: cert-utils-operator-template +labels: + template: cert-utils-operator-template +objects: + - kind: OperatorGroup + apiVersion: operators.coreos.com/v1 + metadata: + name: cert-utils + spec: + targetNamespaces: + - ${NAMESPACE} + - kind: Subscription + apiVersion: operators.coreos.com/v1alpha1 + metadata: + name: cert-utils-operator + spec: + channel: alpha + installPlanApproval: Automatic + name: cert-utils-operator + source: community-operators + sourceNamespace: openshift-marketplace +parameters: + - name: NAMESPACE + value: cert-mgmt diff --git a/cert-manager-configs/.openshift/ocpv4-certs.yml b/cert-manager-configs/.openshift/ocpv4-certs.yml new file mode 100644 index 000000000..e45866f55 --- /dev/null +++ b/cert-manager-configs/.openshift/ocpv4-certs.yml @@ -0,0 +1,116 @@ +--- +kind: Template +apiVersion: v1 +metadata: + annotations: + description: OCP v4 Certificate and Configuration to load the certs + name: "${NAME}-certs" +labels: + template: "${NAME}-certs" +objects: + - kind: ConfigMap + apiVersion: v1 + metadata: + name: letsencrypt-ca + namespace: ${LE_CA_NAMESPACE} + data: + ca-bundle.crt: | + -----BEGIN CERTIFICATE----- + MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/ + MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT + DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow + SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT + GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC + AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF + q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8 + SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0 + Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA + a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj + /PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T + AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG + CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv + bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k + c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw + VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC + ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz + MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu + Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF + AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo + uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/ + wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu + X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG + PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6 + KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg== + -----END CERTIFICATE----- + - kind: Certificate + apiVersion: cert-manager.io/v1alpha2 + metadata: + name: "api-${NAME}-cert" + namespace: ${API_CERT_NAMESPACE} + spec: + secretName: "api-${NAME}-cert" + issuerRef: + name: letsencrypt-production + kind: ClusterIssuer + dnsNames: + - "api.${DNS_DOMAIN}" + - kind: Certificate + apiVersion: cert-manager.io/v1alpha2 + metadata: + name: ingress-${NAME}-cert + namespace: ${INGRESS_CERT_NAMESPACE} + spec: + secretName: "ingress-${NAME}-cert" + issuerRef: + name: letsencrypt-production + kind: ClusterIssuer + dnsNames: + - "*.apps.${DNS_DOMAIN}" + - kind: APIServer + apiVersion: config.openshift.io/v1 + metadata: + name: cluster + spec: + servingCerts: + namedCertificates: + - names: + - "api.${DNS_DOMAIN}" + servingCertificate: + name: "api-${NAME}-cert" + - kind: IngressController + apiVersion: operator.openshift.io/v1 + metadata: + name: default + namespace: ${INGRESS_OPERATOR_NAMESPACE} + spec: + defaultCertificate: + name: "ingress-${NAME}-cert" + - kind: Proxy + apiVersion: config.openshift.io/v1 + metadata: + name: cluster + spec: + trustedCA: + name: letsencrypt-ca +parameters: + - name: NAME + description: Name of the Deployment + value: letsencrypt + - name: DNS_DOMAIN + description: The DNS domain to use for the certificate + required: true + - name: LE_CA_NAMESPACE + description: The namespace used for LE CA + value: openshift-config + - name: LE_CA_NAMESPACE + description: The namespace used for LE CA + value: openshift-config + - name: API_CERT_NAMESPACE + description: The namespace used for the API Cert + value: openshift-config + - name: INGRESS_CERT_NAMESPACE + description: The namespace used for the Ingress Cert + value: openshift-ingress + - name: INGRESS_OPERATOR_NAMESPACE + description: The namespace used for the Ingress Operator + value: openshift-ingress-operator diff --git a/cert-manager-configs/README.md b/cert-manager-configs/README.md index 8195af5bd..e5ebf1978 100644 --- a/cert-manager-configs/README.md +++ b/cert-manager-configs/README.md @@ -1,12 +1,14 @@ # cert-manager-openshift-install +## Helm Templates Approach + This helm chart is meant to provide auto-renewing Let's Encrypt on your `api` and `*.apps` endpoints on Openshift. **This requires ClusterAdmin privileges** to an OCP 4.x cluster as you will be installing CRDs and touching critical networking pieces. You will also need to be able control your DNS to create the ACME challenges if using the dns01 provider. It is recommended that you do not enable the `cluster.apiServer` and `cluster.ingressController` resources until you have successfully installed cert-manager and configured your issuers to generate valid certs. In Openshift 3.x these certs live in the filesystem -## Install cert-manager and CRDs +### Install cert-manager and CRDs Install cert-manager following the [installation instructions for Helm v3](https://cert-manager.io/docs/installation/kubernetes/#steps): @@ -27,7 +29,7 @@ We are using v0.15.0 due to a bug in v0.15.1 at the moment. Future releases may Note the dns01-recursive-nameservers option above is required in most cases for Route53. By default, cert-manager will check dns with /etc/resolv.conf before creating a CertificateRequest, which is undesirable if your node is not pointed to public DNS nameservers. -## Install ClusterIssuer/Issuer and Certificates +### Install ClusterIssuer/Issuer and Certificates Once cert-manager is up and running, use helm to install to install your issuers, create certificates, and point your APIServer and IngressController to the automatically renewable certificates: @@ -38,7 +40,7 @@ While the cert-manager install can be done with mostly default values, these con helm template cert-manager-configs -f charts/cert-manager-configs/values.yaml ./charts/cert-manager-configs | oc apply -f - ``` -## Configuration +### Configuration See comments in [values.yaml](./values.yaml) for more details on configuration @@ -71,3 +73,54 @@ See comments in [values.yaml](./values.yaml) for more details on configuration | `cluster.apiServer.tlsSecret` | APIServer secret name created in `certificates.apiServer.name` | `api-letsencrypt-cert` | | `cluster.ingressController.enabled` | Enable ACME wildcard IngressController certificates | `false` | | `cluster.caBundle` | Get latest Let's Encrypt CA and drop it here | `''` | + + +## OpenShift Templates & OpenShift Applier Approach + +This sections covers how an approach with OpenShift Templates, and perhaps [https://github.com/redhat-cop/openshift-applier](openshift-applier) can be done. + + +### Install cert-manager and CRDs + +**Note**: This is still leveraging helm for the time being, but could be templetized with OpenShift Templates if desire. + +Install cert-manager following the [installation instructions for Helm v3](https://cert-manager.io/docs/installation/kubernetes/#steps): + +```bash +oc new-project cert-manager + +helm repo add jetstack https://charts.jetstack.io +helm repo update +helm install \ + cert-manager jetstack/cert-manager \ + --namespace cert-manager \ + --version v0.15.0 \ + --set installCRDs=true \ + --set 'extraArgs={--dns01-recursive-nameservers=8.8.8.8:53\,1.1.1.1:53}' +``` + +We are using v0.15.0 due to a bug in v0.15.1 at the moment. Future releases may install cert-manager from the OperatorHub cert-manager operator. + +Note the dns01-recursive-nameservers option above is required in most cases for Route53. By default, cert-manager will check dns with /etc/resolv.conf before creating a CertificateRequest, which is undesirable if your node is not pointed to public DNS nameservers. + +### Installing Environment Specific Configuration + +This is done by running the `openshift-applier` playbook. Make sure to update the [inventory](.applier/group_vars/seed-hosts.yml) with the proper values (see `Configuration` below) and then run the following command: + +``` +cd +git clone https://github.com/redhat-cop/openshift-applier.git +cd openshift-applier +ansible-playbook -i ../.applier/inventory playbooks/openshift-cluster-seed.yml +``` + + +### Configuration + +| Parameter | Description | Default | +| ------------------------------------------------ | -------------------------------------------------------------| ------------------------------------- | +| `cert_mgmt_namespace` | Project name to install the certificate management components | `cert-mgmt` | +| `openshift_domain` | The sub-domain to use for the installation (e.g.: my.ocp.domain.com) | \ | +| `cert_manager_params.AWS_ACCESS_KEY_ID` | The Access Key Id for the account used in AWS to manage DNS records for the above domain. | \ | +| `cert_manager_params.AWS_SECRET_ACCESS_KEY` | The Secret Access Key for the account used in AWS to manage DNS records for the above domain. **Note**: this is a base64 encoded value. | \ | +| `cert_manager_params.ACME_EMAIL` | The e-mail address used for the Let's Encrypt Certificate. | \ |