├── .ansible-lint ├── .github └── workflows │ └── release.yml ├── .gitignore ├── .yamllint ├── CHANGELOG.md ├── README.md ├── defaults └── main.yml ├── meta └── main.yml ├── molecule └── default │ ├── converge.yml │ ├── group_vars │ └── all.yml │ ├── host_vars │ ├── test-assets.yml │ ├── test-controller1.yml │ ├── test-controller2.yml │ ├── test-controller3.yml │ ├── test-worker1.yml │ └── test-worker2.yml │ ├── molecule.yml │ ├── prepare.yml │ └── verify.yml ├── tasks └── main.yml └── templates ├── ca-etcd-config.json.j2 ├── ca-etcd-csr.json.j2 ├── ca-k8s-apiserver-config.json.j2 ├── ca-k8s-apiserver-csr.json.j2 ├── cert-admin-csr.json.j2 ├── cert-etcd-client-csr.json.j2 ├── cert-etcd-peer-csr.json.j2 ├── cert-etcd-server-csr.json.j2 ├── cert-k8s-apiserver-csr.json.j2 ├── cert-k8s-controller-manager-csr.json.j2 ├── cert-k8s-controller-manager-sa-csr.json.j2 ├── cert-k8s-proxy-csr.json.j2 ├── cert-k8s-scheduler-csr.json.j2 └── cert-worker-csr.json.j2 /.ansible-lint: -------------------------------------------------------------------------------- 1 | --- 2 | skip_list: 3 | - command-instead-of-shell 4 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # This workflow requires a GALAXY_API_KEY secret present in the GitHub 3 | # repository or organization. 4 | # 5 | # See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy 6 | # See: https://github.com/ansible/galaxy/issues/46 7 | 8 | name: Release 9 | on: 10 | push: 11 | tags: 12 | - '*' 13 | 14 | defaults: 15 | run: 16 | working-directory: 'githubixx.kubernetes_ca' 17 | 18 | jobs: 19 | release: 20 | name: Release 21 | runs-on: ubuntu-latest 22 | steps: 23 | - name: Check out the codebase. 24 | uses: actions/checkout@v2 25 | with: 26 | path: 'githubixx.kubernetes_ca' 27 | 28 | - name: Set up Python 3. 29 | uses: actions/setup-python@v2 30 | with: 31 | python-version: '3.x' 32 | 33 | - name: Install Ansible. 34 | run: pip3 install ansible-core 35 | 36 | - name: Trigger a new import on Galaxy. 37 | run: >- 38 | ansible-galaxy role import --token ${{ secrets.GALAXY_API_KEY }} -vvvvvvvv --role-name=$(echo ${{ github.repository }} | cut -d/ -f2 | sed 's/ansible-role-//' | sed 's/-/_/') $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.retry 3 | -------------------------------------------------------------------------------- /.yamllint: -------------------------------------------------------------------------------- 1 | --- 2 | extends: default 3 | 4 | rules: 5 | line-length: 6 | max: 300 7 | level: warning 8 | 9 | comments-indentation: disable 10 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | ## 12.0.0+1.28.5 4 | 5 | ### BREAKING 6 | 7 | - change default value of `k8s_controller_manager_sa_csr_cn` from `service-accounts` to `k8s-service-accounts` 8 | - change default value of `k8s_interface` from `tap0` to `eth0` 9 | - change default values of `ca_etcd_csr_cn`, `etcd_peer_csr_cn` and `etcd_client_csr_cn_prefix` 10 | - change default value of `k8s_apiserver_csr_cn` from `kubernetes` to `kube-apiserver` 11 | 12 | ### OTHER CHANGES 13 | 14 | - remove tests directory 15 | - add `namespace` to `meta/main.yml` 16 | - update Github workflow 17 | - add important note to `k8s_apiserver_csr_cn` variable 18 | - `.ansible-lint`: remove `role-name` 19 | - remove `vars` directory 20 | - remove `handlers` directory 21 | - remove `files` directory 22 | 23 | ### MOLECULE 24 | 25 | - remove `requirements.yml` 26 | - fix `ansible-lint` issues 27 | - use Ubuntu 22.04 for some VMs 28 | - change IPs from `192.168.10.0/24` to `172.16.10.0/24` 29 | - remove `etcd_cert_hosts` variable from `group_vars` (use default setting) 30 | - remove `role_name_check` 31 | - extend `verify.yml` 32 | - Molecule: rename role `harden-linux` to `harden_linux` 33 | 34 | ## 11.0.0+1.18.4 35 | 36 | - **BREAKING**: `meta/main.yml`: change role_name from `kubernetes-ca` to `kubernetes_ca`. This is a requirement since quite some time for Ansible Galaxy. But the requirement was introduced after this role already existed for quite some time. So please update the name of the role in your playbook accordingly! 37 | - rename `githubixx.kubernetes-ca` to `githubixx.kubernetes_ca` 38 | - `molecule/default/requirements.yml`: remove `githubixx.kubernetes_ca` 39 | - `meta/main.yml`: added `role_name` 40 | - added support for Ubuntu 22.04 41 | - removed support for Ubuntu 16.04 and 18.04 (reached EOL) 42 | 43 | ## 10.0.0+1.18.4 44 | 45 | - add Molecule test 46 | - add `.ansible-lint` 47 | - add '.yamllint` 48 | - add Github workflow 49 | - increase `min_ansible_version` from `2.8` to `2.9` 50 | - rename internal variable `workerHost` to `worker_host` 51 | - rename internal variable `etcdHosts` to `etcd_hosts` 52 | - rename internal variable `k8sApiHosts` to `k8s_api_hosts` 53 | - fix `ansible-lint` issues (use Ansible FQDN module names) 54 | 55 | ## 9.0.0+1.18.4 56 | 57 | - splitted etcd profiles in `server`, `peer` and `client`. This makes it possible to have separate certificate files for `etcd`. E.g. the TLS parameters for `etcd` now looks like this: 58 | 59 | ```plain 60 | --cert-file=cert-etcd-server.pem 61 | --key-file=cert-etcd-server-key.pem 62 | --trusted-ca-file=ca-etcd.pem 63 | --peer-cert-file=cert-etcd-peer.pem 64 | --peer-key-file=cert-etcd-peer-key.pem 65 | --peer-trusted-ca-file=ca-etcd.pem 66 | ``` 67 | 68 | Before this change `cert-file`, `key-file`, `peer-cert-file` and `peer-key-file` used the same certificate files. 69 | 70 | This change makes it also possible to create certificate files for `etcd` clients like `Traefik`, `Cilium` and so on to use the same TLS enabled `etcd` server. As `kube-apiserver` is also an `etcd` client this change also introduced separate certificate files e.g.: 71 | 72 | ```plain 73 | --etcd-cafile=ca-etcd.pem 74 | --etcd-certfile=cert-k8s-apiserver-etcd.pem 75 | --etcd-keyfile=cert-k8s-apiserver-etcd-key.pem 76 | ``` 77 | 78 | - add `localhost` to `etcd_cert_hosts` and `k8s_apiserver_cert_hosts` variables 79 | - rename `etcd_csr_*` variables to `etcd_server_csr_*` 80 | - introduce `etcd_peer_csr_*` variables (see README for more information) 81 | - introduce `etcd_client_csr_*` variables (see README for more information) 82 | - introduce `etcd_additional_clients` variable (see README for more information) 83 | - add Ubuntu 20.04 as supported platform 84 | - increase minimum required Ansible version to 2.8 85 | 86 | ## no changes 87 | 88 | - deleted old tags not compatible with Ansible Galaxy: 89 | 90 | ```plain 91 | r1.0.0_v1.6.0 92 | r1.0.1_v1.8.0 93 | r3.0.0_v1.8.4 94 | r4.0.0_v1.8.4 95 | r4.0.1_v1.8.4 96 | r4.0.1_v1.9.3 97 | r4.0.1_v1.9.8 98 | r5.0.0_v1.10.4 99 | r6.0.0_v1.10.4 100 | ``` 101 | 102 | These versions are outdated anyways. 103 | 104 | ## 8.0.0+1.16.3 105 | 106 | - introduced a few new variables: `k8s_ca_conf_directory_perm`, `k8s_ca_file_perm`, `k8s_ca_controller_nodes_group`, `k8s_ca_etcd_nodes_group`, `k8s_ca_worker_nodes_group`. Values were previously hard coded. They can be adjusted now. 107 | - added `kubernetes.default.svc.cluster` to `k8s_apiserver_cert_hosts` 108 | - removed worker hostnames and IPs from kube-apiserver certificate. They are not needed here. 109 | - better formatting of shell scripts in .yaml files. 110 | - gather facts of K8s hosts as first task 111 | 112 | ## 7.0.0+1.12.3 113 | 114 | - use correct semantic versioning as described in [semver](https://semver.org). Needed for Ansible Galaxy importer as it now insists on using semantic versioning. 115 | - moved changelog entries to separate file 116 | - make Ansible linter happy 117 | - no major changes but decided to start a new major release as versioning scheme changed quite heavily 118 | 119 | ## r6.0.0_v1.10.4 120 | 121 | - support Ubuntu 18.04 122 | 123 | - Remove PeerVPN dependency when generating certificates (use `k8s_interface` variable instead of `peervpn_conf_interface`). When generating certificates previously the values of `peervpn_conf_interface` variables were used and added to the certificate. Now instead `k8s_interface` variable is used. For almost all people that change shouldn't have any effect because the values of both variables should have been the same. If not check if the generated certificates are ok for you. The reason for this change is to allow the usage of a different VPN solution like [WireGuard](https://github.com/githubixx/ansible-role-wireguard) e.g. 124 | 125 | - always gather facts as first task 126 | 127 | - update README 128 | 129 | ## r5.0.0_v1.10.4 130 | 131 | - Implemented changes needed for Kubernetes v1.10.x. 132 | - Renamed certificate files `cert-kube-proxy*` -> `cert-k8s-proxy*` to be in pair with the other certificate file names 133 | - Added `k8s_controller_manager_csr_*` variables for kube-controller-manager client certificate 134 | - Added `k8s_scheduler_csr_*` variables for kube-scheduler client certificate 135 | 136 | ## r4.0.1_v1.9.8 137 | 138 | - No changes. Just added Git tag for Kubernetes v1.9.8 to be in pair with controller and worker roles. 139 | 140 | ## r4.0.1_v1.9.3 141 | 142 | - No changes. Just added Git tag for Kubernetes v1.9.3 to be in pair with controller and worker roles. 143 | 144 | ## r4.0.1_v1.8.4 145 | 146 | - Changed default of `k8s_ca_conf_directory` to `{{ '~/k8s/certs' | expanduser }}`. By default this will expand to user's LOCAL $HOME (the user that run's ansible-playbook) plus /k8s/certs. That means if the user's `$HOME` directory is e.g. /home/da_user then k8s_ca_conf_directory will have a value of /home/da_user/k8s/certs. As the user normally has write access to his $HOME directory we don't rely on the parent directory permission if we deploy the role without root permissions. If you defined this variable with a different value before this change then you don't need to bother about this change. 147 | 148 | ## r3.0.0_v1.8.4 149 | 150 | - include worker node names/ips into CSR (certificate signing request) for kube-apiserver certificate 151 | 152 | ## r1.0.1_v1.8.0 153 | 154 | - renamed `cfssl_*` variables to `k8s_ca_*` 155 | - change defaults for key algos and sizes to match settings in [Kubernetes the not so hard way with Ansible - Certificate authority (CA)](https://github.com/kelseyhightower/kubernetes-the-hard-way/blob/master/docs/04-certificate-authority.md) 156 | - added admin client certificate 157 | - added kubelet client certificates used in Kubernetes 1.7/1.8 158 | - added kube-proxy client certificate used in Kubernetes 1.7/1.8 159 | - Hostname,FQDN,internal IP and PeerVPN IP of all controller hosts are added automatically to Kubernetes API server certificate now 160 | - Hostname,FQDN,internal IP and PeerVPN IP for every worker host certificate is added automatically to the worker certificate 161 | 162 | ## r1.0.0_v1.6.0 163 | 164 | - Initial Ansible role. 165 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ansible-role-kubernetes-ca 2 | 3 | This role is used in [Kubernetes the not so hard way with Ansible - Certificate authority (CA)](https://www.tauceti.blog/post/kubernetes-the-not-so-hard-way-with-ansible-certificate-authority/). It basically creates two CA's: One for `etcd` and one for Kubernetes components (needed to secure communication of the Kubernetes components). Besides the Kubernetes API server none of the Kubernetes components should have a need to communicate with the `etcd` cluster directly. For infrastructure components like [Cilium](https://cilium.io/) for K8s networking or [Traefik](https://traefik.io) for ingress it may make sense to reuse the already existing `etcd` cluster. For more information see [Kubernetes the not so hard way with Ansible - Certificate authority (CA)](https://www.tauceti.blog/post/kubernetes-the-not-so-hard-way-with-ansible-certificate-authority/). 4 | 5 | ## Versions 6 | 7 | I tag every release and try to stay with [semantic versioning](http://semver.org). If you want to use the role I recommend to checkout the latest tag. The master branch is basically development while the tags mark stable releases. But in general I try to keep master in good shape too. A tag `12.0.0+1.28.5` means this is release `12.0.0` of this role and it's meant to be used with Kubernetes version >= `1.28.5` (while normally it should work with basically any Kubernetes version >= 1.18.0 but I tested it with the version tagged). If the role itself changes `X.Y.Z` before `+` will increase. If the Kubernetes version changes `X.Y.Z` after `+` will increase and also the role patch version will increase (e.g. from `12.0.0` to `12.0.1`). This allows to tag bugfixes and new major versions of the role while it's still developed for a specific Kubernetes release. 8 | 9 | ## Changelog 10 | 11 | **Change history:** 12 | 13 | see [CHANGELOG.md](https://github.com/githubixx/ansible-role-kubernetes-ca/blob/master/CHANGELOG.md) 14 | 15 | **Recent changes:** 16 | 17 | ## 12.0.0+1.28.5 18 | 19 | ### BREAKING 20 | 21 | - change default value of `k8s_controller_manager_sa_csr_cn` from `service-accounts` to `k8s-service-accounts` 22 | - change default value of `k8s_interface` from `tap0` to `eth0` 23 | - change default values of `ca_etcd_csr_cn`, `etcd_peer_csr_cn` and `etcd_client_csr_cn_prefix` 24 | - change default value of `k8s_apiserver_csr_cn` from `kubernetes` to `kube-apiserver` 25 | 26 | ### OTHER CHANGES 27 | 28 | - remove tests directory 29 | - add `namespace` to `meta/main.yml` 30 | - update Github workflow 31 | - add important note to `k8s_apiserver_csr_cn` variable 32 | - `.ansible-lint`: remove `role-name` 33 | - remove `vars` directory 34 | 35 | ### MOLECULE 36 | 37 | - remove `requirements.yml` 38 | - fix `ansible-lint` issues 39 | - use Ubuntu 22.04 for some VMs 40 | - change IPs from `192.168.10.0/24` to `172.16.10.0/24` 41 | - remove `etcd_cert_hosts` variable from `group_vars` (use default setting) 42 | - remove `role_name_check` 43 | - extend `verify.yml` 44 | - Molecule: rename role `harden-linux` to `harden_linux` 45 | 46 | ## Requirements 47 | 48 | This playbook needs [CFSSL](https://github.com/cloudflare/cfssl) PKI toolkit binaries installed. You can use [ansible-role-cfssl](https://github.com/githubixx/ansible-role-cfssl) to install CFSSL locally on your machine. If you want to store the generated certificates and CA's locally or on a network share specify the role variables below in `host_vars/localhost` or in `group_vars/all` e.g. 49 | 50 | ## Role Variables 51 | 52 | This playbook has quite a few variables. But that's mainly information needed for the certificates. 53 | 54 | ```yaml 55 | # The directory where to store the certificates. By default this 56 | # will expand to user's LOCAL $HOME (the user that runs "ansible-playbook ...") 57 | # plus "/k8s/certs". That means if the user's $HOME directory is e.g. 58 | # "/home/da_user" then "k8s_ca_conf_directory" will have a value of 59 | # "/home/da_user/k8s/certs". 60 | k8s_ca_conf_directory: "{{ '~/k8s/certs' | expanduser }}" 61 | 62 | # Directory permissions for directory specified in "k8s_ca_conf_directory" 63 | k8s_ca_conf_directory_perm: "0770" 64 | 65 | # File permissions for certificates, csr, and so on 66 | k8s_ca_file_perm: "0660" 67 | 68 | # Owner of the certificate files (you should probably change this) 69 | k8s_ca_certificate_owner: "root" 70 | 71 | # Group to which the certificate files belongs to (you should probably change this) 72 | k8s_ca_certificate_group: "root" 73 | 74 | # Specifies Ansible's hosts group which contains all K8s controller 75 | # nodes (as specified in Ansible's "hosts" file). 76 | k8s_ca_controller_nodes_group: "k8s_controller" 77 | 78 | # As above but for the K8s etcd nodes. 79 | k8s_ca_etcd_nodes_group: "k8s_etcd" 80 | 81 | # As above but for the K8s worker nodes. 82 | k8s_ca_worker_nodes_group: "k8s_worker" 83 | 84 | # This role will include the IP address of the interface you specify here in 85 | # the etcd, kube-apiserver and kubelet certificate SAN (subject alternative name). 86 | # This is the interface where all the Kubernetes cluster services communicates 87 | # and should be an encrypted network. Some examples for interface names: 88 | # "wg0" (WireGuard), "peervpn0" (PeerVPN), "eth0", "tap0" 89 | k8s_interface: "eth0" 90 | 91 | # Expiry for etcd root certificate 92 | ca_etcd_expiry: "87600h" 93 | 94 | # Certificate authority (CA) parameters for etcd certificates. This CA is used 95 | # to sign certificates used by etcd (like peer and server certificates) and 96 | # etcd clients (like "Kube API Server", "Traefik" and "Cilium" e.g.). 97 | ca_etcd_csr_cn: "etcd" 98 | ca_etcd_csr_key_algo: "rsa" 99 | ca_etcd_csr_key_size: "2048" 100 | ca_etcd_csr_names_c: "DE" 101 | ca_etcd_csr_names_l: "The_Internet" 102 | ca_etcd_csr_names_o: "Kubernetes" 103 | ca_etcd_csr_names_ou: "BY" 104 | ca_etcd_csr_names_st: "Bayern" 105 | 106 | # Expiry for Kubernetes API server root certificate 107 | ca_k8s_apiserver_expiry: "87600h" 108 | 109 | # Certificate authority (CA) parameters for Kubernetes API server. The CA is 110 | # used to sign certifcates for various Kubernetes services like Kubernetes API 111 | # server e.g. 112 | ca_k8s_apiserver_csr_cn: "Kubernetes" 113 | ca_k8s_apiserver_csr_key_algo: "rsa" 114 | ca_k8s_apiserver_csr_key_size: "2048" 115 | ca_k8s_apiserver_csr_names_c: "DE" 116 | ca_k8s_apiserver_csr_names_l: "The_Internet" 117 | ca_k8s_apiserver_csr_names_o: "Kubernetes" 118 | ca_k8s_apiserver_csr_names_ou: "BY" 119 | ca_k8s_apiserver_csr_names_st: "Bayern" 120 | 121 | # CSR parameter for etcd server certificate. The server certificate is used by 122 | # etcd server and verified by client for server identity (for example 123 | # "Kubernetes API server"). 124 | # etcd parameter: --cert-file and --key-file 125 | etcd_server_csr_cn: "etcd-server" 126 | etcd_server_csr_key_algo: "rsa" 127 | etcd_server_csr_key_size: "2048" 128 | etcd_server_csr_names_c: "DE" 129 | etcd_server_csr_names_l: "The_Internet" 130 | etcd_server_csr_names_o: "Kubernetes" 131 | etcd_server_csr_names_ou: "BY" 132 | etcd_server_csr_names_st: "Bayern" 133 | 134 | # CSR parameter for etcd peer certificate. The peer certificate is used by etcd 135 | # cluster members as they communicate with each other in both ways. 136 | # etcd parameter: --peer-cert-file and --peer-key-file 137 | etcd_peer_csr_cn: "etcd-peer" 138 | etcd_peer_csr_key_algo: "rsa" 139 | etcd_peer_csr_key_size: "2048" 140 | etcd_peer_csr_names_c: "DE" 141 | etcd_peer_csr_names_l: "The_Internet" 142 | etcd_peer_csr_names_o: "Kubernetes" 143 | etcd_peer_csr_names_ou: "BY" 144 | etcd_peer_csr_names_st: "Bayern" 145 | 146 | # CSR parameter for etcd clients. One such client is "kube-apiserver" e.g. 147 | # and is defined in "etcd_additional_clients" variable (see below). All 148 | # certificates issued for etcd clients will use this parameters. 149 | etcd_client_csr_cn_prefix: "etcd-client" 150 | etcd_client_csr_key_algo: "rsa" 151 | etcd_client_csr_key_size: "2048" 152 | etcd_client_csr_names_c: "DE" 153 | etcd_client_csr_names_l: "The_Internet" 154 | etcd_client_csr_names_o: "Kubernetes" 155 | etcd_client_csr_names_ou: "BY" 156 | etcd_client_csr_names_st: "Bayern" 157 | 158 | # CSR parameter for Kubernetes API server certificate. Used to secure the 159 | # Kubernetes API server communication. 160 | # 161 | # NOTE: It's important that the value of "ca_k8s_apiserver_csr_cn" and 162 | # "k8s_apiserver_csr_cn" are different! Otherwise Python clients and libraries 163 | # like "urllib3" and "requests" might have connection issues with the https 164 | # endpoint of "kube-apiserver". For more details see: 165 | # https://www.tauceti.blog/posts/kubernetes-the-not-so-hard-way-with-ansible-certificate-authority/ 166 | k8s_apiserver_csr_cn: "k8s-apiserver" 167 | k8s_apiserver_csr_key_algo: "rsa" 168 | k8s_apiserver_csr_key_size: "2048" 169 | k8s_apiserver_csr_names_c: "DE" 170 | k8s_apiserver_csr_names_l: "The_Internet" 171 | k8s_apiserver_csr_names_o: "Kubernetes" 172 | k8s_apiserver_csr_names_ou: "BY" 173 | k8s_apiserver_csr_names_st: "Bayern" 174 | 175 | # CSR parameter for the admin user (used for the admin user and which "kubectl" 176 | # will use). 177 | k8s_admin_csr_cn: "admin" 178 | k8s_admin_csr_key_algo: "rsa" 179 | k8s_admin_csr_key_size: "2048" 180 | k8s_admin_csr_names_c: "DE" 181 | k8s_admin_csr_names_l: "The_Internet" 182 | k8s_admin_csr_names_o: "system:masters" # DO NOT CHANGE! 183 | k8s_admin_csr_names_ou: "BY" 184 | k8s_admin_csr_names_st: "Bayern" 185 | 186 | # CSR parameter for kubelet client certificates. The `kubelet` process 187 | # (a.k.a. Kubernetes worker) also needs to authenticate itself against the 188 | # API server. These variables are used to create the CSR file which in turn 189 | # is used to create the `kubelet` certificate. Kubernetes uses a special-purpose 190 | # authorization mode (https://kubernetes.io/docs/admin/authorization/node/) 191 | # called "Node Authorizer", that specifically authorizes API requests made by 192 | # kubelets (https://kubernetes.io/docs/concepts/overview/components/#kubelet). 193 | # In order to be authorized by the "Node Authorizer", Kubelets must use a 194 | # credential that identifies them as being in the `system:nodes` group, 195 | # with a username of `system:node:` 196 | k8s_worker_csr_key_algo: "rsa" 197 | k8s_worker_csr_key_size: "2048" 198 | k8s_worker_csr_names_c: "DE" 199 | k8s_worker_csr_names_l: "The_Internet" 200 | k8s_worker_csr_names_o: "system:nodes" # DO NOT CHANGE! 201 | k8s_worker_csr_names_ou: "BY" 202 | k8s_worker_csr_names_st: "Bayern" 203 | 204 | # CSR parameter for the kube-proxy client certificate 205 | k8s_kube_proxy_csr_cn: "system:kube-proxy" # DO NOT CHANGE! 206 | k8s_kube_proxy_csr_key_algo: "rsa" 207 | k8s_kube_proxy_csr_key_size: "2048" 208 | k8s_kube_proxy_csr_names_c: "DE" 209 | k8s_kube_proxy_csr_names_l: "The_Internet" 210 | k8s_kube_proxy_csr_names_o: "system:node-proxier" # DO NOT CHANGE! 211 | k8s_kube_proxy_csr_names_ou: "BY" 212 | k8s_kube_proxy_csr_names_st: "Bayern" 213 | 214 | # CSR parameter for the kube-scheduler client certificate 215 | k8s_scheduler_csr_cn: "system:kube-scheduler" # DO NOT CHANGE! 216 | k8s_scheduler_csr_key_algo: "rsa" 217 | k8s_scheduler_csr_key_size: "2048" 218 | k8s_scheduler_csr_names_c: "DE" 219 | k8s_scheduler_csr_names_l: "The_Internet" 220 | k8s_scheduler_csr_names_o: "system:kube-scheduler" # DO NOT CHANGE! 221 | k8s_scheduler_csr_names_ou: "BY" 222 | k8s_scheduler_csr_names_st: "Bayern" 223 | 224 | # CSR parameter for the kube-controller-manager client certificate 225 | k8s_controller_manager_csr_cn: "system:kube-controller-manager" # DO NOT CHANGE! 226 | k8s_controller_manager_csr_key_algo: "rsa" 227 | k8s_controller_manager_csr_key_size: "2048" 228 | k8s_controller_manager_csr_names_c: "DE" 229 | k8s_controller_manager_csr_names_l: "The_Internet" 230 | k8s_controller_manager_csr_names_o: "system:kube-controller-manager" # DO NOT CHANGE! 231 | k8s_controller_manager_csr_names_ou: "BY" 232 | k8s_controller_manager_csr_names_st: "Bayern" 233 | 234 | # CSR parameter for kube-controller-manager service account key pair. 235 | # The "kube-controller-manager" leverages a key pair to generate and sign 236 | # service account tokens as described in the managing service accounts 237 | # documentation: https://kubernetes.io/docs/admin/service-accounts-admin/ 238 | # Hint: Think twice if you want to change this key pair for a K8s cluster 239 | # that has already pods deployed. The private key will be used to sign 240 | # generated service account tokens. The public key will be used to verify 241 | # the tokens during authentication. So if you have pods running e.g. with 242 | # the `default` service account and you roll out a new key pair the "Token 243 | # Controller" (https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/#token-controller) 244 | # which is part of the controller manager won't be able to verify the 245 | # already existing service accounts anymore. So this might cause trouble 246 | # for your running pods. 247 | k8s_controller_manager_sa_csr_cn: "k8s-service-accounts" 248 | k8s_controller_manager_sa_csr_key_algo: "rsa" 249 | k8s_controller_manager_sa_csr_key_size: "2048" 250 | k8s_controller_manager_sa_csr_names_c: "DE" 251 | k8s_controller_manager_sa_csr_names_l: "The_Internet" 252 | k8s_controller_manager_sa_csr_names_o: "Kubernetes" 253 | k8s_controller_manager_sa_csr_names_ou: "BY" 254 | k8s_controller_manager_sa_csr_names_st: "Bayern" 255 | 256 | # Add additional etcd hosts that should be included in the certificates SAN. 257 | # The task "Generate list of IP addresses and hostnames needed for etcd certificate" 258 | # in this role will automatically add the hostname, the fully qualified domain name 259 | # (FQDN), the internal IP address and the VPN IP address (e.g. the WireGuard IP) 260 | # of your etcd hosts to a list which is needed to create the certificate. 261 | # But "127.0.0.1" and "localhost" should be included too. 262 | # 263 | # If you plan to expand your etcd cluster from 3 to 5 hosts later e.g. and know the 264 | # hostname, the fully qualified domain name (FQDN), the internal IP address and 265 | # esp. the VPN IP address (e.g. the WireGuard IP) of that hosts upfront then add 266 | # them here too. This will save you a lot of work later as you don't need to 267 | # change the certificate files of the already running etcd daemons. 268 | etcd_cert_hosts: 269 | - 127.0.0.1 270 | - localhost 271 | 272 | # For "k8s_apiserver_cert_hosts" the same is basically true as with 273 | # `etcd_cert_hosts` but we also include the Kubernetes service IP `10.32.0.1` 274 | # (which you will get btw if you execute `nslookup kubernetes` later in one 275 | # of the pods). We also include "127.0.0.1" and "localhost" and we include 276 | # some Kubernetes hostname's that are available by default if "CoreDNS" 277 | # is deployed. 278 | k8s_apiserver_cert_hosts: 279 | - localhost 280 | - 127.0.0.1 281 | - 10.32.0.1 282 | - kubernetes 283 | - kubernetes.default 284 | - kubernetes.default.svc 285 | - kubernetes.default.svc.cluster 286 | - kubernetes.default.svc.cluster.local 287 | 288 | # This list should contain all etcd clients that wants to connect to the etcd 289 | # cluster. The most important client is "kube-apiserver" of course. So you 290 | # definitely want to keep "k8s-apiserver-etcd" in this list. 291 | # If other clients like "Traefik" or "Cilium" should also be able to connect 292 | # to the Kubernetes etcd cluster and store their state there further client 293 | # certificates can be issued. So if "Traefik" and "Cilium" should be able to 294 | # connect to the etcd cluster via TLS the list would look like this: 295 | # 296 | # etcd_additional_clients: 297 | # - k8s-apiserver-etcd 298 | # - traefik 299 | # - cilium 300 | # 301 | # This will generate additional files in the directory specified in 302 | # "k8s_ca_conf_directory" variable e.g. "cert-traefik*" and "cert-cilium*". 303 | # So instead of running a separate etcd cluster for "Traefik" and/or 304 | # "Cilium" the already running etcd cluster for Kubernetes can be used in 305 | # this case. 306 | # 307 | etcd_additional_clients: 308 | - k8s-apiserver-etcd 309 | ``` 310 | 311 | ## Example Playbook 312 | 313 | ```yaml 314 | - hosts: k8s_ca 315 | 316 | roles: 317 | - githubixx.kubernetes_ca 318 | ``` 319 | 320 | ## License 321 | 322 | GNU GENERAL PUBLIC LICENSE Version 3 323 | 324 | ## Author Information 325 | 326 | [http://www.tauceti.blog](http://www.tauceti.blog) 327 | -------------------------------------------------------------------------------- /defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # The directory where to store the certificates. By default this 3 | # will expand to user's LOCAL $HOME (the user that runs "ansible-playbook ...") 4 | # plus "/k8s/certs". That means if the user's $HOME directory is e.g. 5 | # "/home/da_user" then "k8s_ca_conf_directory" will have a value of 6 | # "/home/da_user/k8s/certs". 7 | k8s_ca_conf_directory: "{{ '~/k8s/certs' | expanduser }}" 8 | 9 | # Directory permissions for directory specified in "k8s_ca_conf_directory" 10 | k8s_ca_conf_directory_perm: "0770" 11 | 12 | # File permissions for certificates, csr, and so on 13 | k8s_ca_file_perm: "0660" 14 | 15 | # Owner of the certificate files (you should probably change this) 16 | k8s_ca_certificate_owner: "root" 17 | 18 | # Group to which the certificate files belongs to (you should probably change this) 19 | k8s_ca_certificate_group: "root" 20 | 21 | # Specifies Ansible's hosts group which contains all K8s controller 22 | # nodes (as specified in Ansible's "hosts" file). 23 | k8s_ca_controller_nodes_group: "k8s_controller" 24 | 25 | # As above but for the K8s etcd nodes. 26 | k8s_ca_etcd_nodes_group: "k8s_etcd" 27 | 28 | # As above but for the K8s worker nodes. 29 | k8s_ca_worker_nodes_group: "k8s_worker" 30 | 31 | # This role will include the IP address of the interface you specify here in 32 | # the etcd, kube-apiserver and kubelet certificate SAN (subject alternative name). 33 | # This is the interface where all the Kubernetes cluster services communicates 34 | # and should be an encrypted network. Some examples for interface names: 35 | # "wg0" (WireGuard), "peervpn0" (PeerVPN), "eth0", "tap0" 36 | k8s_interface: "eth0" 37 | 38 | # Expiry for etcd root certificate 39 | ca_etcd_expiry: "87600h" 40 | 41 | # Certificate authority (CA) parameters for etcd certificates. This CA is used 42 | # to sign certificates used by etcd (like peer and server certificates) and 43 | # etcd clients (like "Kube API Server, "Traefik" and "Cilium" e.g.). 44 | ca_etcd_csr_cn: "etcd" 45 | ca_etcd_csr_key_algo: "rsa" 46 | ca_etcd_csr_key_size: "2048" 47 | ca_etcd_csr_names_c: "DE" 48 | ca_etcd_csr_names_l: "The_Internet" 49 | ca_etcd_csr_names_o: "Kubernetes" 50 | ca_etcd_csr_names_ou: "BY" 51 | ca_etcd_csr_names_st: "Bayern" 52 | 53 | # Expiry for Kubernetes API server root certificate 54 | ca_k8s_apiserver_expiry: "87600h" 55 | 56 | # Certificate authority (CA) parameters for Kubernetes API server. The CA is 57 | # used to sign certifcates for various Kubernetes services like Kubernetes API 58 | # server e.g. 59 | ca_k8s_apiserver_csr_cn: "Kubernetes" 60 | ca_k8s_apiserver_csr_key_algo: "rsa" 61 | ca_k8s_apiserver_csr_key_size: "2048" 62 | ca_k8s_apiserver_csr_names_c: "DE" 63 | ca_k8s_apiserver_csr_names_l: "The_Internet" 64 | ca_k8s_apiserver_csr_names_o: "Kubernetes" 65 | ca_k8s_apiserver_csr_names_ou: "BY" 66 | ca_k8s_apiserver_csr_names_st: "Bayern" 67 | 68 | # CSR parameter for etcd server certificate. The server certificate is used by 69 | # etcd server and verified by client for server identity (for example 70 | # "Kubernetes API server"). 71 | # etcd parameter: --cert-file and --key-file 72 | etcd_server_csr_cn: "etcd-server" 73 | etcd_server_csr_key_algo: "rsa" 74 | etcd_server_csr_key_size: "2048" 75 | etcd_server_csr_names_c: "DE" 76 | etcd_server_csr_names_l: "The_Internet" 77 | etcd_server_csr_names_o: "Kubernetes" 78 | etcd_server_csr_names_ou: "BY" 79 | etcd_server_csr_names_st: "Bayern" 80 | 81 | # CSR parameter for etcd peer certificate. The peer certificate is used by etcd 82 | # cluster members as they communicate with each other in both ways. 83 | # etcd parameter: --peer-cert-file and --peer-key-file 84 | etcd_peer_csr_cn: "etcd-peer" 85 | etcd_peer_csr_key_algo: "rsa" 86 | etcd_peer_csr_key_size: "2048" 87 | etcd_peer_csr_names_c: "DE" 88 | etcd_peer_csr_names_l: "The_Internet" 89 | etcd_peer_csr_names_o: "Kubernetes" 90 | etcd_peer_csr_names_ou: "BY" 91 | etcd_peer_csr_names_st: "Bayern" 92 | 93 | # CSR parameter for etcd clients. One such client is "kube-apiserver" e.g. 94 | # and is defined in "etcd_additional_clients" variable (see below). All 95 | # certificates issued for etcd clients will use this parameters. 96 | etcd_client_csr_cn_prefix: "etcd-client" 97 | etcd_client_csr_key_algo: "rsa" 98 | etcd_client_csr_key_size: "2048" 99 | etcd_client_csr_names_c: "DE" 100 | etcd_client_csr_names_l: "The_Internet" 101 | etcd_client_csr_names_o: "Kubernetes" 102 | etcd_client_csr_names_ou: "BY" 103 | etcd_client_csr_names_st: "Bayern" 104 | 105 | # CSR parameter for Kubernetes API server certificate. Used to secure the 106 | # Kubernetes API server communication. 107 | # 108 | # NOTE: It's important that the value of "ca_k8s_apiserver_csr_cn" and 109 | # "k8s_apiserver_csr_cn" are different! Otherwise Python clients and libraries 110 | # like "urllib3" and "requests" might have connection issues with the https 111 | # endpoint of "kube-apiserver". For more details see: 112 | # https://www.tauceti.blog/posts/kubernetes-the-not-so-hard-way-with-ansible-certificate-authority/ 113 | k8s_apiserver_csr_cn: "k8s-apiserver" 114 | k8s_apiserver_csr_key_algo: "rsa" 115 | k8s_apiserver_csr_key_size: "2048" 116 | k8s_apiserver_csr_names_c: "DE" 117 | k8s_apiserver_csr_names_l: "The_Internet" 118 | k8s_apiserver_csr_names_o: "Kubernetes" 119 | k8s_apiserver_csr_names_ou: "BY" 120 | k8s_apiserver_csr_names_st: "Bayern" 121 | 122 | # CSR parameter for the admin user (used for the admin user and which "kubectl" 123 | # will use). 124 | k8s_admin_csr_cn: "admin" 125 | k8s_admin_csr_key_algo: "rsa" 126 | k8s_admin_csr_key_size: "2048" 127 | k8s_admin_csr_names_c: "DE" 128 | k8s_admin_csr_names_l: "The_Internet" 129 | k8s_admin_csr_names_o: "system:masters" # DO NOT CHANGE! 130 | k8s_admin_csr_names_ou: "BY" 131 | k8s_admin_csr_names_st: "Bayern" 132 | 133 | # CSR parameter for kubelet client certificates. The `kubelet` process 134 | # (a.k.a. Kubernetes worker) also needs to authenticate itself against the 135 | # API server. These variables are used to create the CSR file which in turn 136 | # is used to create the `kubelet` certificate. Kubernetes uses a special-purpose 137 | # authorization mode (https://kubernetes.io/docs/admin/authorization/node/) 138 | # called "Node Authorizer", that specifically authorizes API requests made by 139 | # kubelets (https://kubernetes.io/docs/concepts/overview/components/#kubelet). 140 | # In order to be authorized by the "Node Authorizer", Kubelets must use a 141 | # credential that identifies them as being in the `system:nodes` group, 142 | # with a username of `system:node:` 143 | k8s_worker_csr_key_algo: "rsa" 144 | k8s_worker_csr_key_size: "2048" 145 | k8s_worker_csr_names_c: "DE" 146 | k8s_worker_csr_names_l: "The_Internet" 147 | k8s_worker_csr_names_o: "system:nodes" # DO NOT CHANGE! 148 | k8s_worker_csr_names_ou: "BY" 149 | k8s_worker_csr_names_st: "Bayern" 150 | 151 | # CSR parameter for the kube-proxy client certificate 152 | k8s_kube_proxy_csr_cn: "system:kube-proxy" # DO NOT CHANGE! 153 | k8s_kube_proxy_csr_key_algo: "rsa" 154 | k8s_kube_proxy_csr_key_size: "2048" 155 | k8s_kube_proxy_csr_names_c: "DE" 156 | k8s_kube_proxy_csr_names_l: "The_Internet" 157 | k8s_kube_proxy_csr_names_o: "system:node-proxier" # DO NOT CHANGE! 158 | k8s_kube_proxy_csr_names_ou: "BY" 159 | k8s_kube_proxy_csr_names_st: "Bayern" 160 | 161 | # CSR parameter for the kube-scheduler client certificate 162 | k8s_scheduler_csr_cn: "system:kube-scheduler" # DO NOT CHANGE! 163 | k8s_scheduler_csr_key_algo: "rsa" 164 | k8s_scheduler_csr_key_size: "2048" 165 | k8s_scheduler_csr_names_c: "DE" 166 | k8s_scheduler_csr_names_l: "The_Internet" 167 | k8s_scheduler_csr_names_o: "system:kube-scheduler" # DO NOT CHANGE! 168 | k8s_scheduler_csr_names_ou: "BY" 169 | k8s_scheduler_csr_names_st: "Bayern" 170 | 171 | # CSR parameter for the kube-controller-manager client certificate 172 | k8s_controller_manager_csr_cn: "system:kube-controller-manager" # DO NOT CHANGE! 173 | k8s_controller_manager_csr_key_algo: "rsa" 174 | k8s_controller_manager_csr_key_size: "2048" 175 | k8s_controller_manager_csr_names_c: "DE" 176 | k8s_controller_manager_csr_names_l: "The_Internet" 177 | k8s_controller_manager_csr_names_o: "system:kube-controller-manager" # DO NOT CHANGE! 178 | k8s_controller_manager_csr_names_ou: "BY" 179 | k8s_controller_manager_csr_names_st: "Bayern" 180 | 181 | # CSR parameter for kube-controller-manager service account key pair. 182 | # The "kube-controller-manager" leverages a key pair to generate and sign 183 | # service account tokens as described in the managing service accounts 184 | # documentation: https://kubernetes.io/docs/admin/service-accounts-admin/ 185 | # Hint: Think twice if you want to change this key pair for a K8s cluster 186 | # that has already pods deployed. The private key will be used to sign 187 | # generated service account tokens. The public key will be used to verify 188 | # the tokens during authentication. So if you have pods running e.g. with 189 | # the `default` service account and you roll out a new key pair the "Token 190 | # Controller" (https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/#token-controller) 191 | # which is part of the controller manager won't be able to verify the 192 | # already existing service accounts anymore. So this might cause trouble 193 | # for your running pods. 194 | k8s_controller_manager_sa_csr_cn: "k8s-service-accounts" 195 | k8s_controller_manager_sa_csr_key_algo: "rsa" 196 | k8s_controller_manager_sa_csr_key_size: "2048" 197 | k8s_controller_manager_sa_csr_names_c: "DE" 198 | k8s_controller_manager_sa_csr_names_l: "The_Internet" 199 | k8s_controller_manager_sa_csr_names_o: "Kubernetes" 200 | k8s_controller_manager_sa_csr_names_ou: "BY" 201 | k8s_controller_manager_sa_csr_names_st: "Bayern" 202 | 203 | # Add additional etcd hosts that should be included in the certificates SAN. 204 | # The task "Generate list of IP addresses and hostnames needed for etcd certificate" 205 | # in this role will automatically add the hostname, the fully qualified domain name 206 | # (FQDN), the internal IP address and the VPN IP address (e.g. the WireGuard IP) 207 | # of your etcd hosts to a list which is needed to create the certificate. 208 | # But "127.0.0.1" and "localhost" should be included too. 209 | # 210 | # If you plan to expand your etcd cluster from 3 to 5 hosts later e.g. and know the 211 | # hostname, the fully qualified domain name (FQDN), the internal IP address and 212 | # esp. the VPN IP address (e.g. the WireGuard IP) of that hosts upfront then add 213 | # them here too. This will save you a lot of work later as you don't need to 214 | # change the certificate files of the already running etcd daemons. 215 | etcd_cert_hosts: 216 | - 127.0.0.1 217 | - localhost 218 | 219 | # For "k8s_apiserver_cert_hosts" the same is basically true as with 220 | # `etcd_cert_hosts` but we also include the Kubernetes service IP `10.32.0.1` 221 | # (which you will get btw if you execute `nslookup kubernetes` later in one 222 | # of the pods). We also include "127.0.0.1" and "localhost" and we include 223 | # some Kubernetes hostname's that are available by default if "CoreDNS" 224 | # is deployed. 225 | k8s_apiserver_cert_hosts: 226 | - localhost 227 | - 127.0.0.1 228 | - 10.32.0.1 229 | - kubernetes 230 | - kubernetes.default 231 | - kubernetes.default.svc 232 | - kubernetes.default.svc.cluster 233 | - kubernetes.default.svc.cluster.local 234 | 235 | # This list should contain all etcd clients that wants to connect to the etcd 236 | # cluster. The most important client is "kube-apiserver" of course. So you 237 | # definitely want to keep "k8s-apiserver-etcd" in this list. 238 | # If other clients like "Traefik" or "Cilium" should also be able to connect 239 | # to the Kubernetes etcd cluster and store their state there further client 240 | # certificates can be issued. So if "Traefik" and "Cilium" should be able to 241 | # connect to the etcd cluster via TLS the list would look like this: 242 | # 243 | # etcd_additional_clients: 244 | # - k8s-apiserver-etcd 245 | # - traefik 246 | # - cilium 247 | # 248 | # This will generate additional files in the directory specified in 249 | # "k8s_ca_conf_directory" variable e.g. "cert-traefik*" and "cert-cilium*". 250 | # So instead of running a separate etcd cluster for "Traefik" and/or 251 | # "Cilium" the already running etcd cluster for Kubernetes can be used in 252 | # this case. 253 | # 254 | etcd_additional_clients: 255 | - k8s-apiserver-etcd 256 | -------------------------------------------------------------------------------- /meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | author: Robert Wimmer 4 | description: Generate Kubernetes CA plus certificates for etcd and Kubernetes API server 5 | license: GPLv3 6 | min_ansible_version: "2.9" 7 | role_name: kubernetes_ca 8 | namespace: githubixx 9 | platforms: 10 | - name: Ubuntu 11 | versions: 12 | - "focal" 13 | - "jammy" 14 | galaxy_tags: 15 | - tls 16 | - certificate 17 | - security 18 | - kubernetes 19 | -------------------------------------------------------------------------------- /molecule/default/converge.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (C) 2023 Robert Wimmer 3 | # SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | - name: Setup certificates 6 | hosts: k8s_assets 7 | become: true 8 | gather_facts: false 9 | tasks: 10 | - name: Generate etcd and K8s TLS certificates 11 | ansible.builtin.include_role: 12 | name: githubixx.kubernetes_ca 13 | -------------------------------------------------------------------------------- /molecule/default/group_vars/all.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (C) 2023 Robert Wimmer 3 | # SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | # Use "systemd-timesyncd" for time services. It's available by default. 6 | harden_linux_ntp: "systemd-timesyncd" 7 | 8 | # Password for user "root" and "vagrant" is "vagrant" in both cases. As 9 | # "vagrant" user is available in every Vagrant Ubuntu Box just use it. 10 | harden_linux_root_password: "$6$rounds=656000$mysecretsalt$fpyQ9hMON6iKKuM0Rz10WZKNJR4OkQTVfBmd4SPrJPsU9XmgQGRtogcUnFB5FLRIitswuQFr6Tr8Mos9l7Ojm0" 11 | harden_linux_deploy_user: "vagrant" 12 | harden_linux_deploy_user_password: "$6$rounds=656000$mysecretsalt$fpyQ9hMON6iKKuM0Rz10WZKNJR4OkQTVfBmd4SPrJPsU9XmgQGRtogcUnFB5FLRIitswuQFr6Tr8Mos9l7Ojm0" 13 | harden_linux_deploy_user_home: "/home/vagrant" 14 | harden_linux_deploy_user_uid: "1000" 15 | harden_linux_deploy_user_shell: "/bin/bash" 16 | 17 | # Enable IP forwarding for IPv4 and IPv6 18 | harden_linux_sysctl_settings_user: 19 | "net.ipv4.ip_forward": 1 20 | "net.ipv6.conf.default.forwarding": 1 21 | "net.ipv6.conf.all.forwarding": 1 22 | 23 | # Let SSHd listen on port 22, allow password authentication and allow "root" 24 | # login. The last two settings are not recommended for production use but for 25 | # this test deployment it's okay as it makes debugging easier and faster. 26 | harden_linux_sshd_settings_user: 27 | "^Port ": "Port 22" 28 | "^PasswordAuthentication": "PasswordAuthentication yes" 29 | "^PermitRootLogin": "PermitRootLogin yes" 30 | 31 | # Open a few ports for ssh, Wireguard, HTTP, HTTPS and SMTP. 32 | harden_linux_ufw_rules: 33 | - rule: "allow" 34 | to_port: "22" 35 | protocol: "tcp" 36 | - rule: "allow" 37 | to_port: "51820" 38 | protocol: "udp" 39 | - rule: "allow" 40 | to_port: "80" 41 | protocol: "tcp" 42 | - rule: "allow" 43 | to_port: "443" 44 | protocol: "tcp" 45 | - rule: "allow" 46 | to_port: "25" 47 | protocol: "tcp" 48 | 49 | # Allow all traffic from the following networks. 50 | harden_linux_ufw_allow_networks: 51 | - "10.0.0.0/8" 52 | - "172.16.0.0/12" 53 | - "192.168.0.0/16" 54 | 55 | # Enable logging for UFW. 56 | harden_linux_ufw_logging: 'on' 57 | 58 | # Set the default forward policy to "ACCEPT". 59 | harden_linux_ufw_defaults_user: 60 | "^DEFAULT_FORWARD_POLICY": 'DEFAULT_FORWARD_POLICY="ACCEPT"' 61 | 62 | # Don't block SSH logins from the following networks even login attempts fail 63 | # for a few times. 64 | harden_linux_sshguard_whitelist: 65 | - "127.0.0.0/8" 66 | - "::1/128" 67 | - "10.0.0.0/8" 68 | - "172.16.0.0/12" 69 | - "192.168.0.0/16" 70 | 71 | # Directory where the etcd certificates are stored on the Ansible controller 72 | # host. Certificate files for etcd will be copied from this directory to 73 | # the etcd nodes. 74 | etcd_ca_conf_directory: "{{ k8s_ca_conf_directory }}" 75 | # Interface where the etcd service is listening on. 76 | etcd_interface: "{{ k8s_interface }}" 77 | 78 | # Interface where the Kubernetes control plane services are listening on. 79 | k8s_interface: "wg0" 80 | 81 | # Directory where the Kubernetes certificates are stored on the Ansible 82 | # controller host. 83 | k8s_ca_conf_directory: "/tmp/k8s-ca" 84 | # Permissions for the Kubernetes CA directory. 85 | k8s_ca_conf_directory_perm: "0700" 86 | # Permissions for the Kubernetes CA files. 87 | k8s_ca_file_perm: "0600" 88 | # Owner of the Kubernetes CA files. 89 | k8s_ca_certificate_owner: "vagrant" 90 | # Group of the Kubernetes CA files. 91 | k8s_ca_certificate_group: "vagrant" 92 | 93 | # Common name for "etcd" certificate authority certificates. 94 | ca_etcd_csr_cn: "etcd" 95 | ca_etcd_csr_key_algo: "ecdsa" 96 | ca_etcd_csr_key_size: "384" 97 | 98 | # Common name for "kube-apiserver" certificate authority certificate. 99 | ca_k8s_apiserver_csr_cn: "kubernetes" 100 | ca_k8s_apiserver_csr_key_algo: "ecdsa" 101 | ca_k8s_apiserver_csr_key_size: "384" 102 | 103 | # Common name for "etcd" servers 104 | etcd_server_csr_cn: "etcd-server" 105 | etcd_server_csr_key_algo: "ecdsa" 106 | etcd_server_csr_key_size: "384" 107 | 108 | # Common name for "etcd" peers 109 | etcd_peer_csr_cn: "etcd-peer" 110 | etcd_peer_csr_key_algo: "ecdsa" 111 | etcd_peer_csr_key_size: "384" 112 | 113 | # Common name for "etcd" client certificates 114 | etcd_client_csr_cn_prefix: "etcd-client" 115 | etcd_client_csr_key_algo: "ecdsa" 116 | etcd_client_csr_key_size: "384" 117 | 118 | # Common name for "kube-apiserver" 119 | k8s_apiserver_csr_cn: "k8s-apiserver" 120 | k8s_apiserver_csr_key_algo: "ecdsa" 121 | k8s_apiserver_csr_key_size: "384" 122 | 123 | # Common name for Kubernetes "admin" user certificate (used by "kubectl" e.g) 124 | k8s_admin_csr_cn: "k8s-admin" 125 | k8s_admin_csr_key_algo: "ecdsa" 126 | k8s_admin_csr_key_size: "384" 127 | 128 | k8s_worker_csr_key_algo: "ecdsa" 129 | k8s_worker_csr_key_size: "384" 130 | 131 | k8s_controller_manager_csr_key_algo: "ecdsa" 132 | k8s_controller_manager_csr_key_size: "384" 133 | 134 | k8s_scheduler_csr_key_algo: "ecdsa" 135 | k8s_scheduler_csr_key_size: "384" 136 | 137 | k8s_controller_manager_sa_csr_cn: "k8s-service-accounts" 138 | k8s_controller_manager_sa_csr_key_algo: "ecdsa" 139 | k8s_controller_manager_sa_csr_key_size: "384" 140 | 141 | k8s_kube_proxy_csr_key_algo: "ecdsa" 142 | k8s_kube_proxy_csr_key_size: "384" 143 | -------------------------------------------------------------------------------- /molecule/default/host_vars/test-assets.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (C) 2023 Robert Wimmer 3 | # SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | wireguard_address: "10.10.10.5/24" 6 | wireguard_port: 51820 7 | wireguard_persistent_keepalive: "30" 8 | wireguard_endpoint: "172.16.10.5" 9 | -------------------------------------------------------------------------------- /molecule/default/host_vars/test-controller1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (C) 2023 Robert Wimmer 3 | # SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | wireguard_address: "10.10.10.10/24" 6 | wireguard_port: 51820 7 | wireguard_persistent_keepalive: "30" 8 | wireguard_endpoint: "172.16.10.10" 9 | -------------------------------------------------------------------------------- /molecule/default/host_vars/test-controller2.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (C) 2023 Robert Wimmer 3 | # SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | wireguard_address: "10.10.10.20/24" 6 | wireguard_port: 51820 7 | wireguard_persistent_keepalive: "30" 8 | wireguard_endpoint: "172.16.10.20" 9 | -------------------------------------------------------------------------------- /molecule/default/host_vars/test-controller3.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (C) 2023 Robert Wimmer 3 | # SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | wireguard_address: "10.10.10.30/24" 6 | wireguard_port: 51820 7 | wireguard_persistent_keepalive: "30" 8 | wireguard_endpoint: "172.16.10.30" 9 | -------------------------------------------------------------------------------- /molecule/default/host_vars/test-worker1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (C) 2023 Robert Wimmer 3 | # SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | wireguard_address: "10.10.10.100/24" 6 | wireguard_port: 51820 7 | wireguard_persistent_keepalive: "30" 8 | wireguard_endpoint: "172.16.10.100" 9 | -------------------------------------------------------------------------------- /molecule/default/host_vars/test-worker2.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (C) 2023 Robert Wimmer 3 | # SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | wireguard_address: "10.10.10.110/24" 6 | wireguard_port: 51820 7 | wireguard_persistent_keepalive: "30" 8 | wireguard_endpoint: "172.16.10.110" 9 | -------------------------------------------------------------------------------- /molecule/default/molecule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (C) 2023 Robert Wimmer 3 | # SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | dependency: 6 | name: galaxy 7 | 8 | driver: 9 | name: vagrant 10 | provider: 11 | name: libvirt 12 | type: libvirt 13 | 14 | platforms: 15 | - name: test-assets 16 | box: generic/ubuntu2204 17 | memory: 1024 18 | cpus: 2 19 | groups: 20 | - vpn 21 | - k8s_assets 22 | - k8s 23 | interfaces: 24 | - auto_config: true 25 | network_name: private_network 26 | type: static 27 | ip: 172.16.10.5 28 | - name: test-controller1 29 | box: generic/ubuntu2204 30 | memory: 2048 31 | cpus: 2 32 | groups: 33 | - vpn 34 | - k8s_controller 35 | - k8s_worker 36 | - k8s_etcd 37 | - k8s 38 | interfaces: 39 | - auto_config: true 40 | network_name: private_network 41 | type: static 42 | ip: 172.16.10.10 43 | - name: test-controller2 44 | box: generic/ubuntu2004 45 | memory: 2048 46 | cpus: 2 47 | groups: 48 | - vpn 49 | - k8s_controller 50 | - k8s_worker 51 | - k8s_etcd 52 | - k8s 53 | interfaces: 54 | - auto_config: true 55 | network_name: private_network 56 | type: static 57 | ip: 172.16.10.20 58 | - name: test-controller3 59 | box: generic/ubuntu2004 60 | memory: 2048 61 | cpus: 2 62 | groups: 63 | - vpn 64 | - k8s_controller 65 | - k8s_worker 66 | - k8s_etcd 67 | - k8s 68 | interfaces: 69 | - auto_config: true 70 | network_name: private_network 71 | type: static 72 | ip: 172.16.10.30 73 | - name: test-worker1 74 | box: generic/ubuntu2204 75 | memory: 2048 76 | cpus: 2 77 | groups: 78 | - vpn 79 | - k8s_worker 80 | - k8s 81 | interfaces: 82 | - auto_config: true 83 | network_name: private_network 84 | type: static 85 | ip: 172.16.10.100 86 | - name: test-worker2 87 | box: generic/ubuntu2004 88 | memory: 2048 89 | cpus: 2 90 | groups: 91 | - vpn 92 | - k8s_worker 93 | - k8s 94 | interfaces: 95 | - auto_config: true 96 | network_name: private_network 97 | type: static 98 | ip: 172.16.10.110 99 | 100 | provisioner: 101 | name: ansible 102 | connection_options: 103 | ansible_ssh_user: vagrant 104 | ansible_become: true 105 | log: true 106 | lint: yamllint . && flake8 107 | 108 | scenario: 109 | name: default 110 | test_sequence: 111 | - prepare 112 | - converge 113 | 114 | verifier: 115 | name: ansible 116 | enabled: true 117 | -------------------------------------------------------------------------------- /molecule/default/prepare.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (C) 2023 Robert Wimmer 3 | # SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | - name: Update cache 6 | hosts: k8s 7 | remote_user: vagrant 8 | become: true 9 | gather_facts: true 10 | tasks: 11 | - name: Update APT package cache 12 | ansible.builtin.apt: 13 | update_cache: true 14 | cache_valid_time: 3600 15 | 16 | - name: Harden hosts 17 | hosts: all 18 | remote_user: vagrant 19 | become: true 20 | gather_facts: true 21 | tasks: 22 | - name: Setup harden_linux role 23 | ansible.builtin.include_role: 24 | name: githubixx.harden_linux 25 | 26 | - name: Setup Wireguard VPN 27 | hosts: vpn 28 | remote_user: vagrant 29 | become: true 30 | gather_facts: true 31 | tasks: 32 | - name: Setup wireguard role 33 | ansible.builtin.include_role: 34 | name: githubixx.ansible_role_wireguard 35 | 36 | - name: Setup cfssl 37 | hosts: k8s_assets 38 | become: true 39 | gather_facts: false 40 | tasks: 41 | - name: Install cfssl 42 | ansible.builtin.include_role: 43 | name: githubixx.cfssl 44 | -------------------------------------------------------------------------------- /molecule/default/verify.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (C) 2023 Robert Wimmer 3 | # SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | - name: Verify setup 6 | hosts: test-assets 7 | tasks: 8 | - name: Check cert-k8s-proxy.pem 9 | ansible.builtin.shell: | 10 | set -o errexit 11 | set -o pipefail 12 | set -o nounset 13 | openssl x509 -in {{ k8s_ca_conf_directory }}/cert-k8s-proxy.pem -text -noout | grep -q "CN = system:kube-proxy" 14 | exit 0 15 | args: 16 | executable: /bin/bash 17 | changed_when: false 18 | 19 | - name: Check cert-test-worker1.pem 20 | ansible.builtin.shell: | 21 | set -o errexit 22 | set -o pipefail 23 | set -o nounset 24 | openssl x509 -in {{ k8s_ca_conf_directory }}/cert-test-worker1.pem -text -noout | grep -q "CN = system:node:test-worker1" 25 | exit 0 26 | args: 27 | executable: /bin/bash 28 | changed_when: false 29 | 30 | - name: Check cert-k8s-scheduler.pem 31 | ansible.builtin.shell: | 32 | set -o errexit 33 | set -o pipefail 34 | set -o nounset 35 | openssl x509 -in {{ k8s_ca_conf_directory }}/cert-k8s-scheduler.pem -text -noout | grep -q "CN = system:kube-scheduler" 36 | exit 0 37 | args: 38 | executable: /bin/bash 39 | changed_when: false 40 | 41 | - name: Check cert-k8s-controller-manager.pem 42 | ansible.builtin.shell: | 43 | set -o errexit 44 | set -o pipefail 45 | set -o nounset 46 | openssl x509 -in {{ k8s_ca_conf_directory }}/cert-k8s-controller-manager.pem -text -noout | grep -q "CN = system:kube-controller-manager" 47 | exit 0 48 | args: 49 | executable: /bin/bash 50 | changed_when: false 51 | 52 | - name: Check cert-k8s-controller-manager-sa.pem 53 | ansible.builtin.shell: | 54 | set -o errexit 55 | set -o pipefail 56 | set -o nounset 57 | openssl x509 -in {{ k8s_ca_conf_directory }}/cert-k8s-controller-manager-sa.pem -text -noout | grep -q "CN = k8s-service-accounts" 58 | exit 0 59 | args: 60 | executable: /bin/bash 61 | changed_when: false 62 | 63 | - name: Check if OpenSSL matches ca-k8s-apiserver.pem and cert-k8s-apiserver.pem 64 | ansible.builtin.shell: | 65 | set -o errexit 66 | set -o pipefail 67 | set -o nounset 68 | openssl verify -verbose -x509_strict -CAfile {{ k8s_ca_conf_directory }}/ca-k8s-apiserver.pem {{ k8s_ca_conf_directory }}/cert-k8s-apiserver.pem 69 | exit 0 70 | args: 71 | executable: /bin/bash 72 | changed_when: false 73 | -------------------------------------------------------------------------------- /tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Gather instance facts 3 | ansible.builtin.setup: 4 | delegate_to: "{{ item }}" 5 | delegate_facts: true 6 | loop: "{{ groups[k8s_ca_controller_nodes_group] | union(groups[k8s_ca_worker_nodes_group]) | union(groups[k8s_ca_etcd_nodes_group]) }}" 7 | 8 | - name: Generate list of IP addresses and hostnames needed for Kubernetes API server certificate 9 | ansible.builtin.set_fact: 10 | k8s_api_hosts: >- 11 | {% set comma = joiner(",") %}{% for item in groups[k8s_ca_controller_nodes_group] -%} 12 | {{ comma() }}{{ hostvars[item].ansible_default_ipv4.address }}{{ comma() }}{{ hostvars[item]["ansible_" + hostvars[item]["k8s_interface"]].ipv4.address }}{{ comma() }}{{ item }}{{ comma() }}{{ hostvars[item]["ansible_hostname"] }} 13 | {%- endfor %}{% for item in k8s_apiserver_cert_hosts -%} 14 | {{ comma() }}{{ item }} 15 | {%- endfor %} 16 | tags: 17 | - kubernetes-ca 18 | 19 | - name: Output of hostnames/IPs used for Kubernetes API server certificate 20 | ansible.builtin.debug: 21 | var: k8s_api_hosts 22 | verbosity: 2 23 | tags: 24 | - kubernetes-ca 25 | 26 | - name: Generate list of IP addresses and hostnames needed for etcd certificate 27 | ansible.builtin.set_fact: 28 | etcd_hosts: >- 29 | {% set comma = joiner(",") %}{% for item in groups[k8s_ca_etcd_nodes_group] -%} 30 | {{ comma() }}{{ hostvars[item].ansible_default_ipv4.address }}{{ comma() }}{{ hostvars[item]["ansible_" + hostvars[item]["k8s_interface"]].ipv4.address }}{{ comma() }}{{ item }}{{ comma() }}{{ hostvars[item]["ansible_hostname"] }} 31 | {%- endfor %}{% for item in etcd_cert_hosts -%} 32 | {{ comma() }}{{ item }} 33 | {%- endfor %} 34 | tags: 35 | - kubernetes-ca 36 | - kubernetes-ca-etcd 37 | 38 | - name: Output of hostnames/IPs used for etcd certificate 39 | ansible.builtin.debug: 40 | var: etcd_hosts 41 | verbosity: 2 42 | tags: 43 | - kubernetes-ca 44 | - kubernetes-ca-etcd 45 | 46 | - name: Create directory for CA and certificate files 47 | ansible.builtin.file: 48 | path: "{{ k8s_ca_conf_directory }}" 49 | owner: "{{ k8s_ca_certificate_owner }}" 50 | group: "{{ k8s_ca_certificate_group }}" 51 | mode: "{{ k8s_ca_conf_directory_perm }}" 52 | state: directory 53 | tags: 54 | - kubernetes-ca 55 | 56 | - name: Create etcd CA configuration file 57 | ansible.builtin.template: 58 | src: "ca-etcd-config.json.j2" 59 | dest: "{{ k8s_ca_conf_directory }}/ca-etcd-config.json" 60 | owner: "{{ k8s_ca_certificate_owner }}" 61 | group: "{{ k8s_ca_certificate_group }}" 62 | mode: "{{ k8s_ca_file_perm }}" 63 | tags: 64 | - kubernetes-ca 65 | - kubernetes-ca-etcd 66 | 67 | - name: Create Kubernetes API server CA configuration file 68 | ansible.builtin.template: 69 | src: "ca-k8s-apiserver-config.json.j2" 70 | dest: "{{ k8s_ca_conf_directory }}/ca-k8s-apiserver-config.json" 71 | owner: "{{ k8s_ca_certificate_owner }}" 72 | group: "{{ k8s_ca_certificate_group }}" 73 | mode: "{{ k8s_ca_file_perm }}" 74 | tags: 75 | - kubernetes-ca 76 | 77 | - name: Create the etcd CA certificate request file (CSR) 78 | ansible.builtin.template: 79 | src: "ca-etcd-csr.json.j2" 80 | dest: "{{ k8s_ca_conf_directory }}/ca-etcd-csr.json" 81 | owner: "{{ k8s_ca_certificate_owner }}" 82 | group: "{{ k8s_ca_certificate_group }}" 83 | mode: "{{ k8s_ca_file_perm }}" 84 | tags: 85 | - kubernetes-ca 86 | - kubernetes-ca-etcd 87 | 88 | - name: Create the Kubernetes API server CA certificate request file (CSR) 89 | ansible.builtin.template: 90 | src: "ca-k8s-apiserver-csr.json.j2" 91 | dest: "{{ k8s_ca_conf_directory }}/ca-k8s-apiserver-csr.json" 92 | owner: "{{ k8s_ca_certificate_owner }}" 93 | group: "{{ k8s_ca_certificate_group }}" 94 | mode: "{{ k8s_ca_file_perm }}" 95 | tags: 96 | - kubernetes-ca 97 | 98 | - name: Generate the etcd certificate authority (CA) and private key 99 | ansible.builtin.shell: > 100 | set -o errexit; \ 101 | set -o pipefail; \ 102 | cfssl gencert \ 103 | -initca ca-etcd-csr.json \ 104 | | cfssljson -bare ca-etcd 105 | args: 106 | executable: "/bin/bash" 107 | chdir: "{{ k8s_ca_conf_directory }}" 108 | creates: "{{ k8s_ca_conf_directory }}/ca-etcd-key.pem" 109 | tags: 110 | - kubernetes-ca 111 | - kubernetes-ca-etcd 112 | 113 | - name: Set file permissions for etcd CA and private key file 114 | ansible.builtin.file: 115 | path: "{{ k8s_ca_conf_directory }}/{{ item }}" 116 | owner: "{{ k8s_ca_certificate_owner }}" 117 | group: "{{ k8s_ca_certificate_group }}" 118 | mode: '{{ k8s_ca_file_perm }}' 119 | modification_time: "preserve" 120 | access_time: "preserve" 121 | loop: 122 | - ca-etcd.pem 123 | - ca-etcd-key.pem 124 | - ca-etcd.csr 125 | 126 | - name: Generate Kubernetes API server certificate authority (CA) and private key 127 | ansible.builtin.shell: > 128 | set -o errexit; \ 129 | set -o pipefail; \ 130 | cfssl gencert \ 131 | -initca ca-k8s-apiserver-csr.json \ 132 | | cfssljson -bare ca-k8s-apiserver 133 | args: 134 | executable: "/bin/bash" 135 | chdir: "{{ k8s_ca_conf_directory }}" 136 | creates: "{{ k8s_ca_conf_directory }}/ca-k8s-apiserver-key.pem" 137 | tags: 138 | - kubernetes-ca 139 | 140 | - name: Set file permissions for Kubernetes API server CA and private key 141 | ansible.builtin.file: 142 | path: "{{ k8s_ca_conf_directory }}/{{ item }}" 143 | owner: "{{ k8s_ca_certificate_owner }}" 144 | group: "{{ k8s_ca_certificate_group }}" 145 | mode: '{{ k8s_ca_file_perm }}' 146 | modification_time: "preserve" 147 | access_time: "preserve" 148 | loop: 149 | - ca-k8s-apiserver.pem 150 | - ca-k8s-apiserver-key.pem 151 | - ca-k8s-apiserver.csr 152 | 153 | - name: Create the etcd server CSR file 154 | ansible.builtin.template: 155 | src: "cert-etcd-server-csr.json.j2" 156 | dest: "{{ k8s_ca_conf_directory }}/cert-etcd-server-csr.json" 157 | owner: "{{ k8s_ca_certificate_owner }}" 158 | group: "{{ k8s_ca_certificate_group }}" 159 | mode: "{{ k8s_ca_file_perm }}" 160 | tags: 161 | - kubernetes-ca 162 | - kubernetes-ca-etcd 163 | 164 | - name: Create the etcd peer CSR file 165 | ansible.builtin.template: 166 | src: "cert-etcd-peer-csr.json.j2" 167 | dest: "{{ k8s_ca_conf_directory }}/cert-etcd-peer-csr.json" 168 | owner: "{{ k8s_ca_certificate_owner }}" 169 | group: "{{ k8s_ca_certificate_group }}" 170 | mode: "{{ k8s_ca_file_perm }}" 171 | tags: 172 | - kubernetes-ca 173 | - kubernetes-ca-etcd 174 | 175 | - name: Create the Kubernetes API server key CSR file 176 | ansible.builtin.template: 177 | src: "cert-k8s-apiserver-csr.json.j2" 178 | dest: "{{ k8s_ca_conf_directory }}/cert-k8s-apiserver-csr.json" 179 | owner: "{{ k8s_ca_certificate_owner }}" 180 | group: "{{ k8s_ca_certificate_group }}" 181 | mode: "{{ k8s_ca_file_perm }}" 182 | tags: 183 | - kubernetes-ca 184 | 185 | - name: Create the admin user key CSR file 186 | ansible.builtin.template: 187 | src: "cert-admin-csr.json.j2" 188 | dest: "{{ k8s_ca_conf_directory }}/cert-admin-csr.json" 189 | owner: "{{ k8s_ca_certificate_owner }}" 190 | group: "{{ k8s_ca_certificate_group }}" 191 | mode: "{{ k8s_ca_file_perm }}" 192 | tags: 193 | - kubernetes-ca 194 | 195 | - name: Create the kube-proxy key CSR file 196 | ansible.builtin.template: 197 | src: "cert-k8s-proxy-csr.json.j2" 198 | dest: "{{ k8s_ca_conf_directory }}/cert-k8s-proxy-csr.json" 199 | owner: "{{ k8s_ca_certificate_owner }}" 200 | group: "{{ k8s_ca_certificate_group }}" 201 | mode: "{{ k8s_ca_file_perm }}" 202 | tags: 203 | - kubernetes-ca 204 | 205 | - name: Create the worker key CSR files 206 | ansible.builtin.template: 207 | src: "cert-worker-csr.json.j2" 208 | dest: "{{ k8s_ca_conf_directory }}/cert-{{ item }}-csr.json" 209 | owner: "{{ k8s_ca_certificate_owner }}" 210 | group: "{{ k8s_ca_certificate_group }}" 211 | mode: "{{ k8s_ca_file_perm }}" 212 | with_inventory_hostnames: 213 | - "{{ k8s_ca_worker_nodes_group }}" 214 | vars: 215 | worker_host: "{{ item }}" 216 | tags: 217 | - kubernetes-ca 218 | 219 | - name: Create the kube-controller-manager key CSR file 220 | ansible.builtin.template: 221 | src: "cert-k8s-controller-manager-csr.json.j2" 222 | dest: "{{ k8s_ca_conf_directory }}/cert-k8s-controller-manager-csr.json" 223 | owner: "{{ k8s_ca_certificate_owner }}" 224 | group: "{{ k8s_ca_certificate_group }}" 225 | mode: "{{ k8s_ca_file_perm }}" 226 | tags: 227 | - kubernetes-ca 228 | 229 | - name: Create the kube-controller-manager service-account key CSR file 230 | ansible.builtin.template: 231 | src: "cert-k8s-controller-manager-sa-csr.json.j2" 232 | dest: "{{ k8s_ca_conf_directory }}/cert-k8s-controller-manager-sa-csr.json" 233 | owner: "{{ k8s_ca_certificate_owner }}" 234 | group: "{{ k8s_ca_certificate_group }}" 235 | mode: "{{ k8s_ca_file_perm }}" 236 | tags: 237 | - kubernetes-ca 238 | 239 | - name: Create the kube-scheduler key CSR file 240 | ansible.builtin.template: 241 | src: "cert-k8s-scheduler-csr.json.j2" 242 | dest: "{{ k8s_ca_conf_directory }}/cert-k8s-scheduler-csr.json" 243 | owner: "{{ k8s_ca_certificate_owner }}" 244 | group: "{{ k8s_ca_certificate_group }}" 245 | mode: "{{ k8s_ca_file_perm }}" 246 | tags: 247 | - kubernetes-ca 248 | 249 | - name: Generate TLS server certificate for etcd 250 | ansible.builtin.shell: > 251 | set -o errexit; \ 252 | set -o pipefail; \ 253 | cfssl gencert \ 254 | -ca=ca-etcd.pem \ 255 | -ca-key=ca-etcd-key.pem \ 256 | -config=ca-etcd-config.json \ 257 | -hostname={{ etcd_hosts }} \ 258 | -profile=server \ 259 | cert-etcd-server-csr.json \ 260 | | cfssljson -bare cert-etcd-server 261 | args: 262 | executable: "/bin/bash" 263 | chdir: "{{ k8s_ca_conf_directory }}" 264 | creates: "{{ k8s_ca_conf_directory }}/cert-etcd-server-key.pem" 265 | tags: 266 | - kubernetes-ca 267 | - kubernetes-ca-etcd 268 | 269 | - name: Set file permissions for etcd server certificate files 270 | ansible.builtin.file: 271 | path: "{{ k8s_ca_conf_directory }}/{{ item }}" 272 | owner: "{{ k8s_ca_certificate_owner }}" 273 | group: "{{ k8s_ca_certificate_group }}" 274 | mode: '{{ k8s_ca_file_perm }}' 275 | modification_time: "preserve" 276 | access_time: "preserve" 277 | loop: 278 | - cert-etcd-server.pem 279 | - cert-etcd-server-key.pem 280 | - cert-etcd-server.csr 281 | 282 | - name: Generate TLS peer certificate for etcd 283 | ansible.builtin.shell: > 284 | set -o errexit; \ 285 | set -o pipefail; \ 286 | cfssl gencert \ 287 | -ca=ca-etcd.pem \ 288 | -ca-key=ca-etcd-key.pem \ 289 | -config=ca-etcd-config.json \ 290 | -hostname={{ etcd_hosts }} \ 291 | -profile=peer \ 292 | cert-etcd-peer-csr.json \ 293 | | cfssljson -bare cert-etcd-peer 294 | args: 295 | executable: "/bin/bash" 296 | chdir: "{{ k8s_ca_conf_directory }}" 297 | creates: "{{ k8s_ca_conf_directory }}/cert-etcd-peer-key.pem" 298 | tags: 299 | - kubernetes-ca 300 | - kubernetes-ca-etcd 301 | 302 | - name: Set file permissions for etcd peer certificate files 303 | ansible.builtin.file: 304 | path: "{{ k8s_ca_conf_directory }}/{{ item }}" 305 | owner: "{{ k8s_ca_certificate_owner }}" 306 | group: "{{ k8s_ca_certificate_group }}" 307 | mode: '{{ k8s_ca_file_perm }}' 308 | modification_time: "preserve" 309 | access_time: "preserve" 310 | loop: 311 | - cert-etcd-peer.pem 312 | - cert-etcd-peer-key.pem 313 | - cert-etcd-peer.csr 314 | 315 | - name: Generate TLS certificate for Kubernetes API server 316 | ansible.builtin.shell: > 317 | set -o errexit; \ 318 | set -o pipefail; \ 319 | cfssl gencert \ 320 | -ca=ca-k8s-apiserver.pem \ 321 | -ca-key=ca-k8s-apiserver-key.pem \ 322 | -config=ca-k8s-apiserver-config.json \ 323 | -hostname={{ k8s_api_hosts }} \ 324 | -profile=kubernetes \ 325 | cert-k8s-apiserver-csr.json \ 326 | | cfssljson -bare cert-k8s-apiserver 327 | args: 328 | executable: "/bin/bash" 329 | chdir: "{{ k8s_ca_conf_directory }}" 330 | creates: "{{ k8s_ca_conf_directory }}/cert-k8s-apiserver-key.pem" 331 | tags: 332 | - kubernetes-ca 333 | 334 | - name: Set file permissions for Kubernetes API server certificate files 335 | ansible.builtin.file: 336 | path: "{{ k8s_ca_conf_directory }}/{{ item }}" 337 | owner: "{{ k8s_ca_certificate_owner }}" 338 | group: "{{ k8s_ca_certificate_group }}" 339 | mode: '{{ k8s_ca_file_perm }}' 340 | modification_time: "preserve" 341 | access_time: "preserve" 342 | loop: 343 | - cert-k8s-apiserver.pem 344 | - cert-k8s-apiserver-key.pem 345 | - cert-k8s-apiserver.csr 346 | 347 | - name: Generate TLS certificate for admin user 348 | ansible.builtin.shell: > 349 | set -o errexit; \ 350 | set -o pipefail; \ 351 | cfssl gencert \ 352 | -ca=ca-k8s-apiserver.pem \ 353 | -ca-key=ca-k8s-apiserver-key.pem \ 354 | -config=ca-k8s-apiserver-config.json \ 355 | -profile=kubernetes cert-admin-csr.json \ 356 | | cfssljson -bare cert-admin 357 | args: 358 | executable: "/bin/bash" 359 | chdir: "{{ k8s_ca_conf_directory }}" 360 | creates: "{{ k8s_ca_conf_directory }}/cert-admin-key.pem" 361 | tags: 362 | - kubernetes-ca 363 | 364 | - name: Set file permissions for admin user certificate files 365 | ansible.builtin.file: 366 | path: "{{ k8s_ca_conf_directory }}/{{ item }}" 367 | owner: "{{ k8s_ca_certificate_owner }}" 368 | group: "{{ k8s_ca_certificate_group }}" 369 | mode: '{{ k8s_ca_file_perm }}' 370 | modification_time: "preserve" 371 | access_time: "preserve" 372 | loop: 373 | - cert-admin.pem 374 | - cert-admin-key.pem 375 | - cert-admin.csr 376 | 377 | - name: Generate TLS certificates for Kubernetes worker hosts (kubelet) 378 | ansible.builtin.shell: > 379 | set -o errexit; \ 380 | set -o pipefail; \ 381 | cfssl gencert \ 382 | -ca=ca-k8s-apiserver.pem \ 383 | -ca-key=ca-k8s-apiserver-key.pem \ 384 | -config=ca-k8s-apiserver-config.json \ 385 | -hostname={{ hostvars[item]['ansible_hostname'] }},{{ hostvars[item]['ansible_default_ipv4']['address'] }},{{ hostvars[item]['ansible_' + hostvars[item]['k8s_interface']].ipv4.address }} \ 386 | -profile=kubernetes \ 387 | cert-{{ item }}-csr.json \ 388 | | cfssljson -bare cert-{{ item }} 389 | args: 390 | executable: "/bin/bash" 391 | chdir: "{{ k8s_ca_conf_directory }}" 392 | creates: "{{ k8s_ca_conf_directory }}/cert-{{ item }}-key.pem" 393 | with_inventory_hostnames: 394 | - "{{ k8s_ca_worker_nodes_group }}" 395 | tags: 396 | - kubernetes-ca 397 | 398 | - name: Set file permissions for Kubernetes worker certificate files (1/3) 399 | ansible.builtin.file: 400 | path: "{{ k8s_ca_conf_directory }}/cert-{{ item }}.pem" 401 | owner: "{{ k8s_ca_certificate_owner }}" 402 | group: "{{ k8s_ca_certificate_group }}" 403 | mode: '{{ k8s_ca_file_perm }}' 404 | modification_time: "preserve" 405 | access_time: "preserve" 406 | with_inventory_hostnames: 407 | - "{{ k8s_ca_worker_nodes_group }}" 408 | tags: 409 | - kubernetes-ca 410 | 411 | - name: Set file permissions for Kubernetes worker certificate files (2/3) 412 | ansible.builtin.file: 413 | path: "{{ k8s_ca_conf_directory }}/cert-{{ item }}-key.pem" 414 | owner: "{{ k8s_ca_certificate_owner }}" 415 | group: "{{ k8s_ca_certificate_group }}" 416 | mode: '{{ k8s_ca_file_perm }}' 417 | modification_time: "preserve" 418 | access_time: "preserve" 419 | with_inventory_hostnames: 420 | - "{{ k8s_ca_worker_nodes_group }}" 421 | tags: 422 | - kubernetes-ca 423 | 424 | - name: Set file permissions for Kubernetes worker certificate files (3/3) 425 | ansible.builtin.file: 426 | path: "{{ k8s_ca_conf_directory }}/cert-{{ item }}.csr" 427 | owner: "{{ k8s_ca_certificate_owner }}" 428 | group: "{{ k8s_ca_certificate_group }}" 429 | mode: '{{ k8s_ca_file_perm }}' 430 | modification_time: "preserve" 431 | access_time: "preserve" 432 | with_inventory_hostnames: 433 | - "{{ k8s_ca_worker_nodes_group }}" 434 | tags: 435 | - kubernetes-ca 436 | 437 | - name: Generate TLS certificate for kube-proxy 438 | ansible.builtin.shell: > 439 | set -o errexit; \ 440 | set -o pipefail; \ 441 | cfssl gencert \ 442 | -ca=ca-k8s-apiserver.pem \ 443 | -ca-key=ca-k8s-apiserver-key.pem \ 444 | -config=ca-k8s-apiserver-config.json \ 445 | -profile=kubernetes \ 446 | cert-k8s-proxy-csr.json \ 447 | | cfssljson -bare cert-k8s-proxy 448 | args: 449 | executable: "/bin/bash" 450 | chdir: "{{ k8s_ca_conf_directory }}" 451 | creates: "{{ k8s_ca_conf_directory }}/cert-k8s-proxy-key.pem" 452 | tags: 453 | - kubernetes-ca 454 | 455 | - name: Set file permissions for kube-proxy certificate files 456 | ansible.builtin.file: 457 | path: "{{ k8s_ca_conf_directory }}/{{ item }}" 458 | owner: "{{ k8s_ca_certificate_owner }}" 459 | group: "{{ k8s_ca_certificate_group }}" 460 | mode: '{{ k8s_ca_file_perm }}' 461 | modification_time: "preserve" 462 | access_time: "preserve" 463 | loop: 464 | - cert-k8s-proxy.pem 465 | - cert-k8s-proxy-key.pem 466 | - cert-k8s-proxy.csr 467 | 468 | 469 | - name: Generate TLS certificate for kube-controller-manager 470 | ansible.builtin.shell: > 471 | set -o errexit; \ 472 | set -o pipefail; \ 473 | cfssl gencert \ 474 | -ca=ca-k8s-apiserver.pem \ 475 | -ca-key=ca-k8s-apiserver-key.pem \ 476 | -config=ca-k8s-apiserver-config.json \ 477 | -profile=kubernetes \ 478 | cert-k8s-controller-manager-csr.json \ 479 | | cfssljson -bare cert-k8s-controller-manager 480 | args: 481 | executable: "/bin/bash" 482 | chdir: "{{ k8s_ca_conf_directory }}" 483 | creates: "{{ k8s_ca_conf_directory }}/cert-k8s-controller-manager-key.pem" 484 | tags: 485 | - kubernetes-ca 486 | 487 | - name: Set file permissions for kube-controller-manager certificate files 488 | ansible.builtin.file: 489 | path: "{{ k8s_ca_conf_directory }}/{{ item }}" 490 | owner: "{{ k8s_ca_certificate_owner }}" 491 | group: "{{ k8s_ca_certificate_group }}" 492 | mode: '{{ k8s_ca_file_perm }}' 493 | modification_time: "preserve" 494 | access_time: "preserve" 495 | loop: 496 | - cert-k8s-controller-manager.pem 497 | - cert-k8s-controller-manager-key.pem 498 | - cert-k8s-controller-manager.csr 499 | 500 | - name: Generate TLS certificate for kube-controller-manager service account 501 | ansible.builtin.shell: > 502 | set -o errexit; \ 503 | set -o pipefail; \ 504 | cfssl gencert \ 505 | -ca=ca-k8s-apiserver.pem \ 506 | -ca-key=ca-k8s-apiserver-key.pem \ 507 | -config=ca-k8s-apiserver-config.json \ 508 | -profile=kubernetes \ 509 | cert-k8s-controller-manager-sa-csr.json \ 510 | | cfssljson -bare cert-k8s-controller-manager-sa 511 | args: 512 | executable: "/bin/bash" 513 | chdir: "{{ k8s_ca_conf_directory }}" 514 | creates: "{{ k8s_ca_conf_directory }}/cert-k8s-controller-manager-sa-key.pem" 515 | tags: 516 | - kubernetes-ca 517 | 518 | - name: Set file permissions for kube-controller-manager service account certificate files 519 | ansible.builtin.file: 520 | path: "{{ k8s_ca_conf_directory }}/{{ item }}" 521 | owner: "{{ k8s_ca_certificate_owner }}" 522 | group: "{{ k8s_ca_certificate_group }}" 523 | mode: '{{ k8s_ca_file_perm }}' 524 | modification_time: "preserve" 525 | access_time: "preserve" 526 | loop: 527 | - cert-k8s-controller-manager-sa.pem 528 | - cert-k8s-controller-manager-sa-key.pem 529 | - cert-k8s-controller-manager-sa.csr 530 | 531 | - name: Generate TLS certificate for kube-scheduler 532 | ansible.builtin.shell: > 533 | set -o errexit; \ 534 | set -o pipefail; \ 535 | cfssl gencert \ 536 | -ca=ca-k8s-apiserver.pem \ 537 | -ca-key=ca-k8s-apiserver-key.pem \ 538 | -config=ca-k8s-apiserver-config.json \ 539 | -profile=kubernetes \ 540 | cert-k8s-scheduler-csr.json \ 541 | | cfssljson -bare cert-k8s-scheduler 542 | args: 543 | executable: "/bin/bash" 544 | chdir: "{{ k8s_ca_conf_directory }}" 545 | creates: "{{ k8s_ca_conf_directory }}/cert-k8s-scheduler-key.pem" 546 | tags: 547 | - kubernetes-ca 548 | 549 | - name: Set file permissions for kube-scheduler certificate files 550 | ansible.builtin.file: 551 | path: "{{ k8s_ca_conf_directory }}/{{ item }}" 552 | owner: "{{ k8s_ca_certificate_owner }}" 553 | group: "{{ k8s_ca_certificate_group }}" 554 | mode: '{{ k8s_ca_file_perm }}' 555 | modification_time: "preserve" 556 | access_time: "preserve" 557 | loop: 558 | - cert-k8s-scheduler.pem 559 | - cert-k8s-scheduler-key.pem 560 | - cert-k8s-scheduler.csr 561 | 562 | - name: Create CSR files for etcd clients 563 | ansible.builtin.template: 564 | src: "cert-etcd-client-csr.json.j2" 565 | dest: "{{ k8s_ca_conf_directory }}/cert-{{ item }}-csr.json" 566 | owner: "{{ k8s_ca_certificate_owner }}" 567 | group: "{{ k8s_ca_certificate_group }}" 568 | mode: "{{ k8s_ca_file_perm }}" 569 | loop: "{{ etcd_additional_clients }}" 570 | when: etcd_additional_clients is defined 571 | tags: 572 | - etcd-clients 573 | 574 | - name: Generate certificates for etcd clients 575 | ansible.builtin.shell: > 576 | set -o errexit; \ 577 | set -o pipefail; \ 578 | cfssl gencert \ 579 | -ca=ca-etcd.pem \ 580 | -ca-key=ca-etcd-key.pem \ 581 | -config=ca-etcd-config.json \ 582 | -hostname="" \ 583 | -profile=client \ 584 | cert-{{ item }}-csr.json \ 585 | | cfssljson -bare cert-{{ item }} 586 | loop: "{{ etcd_additional_clients }}" 587 | when: etcd_additional_clients is defined 588 | args: 589 | executable: "/bin/bash" 590 | chdir: "{{ k8s_ca_conf_directory }}" 591 | creates: "{{ k8s_ca_conf_directory }}/cert-{{ item }}-key.pem" 592 | tags: 593 | - etcd-clients 594 | 595 | - name: Set file permissions for etcd client certificate files 596 | ansible.builtin.file: 597 | path: "{{ k8s_ca_conf_directory }}/cert-{{ item[0] }}{{ item[1] }}" 598 | owner: "{{ k8s_ca_certificate_owner }}" 599 | group: "{{ k8s_ca_certificate_group }}" 600 | mode: '{{ k8s_ca_file_perm }}' 601 | modification_time: "preserve" 602 | access_time: "preserve" 603 | loop: "{{ etcd_additional_clients | product(['.pem', '-key.pem', '.csr']) | list }}" 604 | when: etcd_additional_clients is defined 605 | -------------------------------------------------------------------------------- /templates/ca-etcd-config.json.j2: -------------------------------------------------------------------------------- 1 | { 2 | "signing": { 3 | "default": { 4 | "expiry": "{{ ca_etcd_expiry }}" 5 | }, 6 | "profiles": { 7 | "server": { 8 | "expiry": "{{ ca_etcd_expiry }}", 9 | "usages": [ 10 | "signing", 11 | "key encipherment", 12 | "server auth", 13 | "client auth" 14 | ] 15 | }, 16 | "peer": { 17 | "expiry": "{{ ca_etcd_expiry }}", 18 | "usages": [ 19 | "signing", 20 | "key encipherment", 21 | "server auth", 22 | "client auth" 23 | ] 24 | }, 25 | "client": { 26 | "expiry": "{{ ca_etcd_expiry }}", 27 | "usages": [ 28 | "signing", 29 | "key encipherment", 30 | "client auth" 31 | ] 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /templates/ca-etcd-csr.json.j2: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "{{ ca_etcd_csr_cn }}", 3 | "key": { 4 | "algo": "{{ ca_etcd_csr_key_algo }}", 5 | "size": {{ ca_etcd_csr_key_size }} 6 | }, 7 | "names": [ 8 | { 9 | "C": "{{ ca_etcd_csr_names_c }}", 10 | "L": "{{ ca_etcd_csr_names_l }}", 11 | "O": "{{ ca_etcd_csr_names_o }}", 12 | "OU": "{{ ca_etcd_csr_names_ou }}", 13 | "ST": "{{ ca_etcd_csr_names_st }}" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /templates/ca-k8s-apiserver-config.json.j2: -------------------------------------------------------------------------------- 1 | { 2 | "signing": { 3 | "default": { 4 | "expiry": "{{ ca_k8s_apiserver_expiry }}" 5 | }, 6 | "profiles": { 7 | "kubernetes": { 8 | "usages": [ 9 | "signing", 10 | "key encipherment", 11 | "server auth", 12 | "client auth" 13 | ], 14 | "expiry": "{{ ca_k8s_apiserver_expiry }}" 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /templates/ca-k8s-apiserver-csr.json.j2: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "{{ ca_k8s_apiserver_csr_cn }}", 3 | "key": { 4 | "algo": "{{ ca_k8s_apiserver_csr_key_algo }}", 5 | "size": {{ ca_k8s_apiserver_csr_key_size }} 6 | }, 7 | "names": [ 8 | { 9 | "C": "{{ ca_k8s_apiserver_csr_names_c }}", 10 | "L": "{{ ca_k8s_apiserver_csr_names_l }}", 11 | "O": "{{ ca_k8s_apiserver_csr_names_o }}", 12 | "OU": "{{ ca_k8s_apiserver_csr_names_ou }}", 13 | "ST": "{{ ca_k8s_apiserver_csr_names_st }}" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /templates/cert-admin-csr.json.j2: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "{{ k8s_admin_csr_cn }}", 3 | "key": { 4 | "algo": "{{ k8s_admin_csr_key_algo }}", 5 | "size": {{ k8s_admin_csr_key_size }} 6 | }, 7 | "names": [ 8 | { 9 | "C": "{{ k8s_admin_csr_names_c }}", 10 | "L": "{{ k8s_admin_csr_names_l }}", 11 | "O": "{{ k8s_admin_csr_names_o }}", 12 | "OU": "{{ k8s_admin_csr_names_ou }}", 13 | "ST": "{{ k8s_admin_csr_names_st }}" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /templates/cert-etcd-client-csr.json.j2: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "{{ etcd_client_csr_cn_prefix }}-{{ item }}", 3 | "key": { 4 | "algo": "{{ etcd_client_csr_key_algo }}", 5 | "size": {{ etcd_client_csr_key_size }} 6 | }, 7 | "names": [ 8 | { 9 | "C": "{{ etcd_client_csr_names_c }}", 10 | "L": "{{ etcd_client_csr_names_l }}", 11 | "O": "{{ etcd_client_csr_names_o }}", 12 | "OU": "{{ etcd_client_csr_names_ou }}", 13 | "ST": "{{ etcd_client_csr_names_st }}" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /templates/cert-etcd-peer-csr.json.j2: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "{{ etcd_peer_csr_cn }}", 3 | "key": { 4 | "algo": "{{ etcd_peer_csr_key_algo }}", 5 | "size": {{ etcd_peer_csr_key_size }} 6 | }, 7 | "names": [ 8 | { 9 | "C": "{{ etcd_peer_csr_names_c }}", 10 | "L": "{{ etcd_peer_csr_names_l }}", 11 | "O": "{{ etcd_peer_csr_names_o }}", 12 | "OU": "{{ etcd_peer_csr_names_ou }}", 13 | "ST": "{{ etcd_peer_csr_names_st }}" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /templates/cert-etcd-server-csr.json.j2: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "{{ etcd_server_csr_cn }}", 3 | "key": { 4 | "algo": "{{ etcd_server_csr_key_algo }}", 5 | "size": {{ etcd_server_csr_key_size }} 6 | }, 7 | "names": [ 8 | { 9 | "C": "{{ etcd_server_csr_names_c }}", 10 | "L": "{{ etcd_server_csr_names_l }}", 11 | "O": "{{ etcd_server_csr_names_o }}", 12 | "OU": "{{ etcd_server_csr_names_ou }}", 13 | "ST": "{{ etcd_server_csr_names_st }}" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /templates/cert-k8s-apiserver-csr.json.j2: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "{{ k8s_apiserver_csr_cn }}", 3 | "key": { 4 | "algo": "{{ k8s_apiserver_csr_key_algo }}", 5 | "size": {{ k8s_apiserver_csr_key_size }} 6 | }, 7 | "names": [ 8 | { 9 | "C": "{{ k8s_apiserver_csr_names_c }}", 10 | "L": "{{ k8s_apiserver_csr_names_l }}", 11 | "O": "{{ k8s_apiserver_csr_names_o }}", 12 | "OU": "{{ k8s_apiserver_csr_names_ou }}", 13 | "ST": "{{ k8s_apiserver_csr_names_st }}" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /templates/cert-k8s-controller-manager-csr.json.j2: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "{{ k8s_controller_manager_csr_cn }}", 3 | "key": { 4 | "algo": "{{ k8s_controller_manager_csr_key_algo }}", 5 | "size": {{ k8s_controller_manager_csr_key_size }} 6 | }, 7 | "names": [ 8 | { 9 | "C": "{{ k8s_controller_manager_csr_names_c }}", 10 | "L": "{{ k8s_controller_manager_csr_names_l }}", 11 | "O": "{{ k8s_controller_manager_csr_names_o }}", 12 | "OU": "{{ k8s_controller_manager_csr_names_ou }}", 13 | "ST": "{{ k8s_controller_manager_csr_names_st }}" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /templates/cert-k8s-controller-manager-sa-csr.json.j2: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "{{ k8s_controller_manager_sa_csr_cn }}", 3 | "key": { 4 | "algo": "{{ k8s_controller_manager_sa_csr_key_algo }}", 5 | "size": {{ k8s_controller_manager_sa_csr_key_size }} 6 | }, 7 | "names": [ 8 | { 9 | "C": "{{ k8s_controller_manager_sa_csr_names_c }}", 10 | "L": "{{ k8s_controller_manager_sa_csr_names_l }}", 11 | "O": "{{ k8s_controller_manager_sa_csr_names_o }}", 12 | "OU": "{{ k8s_controller_manager_sa_csr_names_ou }}", 13 | "ST": "{{ k8s_controller_manager_sa_csr_names_st }}" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /templates/cert-k8s-proxy-csr.json.j2: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "{{ k8s_kube_proxy_csr_cn }}", 3 | "key": { 4 | "algo": "{{ k8s_kube_proxy_csr_key_algo }}", 5 | "size": {{ k8s_kube_proxy_csr_key_size }} 6 | }, 7 | "names": [ 8 | { 9 | "C": "{{ k8s_kube_proxy_csr_names_c }}", 10 | "L": "{{ k8s_kube_proxy_csr_names_l }}", 11 | "O": "{{ k8s_kube_proxy_csr_names_o }}", 12 | "OU": "{{ k8s_kube_proxy_csr_names_ou }}", 13 | "ST": "{{ k8s_kube_proxy_csr_names_st }}" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /templates/cert-k8s-scheduler-csr.json.j2: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "{{ k8s_scheduler_csr_cn }}", 3 | "key": { 4 | "algo": "{{ k8s_scheduler_csr_key_algo }}", 5 | "size": {{ k8s_scheduler_csr_key_size }} 6 | }, 7 | "names": [ 8 | { 9 | "C": "{{ k8s_scheduler_csr_names_c }}", 10 | "L": "{{ k8s_scheduler_csr_names_l }}", 11 | "O": "{{ k8s_scheduler_csr_names_o }}", 12 | "OU": "{{ k8s_scheduler_csr_names_ou }}", 13 | "ST": "{{ k8s_scheduler_csr_names_st }}" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /templates/cert-worker-csr.json.j2: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "system:node:{{ hostvars[worker_host]['ansible_hostname'] }}", 3 | "key": { 4 | "algo": "{{ k8s_worker_csr_key_algo }}", 5 | "size": {{ k8s_worker_csr_key_size }} 6 | }, 7 | "names": [ 8 | { 9 | "C": "{{ k8s_worker_csr_names_c }}", 10 | "L": "{{ k8s_worker_csr_names_l }}", 11 | "O": "{{ k8s_worker_csr_names_o }}", 12 | "OU": "{{ k8s_worker_csr_names_ou }}", 13 | "ST": "{{ k8s_worker_csr_names_st }}" 14 | } 15 | ] 16 | } 17 | --------------------------------------------------------------------------------