snowdrop / k8s-infra

Information to bootstrap vms using dedicated server, local machine and setup using Ansible Playbooks
Apache License 2.0
29 stars 14 forks source link

{{ my_hostvars.ansible_user }}: 'str object' has no attribute 'ansible_user' #191

Closed cmoulliard closed 3 years ago

cmoulliard commented 3 years ago

Issue

This playbook command

ansible-playbook $K8S_INFRA/hetzner/ansible/hetzner-create-server.yml -e vm_name=${VM_NAME}
-e salt_text=$(gpg --gen-random --armor 1 20) 
-e hetzner_context_name=snowdrop 
-e pass_provider=hetzner 
-e k8s_type=masters 
-e k8s_version=${k8s_version}

generates this error

TASK [hetzner/create_server : Template cloudinit file] *****************************************************************************************************************************************************************
task path: /Users/cmoullia/code/snowdrop/infra-jobs-productization/k8s-infra/ansible/roles/hetzner/create_server/tasks/main.yml:37
fatal: [localhost]: FAILED! => {"changed": false, 
"msg": "AnsibleUndefinedVariable: {{ my_hostvars.ansible_user }}: 
'str object' has no attribute 'ansible_user'"}

How to reproduce

export k8s_version=118
export VM_NAME=h01-${k8s_version}
export PASSWORD_STORE_DIR=~/.password-store-snowdrop
export K8S_INFRA=~/code/snowdrop/infra-jobs-productization/k8s-infra
export ANSIBLE_ROLES_PATH="$K8S_INFRA/ansible/roles"

ansible-playbook $K8S_INFRA/hetzner/ansible/hetzner-delete-server.yml -e vm_name=${VM_NAME} -e hetzner_context_name=snowdrop
ansible-playbook $K8S_INFRA/ansible/playbook/passstore_controller_inventory_remove.yml -e vm_name=${VM_NAME}  -e pass_provider=hetzner
ansible-playbook $K8S_INFRA/ansible/playbook/passstore_controller_inventory.yml -e vm_name=${VM_NAME}  -e pass_provider=hetzner -e k8s_type=masters -e k8s_version=${k8s_version} -e operation=create
ansible-playbook $K8S_INFRA/hetzner/ansible/hetzner-create-server.yml -e vm_name=${VM_NAME} -e salt_text=$(gpg --gen-random --armor 1 20) -e hetzner_context_name=snowdrop -e pass_provider=hetzner -e k8s_type=masters -e k8s_version=${k8s_version}
ansible-playbook $K8S_INFRA/ansible/playbook/sec_host.yml -e vm_name=${VM_NAME} -e provider=hetzner
cmoulliard commented 3 years ago

The fix should be

    - include_role:
        name: hetzner/create_server
      vars:
        vm_name: "{{ vm_name }}"
        # os_user: "{{ my_hostvars.ansible_user }}"
        os_user: "{{ query('passwordstore', 'hetzner/'+vm_name+'/os_user')[0] }}"
cmoulliard commented 3 years ago

The problem that some variables are not available such also the timeZone,ansible_user comes from the fact that we execute the commands outside of the project k8s-infra :-(

If I run now the project under k8-infra, then that will work

export k8s_version=118
export VM_NAME=h01-${k8s_version}
export PASSWORD_STORE_DIR=~/.password-store-snowdrop

ansible-playbook hetzner/ansible/hetzner-delete-server.yml -e vm_name=${VM_NAME} -e hetzner_context_name=snowdrop
ansible-playbook ansible/playbook/passstore_controller_inventory_remove.yml -e vm_name=${VM_NAME}  -e pass_provider=hetzner
ansible-playbook ansible/playbook/passstore_controller_inventory.yml -e vm_name=${VM_NAME} -e pass_provider=hetzner -e k8s_type=masters -e k8s_version=${k8s_version} -e operation=create
ansible-playbook hetzner/ansible/hetzner-create-server.yml -e vm_name=${VM_NAME} -e salt_text=$(gpg --gen-random --armor 1 20) -e hetzner_context_name=snowdrop -e pass_provider=hetzner -e k8s_type=masters -e k8s_version=${k8s_version}

WDYT and suggest to do then ? @jacobdotcosta

jacobdotcosta commented 3 years ago

This information should be obtained from the ansible inventory in place.

The timezone variable is defined for all hosts in the ansible/inventory/hosts.yml inventory file.

On the other hand there should be no need to query the passwordstore database directly because we have a dynamic inventory python script that builds the hosts inventory with information from passwordstore. This script is located at ansible/inventory/pass_inventory.py.

All this assumes that the playbook execution uses the inventory located at ansible/inventory.

jacobdotcosta commented 3 years ago

This configuration is being defined in the ansible.cfg file. If the script is being executed from somewhere else then there are options.

One is to use this configuration by defining the ANSIBLE_CONFIG environment variable - https://docs.ansible.com/ansible/latest/reference_appendices/config.html#envvar-ANSIBLE_CONFIG

The other is to select the inventory location when executing the ansible-playbook.

-i INVENTORY, --inventory INVENTORY, --inventory-file INVENTORY
                        specify inventory host path or comma separated host list. --inventory-file is deprecated