ansible-collections / google.cloud

GCP Ansible Collection https://galaxy.ansible.com/google/cloud
https://cloud.google.com
GNU General Public License v3.0
99 stars 129 forks source link

Behaviour of kubectl_path of gcp_container_cluster is unintutive, deprecated and undocumented #255

Open krichter722 opened 4 years ago

krichter722 commented 4 years ago
SUMMARY

Specifying the parameter kubectl_path of gcp_container_cluster seems to cause the master auth credentials to be written to the kubeconfig file created at the specified path (judging from the exception below). This is

ISSUE TYPE
COMPONENT NAME

gcp_container_cluster

ANSIBLE VERSION
ansible-playbook 2.9.2
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.6/site-packages/ansible
  executable location = /usr/local/bin/ansible-playbook
  python version = 3.6.8 (default, Aug  7 2019, 17:28:10) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]

and

  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.6/site-packages/ansible
  executable location = /usr/local/bin/ansible-playbook
  python version = 3.6.8 (default, Aug  7 2019, 17:28:10) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
CONFIGURATION
No config file found; using defaults
OS / ENVIRONMENT

Docker image centos/centos7

STEPS TO REPRODUCE

Build

FROM centos:centos7

RUN yum upgrade -y && yum install -y epel-release git
RUN yum install -y python3-pip openssh-clients && yum clean all
RUN git clone https://github.com/ansible/ansible.git && cd ansible && pip3 install . && cd .. && rm -rf ansible
RUN pip3 install --upgrade pip lxml requests google-auth

with docker build -t dev . and run docker run -v "$(pwd):/mnt" -it dev sh -c 'cd /mnt; ansible-config dump --only-changed; ansible-playbook --ask-vault-pass install_gke_cluster.yml -vvv' with playbook

---
- hosts: localhost
  roles:
    - role: k8s.cluster.gke
...

and task roles/k8s.cluster.gke/tasks/main.yml:

- name: "Create Google Kubernetes Engine Cluster"
  gcp_container_cluster:
    name: "{{cluster_name}}"
    project: "{{project_id}}"
    auth_kind: "serviceaccount"
    location: "{{cluster_location}}"
    logging_service: "none"
    monitoring_service: "none"
    service_account_contents: "{{service_account_contents}}"
    initial_node_count: 1
    kubectl_path: "/tmp/1"
  register: cluster

put values in roles/k8s.cluster.gke/defaults/main.yml as I can't give you my GKE credentials :)

EXPECTED RESULTS

kubeconfig to be created in /tmp/1 (what gcloud container clusters create creates in .kube/config). The kubeconfig should contain token-based credentials as that is what gcloud creates.

If you tackle the feature request aspect and provide token-based authentication, then you still might want to support username/password authentication for backwards compatibility. Therefore the failure below should be handle more gracefully, at least with an intuitive error message that doesn't require to look into the source code.

Both the current requirement for master credentials and how to get a token-based kubeconfig (as soon as implemented) should be documented.

ACTUAL RESULTS

The command fails due to

host_list declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
script declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
auto declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
yaml declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
ini declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
toml declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
[WARNING]: No inventory was parsed, only implicit localhost is available

