--- # tasks file for certificates # Tasks to create a CA and Certificates for the Kubernetes cluster # The CA will be my NFS server host in this use case. # I did find that using the openssl_csr module, the key_usage options did not like a comma # seperated list, but the YAML list did work. # I got an error: # "Cannot parse Subject Alternative Name \" IP:192.168.50.240\" (potentially unsupported by cryptography backend)" # This was due to spaces between the comman sperated values in the subject_alt_name option in the openssl_csr module ########################################## ## CREATE CA ## ########################################## # Create a directory to store certs - name: Create certs directory for storing CA stuff file: path: '{{ CA_DIR }}' state: directory tags: - certficates - ca when: inventory_hostname == groups['management'][0] # Create the CA private key - name: Generate CA private key openssl_privatekey: path: '{{ CA_DIR }}/ca-key.pem' tags: - certficates - ca when: inventory_hostname == groups['management'][0] # Creates a CSR for the CA # Any CA cert must have the keyCertSign usage option - name: Generate CA CSR openssl_csr: path: '{{ CA_DIR }}/ca.csr' privatekey_path: '{{ CA_DIR }}/ca-key.pem' basic_constraints: 'CA:TRUE' basic_constraints_critical: True key_usage: - cRLSign - keyCertSign key_usage_critical: True organizational_unit_name: kubernetes common_name: kubernetes tags: - certficates - ca when: inventory_hostname == groups['management'][0] # Creare the CA cert from the CSR - name: Generate CA certificate openssl_certificate: path: '{{ CA_DIR }}/ca.pem' privatekey_path: '{{ CA_DIR }}/ca-key.pem' csr_path: '{{ CA_DIR }}/ca.csr' provider: selfsigned tags: - certficates - ca when: inventory_hostname == groups['management'][0] ########################################## ## KUBE ADMIN CERTS ## ########################################## # Create the k8sadmin private key - name: Generate Admin private key openssl_privatekey: path: '{{ CA_DIR }}/admin-key.pem' tags: - certficates - admin_cert when: inventory_hostname == groups['management'][0] # Create admin CSR - name: Generate Admin CSR openssl_csr: path: '{{ CA_DIR }}/admin.csr' privatekey_path: '{{ CA_DIR }}/admin-key.pem' basic_constraints: "CA:FALSE" basic_constraints_critical: True key_usage: - digitalSignature - keyEncipherment key_usage_critical: True extended_key_usage: - serverAuth - clientAuth common_name: k8sadmin organization_name: "system:masters" organizational_unit_name: kubernetes tags: - certficates - admin_cert when: inventory_hostname == groups['management'][0] # Create Admin cert. Using the CSR created above and the ca.pem generated in the first tasks, # can generate the certifiacte for the admin - name: Generate Admin certificate openssl_certificate: path: '{{ CA_DIR }}/admin.pem' csr_path: '{{ CA_DIR }}/admin.csr' ownca_path: '{{ CA_DIR }}/ca.pem' ownca_privatekey_path: '{{ CA_DIR }}/ca-key.pem' provider: ownca tags: - certficates - admin_cert when: inventory_hostname == groups['management'][0] ########################################## ## MASTER CERTS ## ########################################## # Create master keys - name: Generate Masters private key openssl_privatekey: path: '{{ CA_DIR }}/k8smasterkey.pem' tags: - certficates - master_cert - master when: inventory_hostname == groups['management'][0] # Localhost and 127.0.0.1 are added for k8s services on controller nodes to access local k8s API # kubernetes.default is added because it can be used from inside the cluster to access the API # 10.32.0.1 is a well known address used by services and pods in the cluster # Create masters CSR - name: Generate Masters CSR openssl_csr: path: '{{ CA_DIR }}/k8smaster.csr' privatekey_path: '{{ CA_DIR }}/k8smasterkey.pem' common_name: 'k8s-master' basic_constraints: "CA:FALSE" basic_constraints_critical: True key_usage: - digitalSignature - keyEncipherment key_usage_critical: True extended_key_usage: - serverAuth - clientAuth organization_name: 'system:masters' organizational_unit_name: 'kubernetes' subject_alt_name: "DNS:kubernetes.default,IP:{{ groups['masters'][0] }},DNS:{{ k8smaster01_hostname }},IP:{{ groups['load_balancers'][0] }},DNS:{{ load_balancer_hostname }},IP:127.0.0.1,DNS:localhost,IP:{{ APISERVER_SERVICE_IP }}" tags: - certficates - master_cert - master when: inventory_hostname == groups['management'][0] # Create master cert using master CSR and CA.pem - name: Generate Masters certificate openssl_certificate: path: '{{ CA_DIR }}/k8s-master.pem' csr_path: '{{ CA_DIR }}/k8smaster.csr' ownca_path: '{{ CA_DIR }}/ca.pem' ownca_privatekey_path: '{{ CA_DIR }}/ca-key.pem' provider: ownca tags: - certficates - master_cert - master when: inventory_hostname == groups['management'][0] ########################################## ## KUBELET CERTS ## ########################################## # Create worker keys - name: Generate Workers private keys openssl_privatekey: path: '{{ CA_DIR }}/{{ item }}-key.pem' loop: - "{{ k8sworker01_hostname }}" - "{{ k8sworker02_hostname }}" - "{{ k8sworker03_hostname }}" tags: - certficates - worker_cert - worker when: inventory_hostname == groups['management'][0] # Create worker CSRs - name: Generate Workers CSRs openssl_csr: path: '{{ CA_DIR }}/{{ item[0] }}.csr' privatekey_path: '{{ CA_DIR }}/{{ item[0] }}-key.pem' common_name: 'system:node:{{ item[0] }}' basic_constraints: "CA:FALSE" basic_constraints_critical: True key_usage: - digitalSignature - keyEncipherment key_usage_critical: True extended_key_usage: - serverAuth - clientAuth organization_name: 'system:nodes' organizational_unit_name: 'kubernetes' subject_alt_name: 'DNS:{{ item[0] }},IP:{{ item[1] }}' loop: - ["{{ k8sworker01_hostname }}", "{{ k8sworker01_ip }}" ] - ["{{ k8sworker02_hostname }}", "{{ k8sworker02_ip }}" ] - ["{{ k8sworker03_hostname }}", "{{ k8sworker03_ip }}" ] tags: - certficates - worker_cert - worker when: inventory_hostname == groups['management'][0] # Create worker Certs - name: Generate Workers certificates openssl_certificate: path: '{{ CA_DIR }}/{{ item }}.pem' csr_path: '{{ CA_DIR }}/{{ item }}.csr' ownca_path: '{{ CA_DIR }}/ca.pem' ownca_privatekey_path: '{{ CA_DIR }}/ca-key.pem' provider: ownca loop: - "{{ k8sworker01_hostname }}" - "{{ k8sworker02_hostname }}" - "{{ k8sworker03_hostname }}" tags: - certficates - worker_cert - worker when: inventory_hostname == groups['management'][0] ########################################## ## KUBEPROXY CERTS ## ########################################## # Create kubeproxy key - name: Generating Kube Proxy private key openssl_privatekey: path: '{{ CA_DIR }}/kube-proxy-key.pem' tags: - certficates - kubeproxy_cert - kubeproxy when: inventory_hostname == groups['management'][0] # Create kubeproxy CSR - name: Generate Kube Proxy CSR openssl_csr: path: '{{ CA_DIR }}/kube-proxy.csr' privatekey_path: '{{ CA_DIR }}/kube-proxy-key.pem' basic_constraints: "CA:FALSE" basic_constraints_critical: True key_usage: - digitalSignature - keyEncipherment key_usage_critical: True extended_key_usage: - serverAuth - clientAuth common_name: 'system:kube-proxy' organization_name: 'system:node-proxier' organizational_unit_name: 'kubernetes' tags: - certficates - kubeproxy_cert - kubeproxy when: inventory_hostname == groups['management'][0] # Create kubeproxy cert - name: Generate Kube Proxy certificate openssl_certificate: path: '{{ CA_DIR }}/kube-proxy.pem' csr_path: '{{ CA_DIR }}/kube-proxy.csr' ownca_path: '{{ CA_DIR }}/ca.pem' ownca_privatekey_path: '{{ CA_DIR }}/ca-key.pem' provider: ownca tags: - certficates - kubeproxy_cert - kubeproxy when: inventory_hostname == groups['management'][0] ########################################## ## KUBE SCHEDULER CERTS ## ########################################## # Create kube scheduler key - name: Generating Kube scheduler private key openssl_privatekey: path: '{{ CA_DIR }}/kube-scheduler-key.pem' tags: - certficates - kubescheduler_cert - kubescheduler when: inventory_hostname == groups['management'][0] # Create kube scheduler CSR - name: Generate Kube scheduler CSR openssl_csr: path: '{{ CA_DIR }}/kube-scheduler.csr' privatekey_path: '{{ CA_DIR }}/kube-scheduler-key.pem' basic_constraints: "CA:FALSE" basic_constraints_critical: True key_usage: - digitalSignature - keyEncipherment key_usage_critical: True extended_key_usage: - serverAuth - clientAuth common_name: 'system:kube-scheduler' organization_name: 'system:kube-scheduler' organizational_unit_name: 'kubernetes' tags: - certficates - kubescheduler_cert - kubescheduler when: inventory_hostname == groups['management'][0] # Create kube scheduler cert - name: Generate Kube scheduler certificate openssl_certificate: path: '{{ CA_DIR }}/kube-scheduler.pem' csr_path: '{{ CA_DIR }}/kube-scheduler.csr' ownca_path: '{{ CA_DIR }}/ca.pem' ownca_privatekey_path: '{{ CA_DIR }}/ca-key.pem' provider: ownca tags: - certficates - kubescheduler_cert - kubescheduler when: inventory_hostname == groups['management'][0] ########################################## ## KUBE CONTROLLER MANAGER CERTS ## ########################################## # Create kube controller manager key - name: Generating Kube controller-manager private key openssl_privatekey: path: '{{ CA_DIR }}/kube-controller-manager-key.pem' tags: - certficates - kubecontroller_cert - kubecontroller when: inventory_hostname == groups['management'][0] # Create kube controller manager CSR - name: Generate Kube controller-manager CSR openssl_csr: path: '{{ CA_DIR }}/kube-controller-manager.csr' privatekey_path: '{{ CA_DIR }}/kube-controller-manager-key.pem' basic_constraints: "CA:FALSE" basic_constraints_critical: True key_usage: - digitalSignature - keyEncipherment key_usage_critical: True extended_key_usage: - serverAuth - clientAuth common_name: 'system:kube-controller-manager' organization_name: 'system:kube-controller-manager' organizational_unit_name: 'kubernetes' tags: - certficates - kubecontroller_cert - kubecontroller when: inventory_hostname == groups['management'][0] # Create kube controller manager cert - name: Generate Kube controller-manager certificate openssl_certificate: path: '{{ CA_DIR }}/kube-controller-manager.pem' csr_path: '{{ CA_DIR }}/kube-controller-manager.csr' ownca_path: '{{ CA_DIR }}/ca.pem' ownca_privatekey_path: '{{ CA_DIR }}/ca-key.pem' provider: ownca tags: - certficates - kubecontroller_cert - kubecontroller when: inventory_hostname == groups['management'][0] ########################################## ## CREATE SERVICE ACCOUNT KEY PAIR ## ########################################## # This certificate is used to sign service account tokens # Create service-account key - name: Generating service-account private key openssl_privatekey: path: '{{ CA_DIR }}/service-account-key.pem' tags: - certficates - serviceaccount_cert - serviceaccount when: inventory_hostname == groups['management'][0] # Create service-account CSR - name: Generate service-account CSR openssl_csr: path: '{{ CA_DIR }}/service-account.csr' privatekey_path: '{{ CA_DIR }}/service-account-key.pem' basic_constraints: "CA:FALSE" basic_constraints_critical: True key_usage: - digitalSignature - keyEncipherment key_usage_critical: True extended_key_usage: - serverAuth - clientAuth common_name: 'service-accounts' organization_name: 'kubernetes' organizational_unit_name: 'kubernetes' tags: - certficates - serviceaccount_cert - serviceaccount when: inventory_hostname == groups['management'][0] # Create service-account cert - name: Generate service-account certificate openssl_certificate: path: '{{ CA_DIR }}/service-account.pem' csr_path: '{{ CA_DIR }}/service-account.csr' ownca_path: '{{ CA_DIR }}/ca.pem' ownca_privatekey_path: '{{ CA_DIR }}/ca-key.pem' provider: ownca tags: - certficates - serviceaccount_cert - serviceaccount when: inventory_hostname == groups['management'][0] ########################################## ## KUBE DASHBOARD CERTS ## ########################################## # Create dashboard key - name: Generate k8s Dashboard private key openssl_privatekey: path: '{{ CA_DIR }}/k8s-dashboard-key.pem' tags: - certficates - kubedashboard_cert - kubedashboard when: inventory_hostname == groups['management'][0] # Create dashboard CSR - name: Generate k8s Dashboard CSR openssl_csr: path: '{{ CA_DIR }}/k8s-dashboard.csr' privatekey_path: '{{ CA_DIR }}/k8s-dashboard-key.pem' basic_constraints: "CA:FALSE" basic_constraints_critical: True key_usage: - digitalSignature - keyEncipherment key_usage_critical: True extended_key_usage: - serverAuth - clientAuth common_name: 'k8s-Dashboard' organization_name: 'addons:Dashboard' organizational_unit_name: 'kubernetes' tags: - certficates - kubedashboard_cert - kubedashboard when: inventory_hostname == groups['management'][0] # Create dashboard cert - name: Generate k8s Dashboard certificate openssl_certificate: path: '{{ CA_DIR }}/k8s-dashboard.pem' csr_path: '{{ CA_DIR }}/k8s-dashboard.csr' ownca_path: '{{ CA_DIR }}/ca.pem' ownca_privatekey_path: '{{ CA_DIR }}/ca-key.pem' provider: ownca tags: - certficates - kubedashboard_cert - kubedashboard when: inventory_hostname == groups['management'][0] # Create cert bundle for dashboard - name: Generate k8s-dashboard bundle shell: "cat {{ CA_DIR }}/k8s-dashboard.pem {{ CA_DIR }}/k8s-dashboard-key.pem > {{ CA_DIR }}/k8s-dashboard.bundle" args: creates: '{{ CA_DIR }}/k8s-dashboard.bundle' tags: - certficates - kubedashboard_cert - kubedashboard when: inventory_hostname == groups['management'][0] # Create encryption-config #- name: Generate encryption-config.yml # shell: echo "{{ encryption_config }}" > {{ CA_DIR }}/encryption-config.yml # args: # creates: '{{ CA_DIR }}/encryption-config.yml' # tags: # - certficates # - kubedashboard_cert # - kubedashboard # when: inventory_hostname == groups['management'][0] ########################################## ## GATHER CERTS FOR DISTRIBUTION ## ########################################## ########################################## ## WARNING: ADD THIS ROLES /FILES ## ## DIRECTORY TO YOUR .GITIGNORE ## ## OR EVERYONE WILL ## # HAVE YOUR CERTS ## ########################################## - name: Gather the cert files to be fetched find: paths: /root/k8scerts recurse: no patterns: "*" register: files_to_copy tags: - certificates - fetch - distribute when: inventory_hostname == groups['management'][0] - name: Fetch certs from CA and place them into this roles file directory fetch: src: "{{ item.path }}" dest: roles/certificates/files/ flat: yes with_items: "{{ files_to_copy.files }}" tags: - certificates - fetch - distribute when: inventory_hostname == groups['management'][0] - name: Distribute worker01 certs copy: src: "{{ item.src }}" dest: "/home/k8sadmin" with_items: - { src: ca.pem } - { src: k8sworker01-key.pem } - { src: k8sworker01.pem } - { src: kube-proxy.pem } - { src: kube-proxy-key.pem} tags: - certificates - distribute #when: inventory_hostname == groups['workers'][0] when: ansible_hostname == 'k8sworker01' - name: Distribute worker02 certs copy: src: "{{ item.src }}" dest: "/home/k8sadmin" with_items: - { src: ca.pem } - { src: k8sworker02-key.pem } - { src: k8sworker02.pem } - { src: kube-proxy.pem } - { src: kube-proxy-key.pem} tags: - certificates - distribute #when: inventory_hostname == groups['workers'][1] when: ansible_hostname == 'k8sworker02' - name: Distribute worker03 certs copy: src: "{{ item.src }}" dest: "/home/k8sadmin" with_items: - { src: ca.pem } - { src: k8sworker03-key.pem } - { src: k8sworker03.pem } - { src: kube-proxy.pem } - { src: kube-proxy-key.pem} tags: - certificates - distribute #when: inventory_hostname == groups['workers'][2] when: ansible_hostname == 'k8sworker03' - name: Distribute master01 certs copy: src: "{{ item.src }}" dest: "/home/k8sadmin" with_items: - { src: ca.pem } - { src: ca-key.pem } - { src: k8smasterkey.pem } - { src: k8s-master.pem } - { src: service-account-key.pem } - { src: service-account.pem } - { src: kube-controller-manager-key.pem } - { src: kube-controller-manager.pem} - { src: kube-scheduler-key.pem } - { src: kube-scheduler.pem} - { src: admin-key.pem } - { src: admin.pem} tags: - certificates - distribute when: inventory_hostname == groups['masters'][0]