google.cloud icon indicating copy to clipboard operation
google.cloud copied to clipboard

issue with service account key

Open mikamakusa opened this issue 5 years ago • 1 comments

SUMMARY

Hi, I'm running into a problem with gcp_iam_service_account_key...each time I try what's explained on the documentation (here: https://docs.ansible.com/ansible/latest/collections/google/cloud/gcp_iam_service_account_key_module.html#ansible-collections-google-cloud-gcp-iam-service-account-key-module), I get the same error :

File is not a valid GCP JSON service account key

ISSUE TYPE
  • Bug Report
COMPONENT NAME

gcp_iam_service_account_key

ANSIBLE VERSION
ansible 2.9.6
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/mike/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.8.5 (default, Jul 28 2020, 12:59:40) [GCC 9.3.0]
CONFIGURATION
ACTION_WARNINGS(default) = True
AGNOSTIC_BECOME_PROMPT(default) = True
ALLOW_WORLD_READABLE_TMPFILES(default) = False
ANSIBLE_CONNECTION_PATH(default) = None
ANSIBLE_COW_PATH(default) = None
ANSIBLE_COW_SELECTION(default) = default
ANSIBLE_COW_WHITELIST(default) = ['bud-frogs', 'bunny', 'cheese', 'daemon', 'default', 'dragon', 'elephant-in-snake', 'elephant', 'eyes', 'hellokitty', 'kitty', 'luke-koala', 'meow', 'milk', 'moofasa', 'moose', 'ren', 'sheep', 'small', '
stegosaurus', 'stimpy', 'supermilker', 'three-eyes', 'turkey', 'turtle', 'tux', 'udder', 'vader-koala', 'vader', 'www']
ANSIBLE_FORCE_COLOR(default) = False
ANSIBLE_NOCOLOR(default) = False
ANSIBLE_NOCOWS(default) = False
ANSIBLE_PIPELINING(default) = False
ANSIBLE_SSH_ARGS(default) = -C -o ControlMaster=auto -o ControlPersist=60s
ANSIBLE_SSH_CONTROL_PATH(default) = None
ANSIBLE_SSH_CONTROL_PATH_DIR(default) = ~/.ansible/cp
ANSIBLE_SSH_EXECUTABLE(default) = ssh
ANSIBLE_SSH_RETRIES(default) = 0
ANY_ERRORS_FATAL(default) = False
BECOME_ALLOW_SAME_USER(default) = False
BECOME_PLUGIN_PATH(default) = ['/home/mike/.ansible/plugins/become', '/usr/share/ansible/plugins/become']
CACHE_PLUGIN(default) = memory
CACHE_PLUGIN_CONNECTION(default) = None
CACHE_PLUGIN_PREFIX(default) = ansible_facts
CACHE_PLUGIN_TIMEOUT(default) = 86400
COLLECTIONS_PATHS(default) = ['/home/mike/.ansible/collections', '/usr/share/ansible/collections']
COLOR_CHANGED(default) = yellow
COLOR_CONSOLE_PROMPT(default) = white
COLOR_DEBUG(default) = dark gray
COLOR_DEPRECATE(default) = purple
COLOR_DIFF_ADD(default) = green
COLOR_DIFF_LINES(default) = cyan
COLOR_DIFF_REMOVE(default) = red
COLOR_ERROR(default) = red
COLOR_HIGHLIGHT(default) = white
COLOR_OK(default) = green
COLOR_SKIP(default) = cyan
COLOR_UNREACHABLE(default) = bright red
COLOR_VERBOSE(default) = blue
COLOR_WARN(default) = bright purple
COMMAND_WARNINGS(default) = True
CONDITIONAL_BARE_VARS(default) = True
CONNECTION_FACTS_MODULES(default) = {'eos': 'eos_facts', 'frr': 'frr_facts', 'ios': 'ios_facts', 'iosxr': 'iosxr_facts', 'junos': 'junos_facts', 'nxos': 'nxos_facts', 'vyos': 'vyos_facts'}
COVERAGE_REMOTE_OUTPUT(default) = None
COVERAGE_REMOTE_WHITELIST(default) = *
DEFAULT_ACTION_PLUGIN_PATH(default) = ['/home/mike/.ansible/plugins/action', '/usr/share/ansible/plugins/action']
DEFAULT_ALLOW_UNSAFE_LOOKUPS(default) = False
DEFAULT_ASK_PASS(default) = False
DEFAULT_ASK_VAULT_PASS(default) = False
DEFAULT_BECOME(default) = False
DEFAULT_BECOME_ASK_PASS(default) = False
DEFAULT_BECOME_EXE(default) = None
DEFAULT_BECOME_FLAGS(default) = 
DEFAULT_BECOME_METHOD(default) = sudo
DEFAULT_BECOME_USER(default) = root
DEFAULT_CACHE_PLUGIN_PATH(default) = ['/home/mike/.ansible/plugins/cache', '/usr/share/ansible/plugins/cache']
DEFAULT_CALLABLE_WHITELIST(default) = []
DEFAULT_CALLBACK_PLUGIN_PATH(default) = ['/home/mike/.ansible/plugins/callback', '/usr/share/ansible/plugins/callback']
DEFAULT_CALLBACK_WHITELIST(default) = []
OS / ENVIRONMENT

I'm on Ubuntu 20.04

STEPS TO REPRODUCE
main.yml
    - name: "create service Account"
      gcp_iam_service_account:
        name: "gcp-{{ environments }}-{{ buckets }}-sa@{{ project }}.iam.gserviceaccount.com"
        display_name: "gcp-{{ environments }}-{{ buckets }}-sa"
        project: "{{ project }}"
        auth_kind: serviceaccount
        service_account_file: "tf-project-1351-3278615fdb7b.json"
        state: present
      with_items: 
        - buckets
      register: serviceaccount

    - name: "Create Service Account Key file"
      gcp_iam_service_account_key:
        service_account: "{{ serviceaccount }}"
        # key_algorithm: "KEY_ALG_RSA_2048"
        private_key_type: TYPE_GOOGLE_CREDENTIALS_FILE
        path: "{{ project }}.json"
        project: "{{ project }}"
        auth_kind: serviceaccount
        service_account_file: "tf-project-1351-3278615fdb7b.json"
        state: present
      with_items: 
        - buckets
vars.yml
environments: "dev"
buckets: orga
project: "tf-project-1351"
EXPECTED RESULTS

Get the json key from google service account

ACTUAL RESULTS
The full traceback is:
  File "/tmp/ansible_gcp_iam_service_account_key_payload_14828lgb/ansible_gcp_iam_service_account_key_payload.zip/ansible/modules/cloud/google/gcp_iam_service_account_key.py", line 240, in key_name_from_file
  File "/usr/lib/python3.8/json/__init__.py", line 357, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.8/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.8/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
failed: [localhost] (item=buckets) => {
    "ansible_loop_var": "item",
    "changed": false,
    "invocation": {
        "module_args": {
            "auth_kind": "serviceaccount",
            "env_type": null,
            "key_algorithm": null,
            "path": "tf-project-1351.json",
            "private_key_type": "TYPE_GOOGLE_CREDENTIALS_FILE",
            "project": "tf-project-1351",
            "scopes": [
                "https://www.googleapis.com/auth/iam"
            ],
            "service_account": {
                "changed": false,
                "msg": "All items completed",
                "results": [
                    {
                        "ansible_loop_var": "item",
                        "changed": false,
                        "displayName": "gcp-dev-orga-sa",
                        "email": "[email protected]",
                        "etag": "MDEwMjE5MjA=",
                        "failed": false,
                        "invocation": {
                            "module_args": {
                                "auth_kind": "serviceaccount",
                                "display_name": "gcp-dev-orga-sa",
                                "env_type": null,
                                "name": "[email protected]",
                                "project": "tf-project-1351",
                                "scopes": [
                                    "https://www.googleapis.com/auth/iam"
                                ],
                                "service_account_contents": null,
                                "service_account_email": null,
                                "service_account_file": "tf-project-1351-3278615fdb7b.json",
                                "state": "present"
                            }
                        },
                        "item": "buckets",
                        "name": "[email protected]",
                        "oauth2ClientId": "106591229016502380749",
                        "projectId": "tf-project-1351",
                        "uniqueId": "106591229016502380749"
                    }
                ]
            },
            "service_account_contents": null,
            "service_account_email": null,
            "service_account_file": "tf-project-1351-3278615fdb7b.json",
            "state": "present"
        }
    },
    "item": "buckets",
    "msg": "File is not a valid GCP JSON service account key"
}

mikamakusa avatar Feb 04 '21 16:02 mikamakusa

Ran into this problem. You have to delete the file in the path attribute before running the key generation (if it already exists) or the module tries to read it. Try adding this first:

- name: Remove creds file if exists
  ansible.builtin.file:
    path: "{{ project }}.json"
    state: absent

Google, please fix the documentation to make it clear it would read the file if it exists already.

rut31337 avatar May 27 '22 18:05 rut31337

This ansible module is not idempotent. And there's no reason nor technical impediment for this module to be idempotent.

If no key was retrieved, why write an empty file?

ml0renz0 avatar Jun 09 '23 06:06 ml0renz0

If no key was retrieved, why write an empty file?

The module IIUC does not write an empty file. Instead, if a user creates a file there that is not json, the the module attempts to read it.

I've file #576 to update documentation to note the behavior around the file. If there's a better way to handle these, we're definitely open to PRs!

toumorokoshi avatar Jun 10 '23 20:06 toumorokoshi