From 44bce4b274195bcce0f3cbc8a3efe05ef6fc646b Mon Sep 17 00:00:00 2001 From: Nikolai Rodionov Date: Sat, 11 Mar 2023 18:18:57 +0100 Subject: [PATCH] Migrate the role to a separate repo --- README.md | 34 ++++++++ defaults/main.yml | 52 +++++++++++++ handlers/main.yml | 5 ++ kubernetes-create-user.yaml | 8 ++ meta/main.yml | 14 ++++ tasks/main.yml | 151 ++++++++++++++++++++++++++++++++++++ templates/config.j2 | 19 +++++ templates/role-binding.j2 | 13 ++++ vars/main.yml | 1 + 9 files changed, 297 insertions(+) create mode 100644 README.md create mode 100644 defaults/main.yml create mode 100644 handlers/main.yml create mode 100644 kubernetes-create-user.yaml create mode 100644 meta/main.yml create mode 100644 tasks/main.yml create mode 100644 templates/config.j2 create mode 100644 templates/role-binding.j2 create mode 100644 vars/main.yml diff --git a/README.md b/README.md new file mode 100644 index 0000000..4916ade --- /dev/null +++ b/README.md @@ -0,0 +1,34 @@ +Kubernetes RBAC +========= + +Add user to k8s cluster drom control plain node + +Role Variables +-------------- +Will add soon + +Dependencies +------------ + +Example Playbook +---------------- + +Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: + +--- +- hosts: k8s_master + become: no + roles: + - role: '.' + +License +------- + +BSD + +Author Information +------------------ + +Feel free to contribute + +If you got something to say, send me an email (allanger@protonmail.com) diff --git a/defaults/main.yml b/defaults/main.yml new file mode 100644 index 0000000..91083f6 --- /dev/null +++ b/defaults/main.yml @@ -0,0 +1,52 @@ +--- +# -------------------------------------- +# -- yq version +# -------------------------------------- +yq: + version: v4.31.2 + binary: yq_linux_amd64 +# -------------------------------------- +# -- Path to k8s admin config +# -------------------------------------- +k8s_config_path: /etc/kubernetes/admin.conf +k8s_cert_path: /etc/kubernetes/pki +k8s_cert_crt_file: ca.crt +k8s_cert_key_file: ca.key +# -------------------------------------- +# -- K8s username +# -------------------------------------- +username: "admin" +# -------------------------------------- +# -- How many days certificate +# -- will be valid +# -------------------------------------- +certificate_expires_in: 500 +# -------------------------------------- +# -- K8s cluster name +# -------------------------------------- +cluster: "microk8s-cluster" +# -------------------------------------- +# -- RoleBinding parameters +# -------------------------------------- +# -- Binding type: +# ---- ClusterRoleBinding +# ---- RoleBinding +# -------------------------------------- +binding_type: ClusterRoleBinding +# -------------------------------------- +# -- Role type +# -- ClusterRole +# -- Role +# -------------------------------------- +role_type: ClusterRole +# -------------------------------------- +# -- Cluster role name +# -- https://kubernetes.io/docs/reference/access-authn-authz/rbac/ +# -------------------------------------- +role: cluster-admin + +# -------------------------------------- +# -- Use with microk8s +# -------------------------------------- +# k8s_config_path: /var/snap/microk8s/current/credentials/client.config +# k8s_cert_path: /var/snap/microk8s/current/certs diff --git a/handlers/main.yml b/handlers/main.yml new file mode 100644 index 0000000..d8af5f1 --- /dev/null +++ b/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: remove certificates + file: + state: absent + path: "{{ working_dir }}" \ No newline at end of file diff --git a/kubernetes-create-user.yaml b/kubernetes-create-user.yaml new file mode 100644 index 0000000..4163320 --- /dev/null +++ b/kubernetes-create-user.yaml @@ -0,0 +1,8 @@ +# -------------------------------------- +# -- Initialize kubernetes cluster +# -------------------------------------- +--- +- hosts: k8s_master + become: no + roles: + - role: '.' diff --git a/meta/main.yml b/meta/main.yml new file mode 100644 index 0000000..e192866 --- /dev/null +++ b/meta/main.yml @@ -0,0 +1,14 @@ +galaxy_info: + author: Allen Languor + description: Create k8s user + license: license (GPL-2.0-or-later, MIT, etc) + min_ansible_version: 2.1 + platforms: + - name: Ubuntu + versions: + - 20.04 + - 18.04 + + galaxy_tags: + - kubernetes + - rbac diff --git a/tasks/main.yml b/tasks/main.yml new file mode 100644 index 0000000..0b3b475 --- /dev/null +++ b/tasks/main.yml @@ -0,0 +1,151 @@ +# -------------------------------------- +# -- Create kubernetes user +# -------------------------------------- +# -- 1. Install packages +# -- 2. Generate certificate +# -- 3. Add user to kubernetes +# -- 4. Remove certificates (Optional) +# -------------------------------------- +--- +- name: Prepare working directory + block: + - name: Set workdir as fact + set_fact: + working_dir: "{{ working_dir | ansible_env.HOME }}/.certs/{{ username }}" + + - name: Create a directory if it does not exist + ansible.builtin.file: + path: "{{ working_dir }}" + state: directory + mode: "0775" + +- name: Ensure required packages are installed + tags: packages + block: + # ------------------------- + # -- Prepare kubectl repo + # ------------------------- + - name: Add an apt signing key for Kubernetes + become: yes + apt_key: + url: https://packages.cloud.google.com/apt/doc/apt-key.gpg + state: present + + - name: Adding apt repository for Kubernetes + become: yes + apt_repository: + repo: deb https://apt.kubernetes.io/ kubernetes-xenial main + state: present + filename: kubernetes.list + + # -------------------------------------- + # -- Install yq + # -------------------------------------- + - name: Ensure yq is installed + become: yes + get_url: + url: "https://github.com/mikefarah/yq/releases/download/{{ yq.version }}/{{ yq.binary }}" + dest: /usr/bin/yq + mode: "0777" + + - name: Ensure kubectl and openssl are installed + become: yes + package: + name: "{{ packages }}" + state: present + vars: + packages: + - kubectl + - openssl + +- name: Generate openssl certificate + tags: openssl + block: + - name: Generate an OpenSSL private key + community.crypto.openssl_privatekey: + path: "{{ working_dir }}/{{ username }}.key" + size: 2048 + + - name: Generate an OpenSSL Certificate Signing Request + community.crypto.openssl_csr: + path: "{{ working_dir }}/{{ username }}.csr" + privatekey_path: "{{ working_dir }}/{{ username }}.key" + common_name: "{{ username }}" + + - name: Generate an OpenSSL certificate signed with your own CA certificate + become: yes + community.crypto.x509_certificate: + path: "{{ working_dir }}/{{ username }}.crt" + csr_path: "{{ working_dir }}/{{ username }}.csr" + ownca_path: "{{ k8s_cert_path }}/{{ k8s_cert_crt_file }}" + ownca_privatekey_path: "{{ k8s_cert_path }}/{{ k8s_cert_key_file }}" + provider: ownca + entrust_not_after: "+{{ certificate_expires_in }}d" + +- name: Add user to cluster + block: + # -------------------------------------- + # -- Get k8s server from admin.conf + # -------------------------------------- + - name: Get k8s server + shell: yq e '.clusters[0] | select(.name == "{{ cluster }}").cluster.server' "{{ k8s_config_path }}" + register: kubernetes_server_output + # -------------------------------------- + # -- Get k8s certificate authority data + # -- from admin-conf + # -------------------------------------- + - name: Get k8s certificate authority data + shell: yq e '.clusters[0] | select(.name == "{{ cluster }}").cluster.certificate-authority-data' "{{ k8s_config_path }}" + register: kubernetes_cad_output + + - name: Get user cert data + shell: cat "{{ working_dir }}/{{ username }}.crt" | base64 -w 0 + register: user_cert_data_output + + - name: Get user key data + shell: cat "{{ working_dir }}/{{ username }}.key" | base64 -w 0 + register: user_key_data_output + + - name: Set variables for template + set_fact: + kubernetes_server: "{{ kubernetes_server_output.stdout }}" + kubernetes_cad: "{{ kubernetes_cad_output.stdout }}" + user_cert_data: " {{ user_cert_data_output.stdout }}" + user_key_data: " {{ user_key_data_output.stdout }}" + + - name: Create k8s user + ansible.builtin.shell: | + kubectl config set-credentials "{{ username }}"\ + --client-certificate="{{ working_dir }}/{{ username }}.crt" \ + --client-key="{{ working_dir }}/{{ username }}.key" + notify: remove certificates + + - name: Set user context + ansible.builtin.shell: | + kubectl config set-context "{{ username }}@{{ cluster }}" \ + --cluster={{ cluster }} --user="{{ username }}" + + - name: Create config file from template + template: + src: config.j2 + dest: "{{ working_dir }}/config" + + - name: Storing config on the local machine + ansible.builtin.fetch: + src: "{{ working_dir }}/config" + dest: ./ + flat: yes + tags: config + +- name: Bind user to role + block: + - name: Generate role binding yaml + template: + src: role-binding.j2 + dest: "{{ working_dir }}/{{ username }}.yaml" + + - name: Apply role binding manifest + environment: + KUBECONFIG: "{{ k8s_config_path }}" + shell: kubectl apply -f "{{ working_dir }}/{{ username }}.yaml" + tags: add_user diff --git a/templates/config.j2 b/templates/config.j2 new file mode 100644 index 0000000..f9b98d8 --- /dev/null +++ b/templates/config.j2 @@ -0,0 +1,19 @@ +apiVersion: v1 +clusters: +- cluster: + certificate-authority-data: {{ kubernetes_cad }} + server: {{ kubernetes_server }} + name: {{ cluster }} +contexts: +- context: + cluster: {{ cluster }} + user: {{ username }} + name: {{ username }}@{{ cluster }} +current-context: {{ username }}@{{ cluster }} +kind: Config +preferences: {} +users: +- name: {{ username }} + user: + client-certificate-data: {{ user_cert_data }} + client-key-data: {{ user_key_data }} \ No newline at end of file diff --git a/templates/role-binding.j2 b/templates/role-binding.j2 new file mode 100644 index 0000000..c0b3221 --- /dev/null +++ b/templates/role-binding.j2 @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: {{ binding_type}} +metadata: + name: {{ username }} + namespace: {{ k8s_namespace | default("default") }} +subjects: +- kind: User + name: {{ username }} + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: {{ role_type }} + name: {{ role }} + apiGroup: rbac.authorization.k8s.io \ No newline at end of file diff --git a/vars/main.yml b/vars/main.yml new file mode 100644 index 0000000..ed97d53 --- /dev/null +++ b/vars/main.yml @@ -0,0 +1 @@ +---