--- # Create an OpenShift ServiceAccount with a scoped ClusterRole and long-lived token. # # Requires: ocp_service_account_name, ocp_service_account_namespace, # ocp_service_account_cluster_role_rules # # Registers: __ocp_service_account_token (decoded bearer token) - name: Validate required variables ansible.builtin.assert: that: - ocp_service_account_name | length > 0 - ocp_service_account_namespace | length > 0 - ocp_service_account_cluster_role_rules | length > 0 fail_msg: "ocp_service_account_name, ocp_service_account_namespace, and ocp_service_account_cluster_role_rules are required" - name: Create namespace {{ ocp_service_account_namespace }} kubernetes.core.k8s: state: present definition: apiVersion: v1 kind: Namespace metadata: name: "{{ ocp_service_account_namespace }}" when: ocp_service_account_create_namespace | bool - name: Create ServiceAccount {{ ocp_service_account_name }} kubernetes.core.k8s: state: present definition: apiVersion: v1 kind: ServiceAccount metadata: name: "{{ ocp_service_account_name }}" namespace: "{{ ocp_service_account_namespace }}" labels: app.kubernetes.io/managed-by: ocp-service-account-role - name: Create ClusterRole {{ ocp_service_account_name }} kubernetes.core.k8s: state: present definition: apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: "{{ ocp_service_account_name }}" labels: app.kubernetes.io/managed-by: ocp-service-account-role rules: "{{ ocp_service_account_cluster_role_rules }}" - name: Create ClusterRoleBinding {{ ocp_service_account_name }} kubernetes.core.k8s: state: present definition: apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: "{{ ocp_service_account_name }}" labels: app.kubernetes.io/managed-by: ocp-service-account-role roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: "{{ ocp_service_account_name }}" subjects: - kind: ServiceAccount name: "{{ ocp_service_account_name }}" namespace: "{{ ocp_service_account_namespace }}" - name: Create long-lived token Secret for {{ ocp_service_account_name }} kubernetes.core.k8s: state: present definition: apiVersion: v1 kind: Secret metadata: name: "{{ ocp_service_account_name }}-token" namespace: "{{ ocp_service_account_namespace }}" labels: app.kubernetes.io/managed-by: ocp-service-account-role app.kubernetes.io/instance: "{{ ocp_service_account_name }}" annotations: kubernetes.io/service-account.name: "{{ ocp_service_account_name }}" type: kubernetes.io/service-account-token - name: Wait for token to be populated kubernetes.core.k8s_info: api_version: v1 kind: Secret namespace: "{{ ocp_service_account_namespace }}" name: "{{ ocp_service_account_name }}-token" register: __ocp_sa_token_secret until: >- __ocp_sa_token_secret.resources | length > 0 and (__ocp_sa_token_secret.resources[0].data.token | default('') | length > 0) retries: 12 delay: 5 - name: Register SA token for downstream use ansible.builtin.set_fact: __ocp_service_account_token: "{{ __ocp_sa_token_secret.resources[0].data.token | b64decode }}" no_log: true - name: Display SA token for vault storage ansible.builtin.debug: msg: - "*** SERVICE ACCOUNT TOKEN — SAVE TO 1PASSWORD ***" - "ServiceAccount: {{ ocp_service_account_name }} ({{ ocp_service_account_namespace }})" - "Vault variable: vault_{{ ocp_service_account_name | regex_replace('-', '_') }}_token" - "" - "Token: {{ __ocp_service_account_token }}"