[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAYBOOK: install_gke_cluster.yml *********************************************************************************************************************************************************************************
1 plays in install_gke_cluster.yml

PLAY [localhost] **************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************************************************************************************************
task path: /mnt/install_gke_cluster.yml:2
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: root
<127.0.0.1> EXEC /bin/sh -c 'echo ~root && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-tmp-1577455971.2539594-163372358451818 `" && echo ansible-tmp-1577455971.2539594-163372358451818="` echo /root/.ansible/tmp/ansible-tmp-1577455971.2539594-163372358451818 `" ) && sleep 0'
Using module file /usr/local/lib/python3.6/site-packages/ansible/modules/system/setup.py
<127.0.0.1> PUT /root/.ansible/tmp/ansible-local-7udgzyfs8/tmpaeb2oavb TO /root/.ansible/tmp/ansible-tmp-1577455971.2539594-163372358451818/AnsiballZ_setup.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp-1577455971.2539594-163372358451818/ /root/.ansible/tmp/ansible-tmp-1577455971.2539594-163372358451818/AnsiballZ_setup.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python3 /root/.ansible/tmp/ansible-tmp-1577455971.2539594-163372358451818/AnsiballZ_setup.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-tmp-1577455971.2539594-163372358451818/ > /dev/null 2>&1 && sleep 0'
ok: [localhost]
META: ran handlers

TASK [k8s.cluster.gke : Create Google Kubernetes Engine Cluster] **************************************************************************************************************************************************
task path: /mnt/roles/k8s.cluster.gke/tasks/main.yml:1
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: root
<127.0.0.1> EXEC /bin/sh -c 'echo ~root && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-tmp-1577455972.5203164-148877134187943 `" && echo ansible-tmp-1577455972.5203164-148877134187943="` echo /root/.ansible/tmp/ansible-tmp-1577455972.5203164-148877134187943 `" ) && sleep 0'
Using module file /usr/local/lib/python3.6/site-packages/ansible/modules/cloud/google/gcp_container_cluster.py
<127.0.0.1> PUT /root/.ansible/tmp/ansible-local-7udgzyfs8/tmpwxrdvmj0 TO /root/.ansible/tmp/ansible-tmp-1577455972.5203164-148877134187943/AnsiballZ_gcp_container_cluster.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp-1577455972.5203164-148877134187943/ /root/.ansible/tmp/ansible-tmp-1577455972.5203164-148877134187943/AnsiballZ_gcp_container_cluster.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python3 /root/.ansible/tmp/ansible-tmp-1577455972.5203164-148877134187943/AnsiballZ_gcp_container_cluster.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-tmp-1577455972.5203164-148877134187943/ > /dev/null 2>&1 && sleep 0'
The full traceback is:
Traceback (most recent call last):
  File "/root/.ansible/tmp/ansible-tmp-1577455972.5203164-148877134187943/AnsiballZ_gcp_container_cluster.py", line 102, in <module>
    _ansiballz_main()
  File "/root/.ansible/tmp/ansible-tmp-1577455972.5203164-148877134187943/AnsiballZ_gcp_container_cluster.py", line 94, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File "/root/.ansible/tmp/ansible-tmp-1577455972.5203164-148877134187943/AnsiballZ_gcp_container_cluster.py", line 40, in invoke_module
    runpy.run_module(mod_name='ansible.modules.cloud.google.gcp_container_cluster', init_globals=None, run_name='__main__', alter_sys=True)
  File "/usr/lib64/python3.6/runpy.py", line 205, in run_module
    return _run_module_code(code, init_globals, run_name, mod_spec)
  File "/usr/lib64/python3.6/runpy.py", line 96, in _run_module_code
    mod_name, mod_spec, pkg_name, script_name)
  File "/usr/lib64/python3.6/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/tmp/ansible_gcp_container_cluster_payload_d0jf0pd_/ansible_gcp_container_cluster_payload.zip/ansible/modules/cloud/google/gcp_container_cluster.py", line 2055, in <module>
  File "/tmp/ansible_gcp_container_cluster_payload_d0jf0pd_/ansible_gcp_container_cluster_payload.zip/ansible/modules/cloud/google/gcp_container_cluster.py", line 1373, in main
  File "/tmp/ansible_gcp_container_cluster_payload_d0jf0pd_/ansible_gcp_container_cluster_payload.zip/ansible/modules/cloud/google/gcp_container_cluster.py", line 1598, in write_file
  File "/tmp/ansible_gcp_container_cluster_payload_d0jf0pd_/ansible_gcp_container_cluster_payload.zip/ansible/modules/cloud/google/gcp_container_cluster.py", line 1634, in _contents
KeyError: 'username'

fatal: [localhost]: FAILED! => {
    "changed": false,
    "module_stderr": "Traceback (most recent call last):\n  File \"/root/.ansible/tmp/ansible-tmp-1577455972.5203164-148877134187943/AnsiballZ_gcp_container_cluster.py\", line 102, in <module>\n    _ansiballz_main()\n  File \"/root/.ansible/tmp/ansible-tmp-1577455972.5203164-148877134187943/AnsiballZ_gcp_container_cluster.py\", line 94, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/root/.ansible/tmp/ansible-tmp-1577455972.5203164-148877134187943/AnsiballZ_gcp_container_cluster.py\", line 40, in invoke_module\n    runpy.run_module(mod_name='ansible.modules.cloud.google.gcp_container_cluster', init_globals=None, run_name='__main__', alter_sys=True)\n  File \"/usr/lib64/python3.6/runpy.py\", line 205, in run_module\n    return _run_module_code(code, init_globals, run_name, mod_spec)\n  File \"/usr/lib64/python3.6/runpy.py\", line 96, in _run_module_code\n    mod_name, mod_spec, pkg_name, script_name)\n  File \"/usr/lib64/python3.6/runpy.py\", line 85, in _run_code\n    exec(code, run_globals)\n  File \"/tmp/ansible_gcp_container_cluster_payload_d0jf0pd_/ansible_gcp_container_cluster_payload.zip/ansible/modules/cloud/google/gcp_container_cluster.py\", line 2055, in <module>\n  File \"/tmp/ansible_gcp_container_cluster_payload_d0jf0pd_/ansible_gcp_container_cluster_payload.zip/ansible/modules/cloud/google/gcp_container_cluster.py\", line 1373, in main\n  File \"/tmp/ansible_gcp_container_cluster_payload_d0jf0pd_/ansible_gcp_container_cluster_payload.zip/ansible/modules/cloud/google/gcp_container_cluster.py\", line 1598, in write_file\n  File \"/tmp/ansible_gcp_container_cluster_payload_d0jf0pd_/ansible_gcp_container_cluster_payload.zip/ansible/modules/cloud/google/gcp_container_cluster.py\", line 1634, in _contents\nKeyError: 'username'\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
    "rc": 1
}

PLAY RECAP ********************************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   
agoose77 commented 4 years ago

I just ran into this as well. For now, the best user-space solution seems to be running gcloud itself to generate the kubeconfig file, and then depend upon that role for the subsequent cluster operations.

bogd commented 5 months ago

Was this ever fixed? Because I got here looking for a solution to the exact same problem. And installing and running gcloud just to get the cluster credentials is... clunky (to say the least).