Ansible: Obtain api_token from gce_container_cluster

10/13/2019

I launch the GCP cluster with no problem but I do not know how to get k8s ansible module to work. I would prefer to get the api_key to authenticate into k8s module.

My playbook is the following.

- name: Hello k8s
  hosts: all
  tasks:
    - name: Create a cluster
      register: cluster
      gcp_container_cluster:
        name: thecluster
        initial_node_count: 1
        master_auth:
          username: admin
          password: TheRandomPassword
        node_config:
          machine_type: g1-small
          disk_size_gb: 10
          oauth_scopes:
            - "https://www.googleapis.com/auth/compute"
            - "https://www.googleapis.com/auth/devstorage.read_only"
            - "https://www.googleapis.com/auth/logging.write"
            - "https://www.googleapis.com/auth/monitoring"
        zone: europe-west3-c
        project:  second-network-255214 
        auth_kind: serviceaccount
        service_account_file: "{{ lookup('env', 'GOOGLE_CREDENTIALS') }}"
        state: present 
    - name: Show results
      debug: var=cluster
    - name: Create temporary file for CA
      tempfile:
        state: file
        suffix: build
      register: ca_crt
    - name: Save content to file
      copy: 
        content: "{{ cluster.masterAuth.clusterCaCertificate |b64decode }}"
        dest: "{{ ca_crt.path }}"
    - name: Create a k8s namespace
      k8s:
        host: "https://{{ cluster.endpoint }}"
        ca_cert: "{{ ca_crt.path }}"
        api_key: "{{ cluster.HOW_I_GET_THE_API_KEY}}" <<<-- Here is what I want!!!
        name: testing
        api_version: v1
        kind: Namespace
        state: present 

Any idea?

-- user2108278
ansible
google-compute-engine
google-kubernetes-engine
kubernetes

2 Answers

10/14/2019

According to the fine manual, masterAuth contains two other fields, clientCertificate and clientKey that correspond to the client_cert: and client_key: parameters, respectively. From that point, you can authenticate to your cluster's endpoint as cluster-admin using the very, very strong credentials of the private key, and from that point use the same k8s: task to provision yourself a cluster-admin ServiceAccount token if you wish to do that.

You can also apparently use masterAuth.username and masterAuth.password in the username: and password: parameters of k8s:, too, which should be just as safe since the credentials travel over HTTPS, but you seemed like you were more interested in a higher entropy authentication solution.

-- mdaniel
Source: StackOverflow

10/14/2019

I founded a workaround that is to call gcloud directly:

    - name: Get JWT
      command: gcloud auth application-default print-access-token
      register: api_key

Obviously, I needed to:

  • Install GCloud
  • Redefine the envvar with the auth.json to GOOGLE_APPLICATION_CREDENTIALS.

The task calls gcloud directly to obtain the token, so no need to generate the token. I will try to add to add this feature as a module into ansible for better interoperability with kubernetes.

Once obtained it is possible to call k8s module like this:

    - name: Create ClusterRoleBinding
      k8s:
        state: present
        host: "https://{{ cluster.endpoint }}"
        ca_cert: "{{ ca_crt.path }}"
        api_version: rbac.authorization.k8s.io/v1
        api_key: "{{ api_key.stdout }}"
        definition:
          kind: ClusterRoleBinding
          metadata:
            name: kube-system_default_cluster-admin
          subjects:
          - kind: ServiceAccount
            name: default # Name is case sensitive
            namespace: kube-system
          roleRef:
            kind: ClusterRole
            name: cluster-admin
            apiGroup: rbac.authorization.k8s.io
-- user2108278
Source: StackOverflow