openshift-ansible: call to 'certificates_to_synchronize' causes openshift_master_certificates to abend with 'ERROR! |failed expects hostvars is a dict'
Description
Provide a brief description of your issue here. For example:
On a multi master install deploy_cluster.yml terminates after task “openshift_master_certificates : Generate the loopback master client config” with the error message “ERROR! |failed expects hostvars is a dict”
Version
- oc verions
# oc version
oc v3.7.1+c2ce2c0-1
kubernetes v1.7.6+a08f5eeb62
features: Basic-Auth GSSAPI Kerberos SPNEGO
- Ansible verions
# ansible --version
ansible 2.6.0
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.5 (default, Aug 4 2017, 00:39:18) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)]
- Ansible Openshift Playbooks
# cd /etc/ansible/
# mkdir playbooks
# cd playbooks
# git clone https://github.com/openshift/openshift-ansible
- CentOS version
# cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)
- Openshift version
# openshift version
openshift v3.7.1+c2ce2c0-1
kubernetes v1.7.6+a08f5eeb62
etcd 3.2.8
Inventory Hosts Files
#---- Set variables common for all OSEv3 hosts
[OSEv3:vars]
ansible_ssh_user=root
debug_level='2'
containerized='false'
openshift_deployment_type=origin
os_firewall_use_firewalld='true'
#-- Configure networking
#openshift_master_default_subdomain=fossil.com
openshift_use_openshift_sdn=true
#openshift_use_flannel=true
#flannel_interface=bond0
# Uncomment the following to enable htpasswd authentication; defaults to DenyAllPasswordIdentityProvider.
#openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', 'challenge': 'true', 'kind': 'HTPasswdPasswordIdentityProvider', 'filename': '/etc/origin/master/htpasswd'}]
# Native high availbility cluster method with optional load balancer.
# If no lb group is defined installer assumes that a load balancer has
# been preconfigured. For installation the value of
# openshift_master_cluster_hostname must resolve to the load balancer
# or to one or all of the masters defined in the inventory if no load
# balancer is present.
#-- When we get to production use an external LB
openshift_master_cluster_method=native
#openshift_master_cluster_hostname=uusrcdkub00.fossil.com
#openshift_master_cluster_public_hostname=uusrcdkub00.fossil.com
# apply updated node defaults
openshift_node_kubelet_args={'pods-per-core': ['10'], 'max-pods': ['250'], 'image-gc-high-threshold': ['90'], 'image-gc-low-threshold': ['80']}
# enable ntp on masters to ensure proper failover
openshift_clock_enabled=true
# Setup rolling updates at the service level
openshift_rolling_restart_mode='services'
# Change all the certificates to last for 10 years.
openshift_hosted_registry_cert_expire_days='720'
openshift_ca_cert_expire_days='720'
openshift_node_cert_expire_days='720'
openshift_master_cert_expire_days='720'
etcd_ca_default_days='720'
#---- host group for masters
[masters]
uusrcdkub01.fossil.com
uusrcdkub02.fossil.com
uusrcdkub03.fossil.com
#---- host group for etcd
[etcd]
uusrcdkub01.fossil.com
uusrcdkub02.fossil.com
uusrcdkub03.fossil.com
#---- Specify load balancer host
#[lb]
#uusrcdkub00.fossil.com
#---- host group for nodes, includes region info
[nodes]
uusrcdkub01.fossil.com openshift_schedulable=true openshift_node_labels="{'region': 'infra', 'zone': 'default'}"
uusrcdkub02.fossil.com openshift_schedulable=true openshift_node_labels="{'region': 'infra', 'zone': 'default'}"
uusrcdkub03.fossil.com openshift_schedulable=true openshift_node_labels="{'region': 'infra', 'zone': 'default'}"
# Create an OSEv3 group that contains the master, nodes, etcd, and lb groups.
# The lb group lets Ansible configure HAProxy as the load balancing solution.
# Comment lb out if your load balancer is pre-configured.
[OSEv3:children]
masters
nodes
etcd
#lb
Steps To Reproduce
- After base CentOS 7.3 install
- Install pre-reqs and update the OS
yum -y install wget git net-tools bind-utils iptables-services bridge-utils bash-completion kexec-tools sos psacct curl docker etcd atomic pyOpenSSL.x86_64 python-cryptography python-lxml
yum update
systemctl reboot
- Increase the root volume group to use the complete disk
fdisk /dev/sda
d
2
n
primary
2
default
default
systemctl reboot
pvresize /dev/sda2
- Update the docker config to use a LV for the docker storage
systemctl stop docker
rm -rf /var/lib/docker
vi /etc/sysconfig/docker-storage-setup
# File contents below
/bin/docker-storage-setup
systemctl start docker
systemctl enbale docker
docker info
lvs
File: /etc/sysconfig/docker-storage-setup
# Edit this file to override any configuration options specified in
# /usr/lib/docker-storage-setup/docker-storage-setup.
#
# For more details refer to "man docker-storage-setup"
#STORAGE_DRIVER
#DEVS=/dev/sda
VG=centos
GROWPART=enable
AUTO_EXTEND_POOL=enable
MIN_DATA_SIZE=8G
POOL_AUTOEXTEND_THRESHOLD=60
POOL_AUTOEXTEND_PERCENT=10
- Install Ansible on the first master We need at least Ansible 2.4.3. At the time of writing this doc the latest published was 2.4.2. So, we need to role our own RPM. To build Ansible we need:
yum -y install asciidoc rpm-build python2-devel
- Build and install the latest Ansible
mkdir Development
git clone https://github.com/ansible/ansible.git
cd ansible
make rpm
cd /root/Development/ansible/rpm-build
rpm --install ansible-2.6.0-100.git201803142047.0cf2ecb.devel.el7.centos.noarch.rpm
- Pull the OpenShift Ansible Source
cd /etc/ansible/
mkdir playbooks
cd playbooks
git clone https://github.com/openshift/openshift-ansible
- Create the Ansible Host File
vi /etc/ansbile/hosts
File contents listed above.
- Run the pre-reqs and deploy
cd /etc/ansible/playbooks/openshift-ansible/playbooks/
ansible-playbook -i /etc/ansible/hosts $PWD/prerequisites.yml
cd /etc/ansible/playbooks/openshift-ansible/playbooks/openshift-checks
vi roles/openshift_health_checker/openshift_checks/package_version.py
I updated the allowed docker versions for (3,7) to include 1.13 and 1.13.1
ansible-playbook -i /etc/ansible/hosts $PWD/pre-install.yml
cd /etc/ansible/playbooks/openshift-ansible/playbooks/
ansible-playbook -vvv -i /etc/ansible/hosts $PWD/deploy_cluster.yml
Expected Results
Describe what you expected to happen.
I expected the install and configuration to complete
Observed Results
Everything is chugging along find. The verbose output before the abend is listed below. I don’t see any other errors in the output until this.
TASK [openshift_master_certificates : Generate the loopback master client config] ***************************************************************************************
task path: /etc/ansible/playbooks/openshift-ansible/roles/openshift_master_certificates/tasks/main.yml:63
Using module file /usr/lib/python2.7/site-packages/ansible/modules/commands/command.py
<uusrcdkub01.fossil.com> ESTABLISH SSH CONNECTION FOR USER: root
<uusrcdkub01.fossil.com> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/21d2154973 uusrcdkub01.fossil.com '/bin/sh -c '"'"'echo ~ && sleep 0'"'"''
<uusrcdkub01.fossil.com> (0, '/root\n', '')
<uusrcdkub01.fossil.com> ESTABLISH SSH CONNECTION FOR USER: root
<uusrcdkub01.fossil.com> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/21d2154973 uusrcdkub01.fossil.com '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-tmp-1521658222.4-93760209595884 `" && echo ansible-tmp-1521658222.4-93760209595884="` echo /root/.ansible/tmp/ansible-tmp-1521658222.4-93760209595884 `" ) && sleep 0'"'"''
<uusrcdkub01.fossil.com> (0, 'ansible-tmp-1521658222.4-93760209595884=/root/.ansible/tmp/ansible-tmp-1521658222.4-93760209595884\n', '')
<uusrcdkub01.fossil.com> PUT /root/.ansible/tmp/ansible-local-20837_E4d2Q/tmpbS7CiZ TO /root/.ansible/tmp/ansible-tmp-1521658222.4-93760209595884/command.py
<uusrcdkub01.fossil.com> SSH: EXEC sftp -b - -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/21d2154973 '[uusrcdkub01.fossil.com]'
...
Skip a lot
...
Using module file /usr/lib/python2.7/site-packages/ansible/modules/commands/command.py
<uusrcdkub01.fossil.com> ESTABLISH SSH CONNECTION FOR USER: root
<uusrcdkub01.fossil.com> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/21d2154973 uusrcdkub01.fossil.com '/bin/sh -c '"'"'echo ~ && sleep 0'"'"''
<uusrcdkub01.fossil.com> (0, '/root\n', '')
<uusrcdkub01.fossil.com> ESTABLISH SSH CONNECTION FOR USER: root
<uusrcdkub01.fossil.com> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/21d2154973 uusrcdkub01.fossil.com '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-tmp-1521656686.1-214052715328726 `" && echo ansible-tmp-1521656686.1-214052715328726="` echo /root/.ansible/tmp/ansible-tmp-1521656686.1-214052715328726 `" ) && sleep 0'"'"''
<uusrcdkub01.fossil.com> (0, 'ansible-tmp-1521656686.1-214052715328726=/root/.ansible/tmp/ansible-tmp-1521656686.1-214052715328726\n', '')
<uusrcdkub01.fossil.com> PUT /root/.ansible/tmp/ansible-local-115241x1n7s/tmp4R_seg TO /root/.ansible/tmp/ansible-tmp-1521656686.1-214052715328726/command.py
<uusrcdkub01.fossil.com> SSH: EXEC sftp -b - -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/21d2154973 '[uusrcdkub01.fossil.com]'
<uusrcdkub01.fossil.com> (0, 'sftp> put /root/.ansible/tmp/ansible-local-115241x1n7s/tmp4R_seg /root/.ansible/tmp/ansible-tmp-1521656686.1-214052715328726/command.py\n', '')
<uusrcdkub01.fossil.com> ESTABLISH SSH CONNECTION FOR USER: root
<uusrcdkub01.fossil.com> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/21d2154973 uusrcdkub01.fossil.com '/bin/sh -c '"'"'chmod u+x /root/.ansible/tmp/ansible-tmp-1521656686.1-214052715328726/ /root/.ansible/tmp/ansible-tmp-1521656686.1-214052715328726/command.py && sleep 0'"'"''
<uusrcdkub01.fossil.com> (0, '', '')
<uusrcdkub01.fossil.com> ESTABLISH SSH CONNECTION FOR USER: root
<uusrcdkub01.fossil.com> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/21d2154973 -tt uusrcdkub01.fossil.com '/bin/sh -c '"'"'/usr/bin/python /root/.ansible/tmp/ansible-tmp-1521656686.1-214052715328726/command.py && sleep 0'"'"''
<uusrcdkub01.fossil.com> (0, '\r\n{"invocation": {"module_args": {"warn": true, "executable": null, "_uses_shell": false, "_raw_params": "oc adm create-api-client-config\\n --certificate-authority=/etc/origin/master/ca.crt\\n --client-dir=/etc/origin/generated-configs/master-uusrcdkub03.fossil.com\\n --groups=system:masters,system:openshift-master\\n --master=https://uusrcdkub03.fossil.com:8443\\n --public-master=https://uusrcdkub03.fossil.com:8443\\n --signer-cert=/etc/origin/master/ca.crt\\n --signer-key=/etc/origin/master/ca.key\\n --signer-serial=/etc/origin/master/ca.serial.txt\\n --user=system:openshift-master\\n --basename=openshift-master\\n --expire-days=720", "removes": null, "creates": "/etc/origin/generated-configs/master-uusrcdkub03.fossil.com/openshift-master.kubeconfig", "chdir": null, "stdin": null}}, "cmd": "oc adm create-api-client-config\\n --certificate-authority=/etc/origin/master/ca.crt\\n --client-dir=/etc/origin/generated-configs/master-uusrcdkub03.fossil.com\\n --groups=system:masters,system:openshift-master\\n --master=https://uusrcdkub03.fossil.com:8443\\n --public-master=https://uusrcdkub03.fossil.com:8443\\n --signer-cert=/etc/origin/master/ca.crt\\n --signer-key=/etc/origin/master/ca.key\\n --signer-serial=/etc/origin/master/ca.serial.txt\\n --user=system:openshift-master\\n --basename=openshift-master\\n --expire-days=720", "stdout": "skipped, since /etc/origin/generated-configs/master-uusrcdkub03.fossil.com/openshift-master.kubeconfig exists", "rc": 0, "changed": false}\r\n', 'Shared connection to uusrcdkub01.fossil.com closed.\r\n')
<uusrcdkub01.fossil.com> ESTABLISH SSH CONNECTION FOR USER: root
<uusrcdkub01.fossil.com> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/21d2154973 uusrcdkub01.fossil.com '/bin/sh -c '"'"'rm -f -r /root/.ansible/tmp/ansible-tmp-1521656686.1-214052715328726/ > /dev/null 2>&1 && sleep 0'"'"''
<uusrcdkub01.fossil.com> (0, '', '')
ok: [uusrcdkub01.fossil.com -> uusrcdkub01.fossil.com] => (item=uusrcdkub03.fossil.com) => {
"changed": false,
"cmd": "oc adm create-api-client-config\n --certificate-authority=/etc/origin/master/ca.crt\n --client-dir=/etc/origin/generated-configs/master-uusrcdkub03.fossil.com\n --groups=system:masters,system:openshift-master\n --master=https://uusrcdkub03.fossil.com:8443\n --public-master=https://uusrcdkub03.fossil.com:8443\n --signer-cert=/etc/origin/master/ca.crt\n --signer-key=/etc/origin/master/ca.key\n --signer-serial=/etc/origin/master/ca.serial.txt\n --user=system:openshift-master\n --basename=openshift-master\n --expire-days=720",
"invocation": {
"module_args": {
"_raw_params": "oc adm create-api-client-config\n --certificate-authority=/etc/origin/master/ca.crt\n --client-dir=/etc/origin/generated-configs/master-uusrcdkub03.fossil.com\n --groups=system:masters,system:openshift-master\n --master=https://uusrcdkub03.fossil.com:8443\n --public-master=https://uusrcdkub03.fossil.com:8443\n --signer-cert=/etc/origin/master/ca.crt\n --signer-key=/etc/origin/master/ca.key\n --signer-serial=/etc/origin/master/ca.serial.txt\n --user=system:openshift-master\n --basename=openshift-master\n --expire-days=720",
"_uses_shell": false,
"chdir": null,
"creates": "/etc/origin/generated-configs/master-uusrcdkub03.fossil.com/openshift-master.kubeconfig",
"executable": null,
"removes": null,
"stdin": null,
"warn": true
}
},
"item": "uusrcdkub03.fossil.com",
"rc": 0,
"stdout": "skipped, since /etc/origin/generated-configs/master-uusrcdkub03.fossil.com/openshift-master.kubeconfig exists",
"stdout_lines": [
"skipped, since /etc/origin/generated-configs/master-uusrcdkub03.fossil.com/openshift-master.kubeconfig exists"
]
}
ERROR! |failed expects hostvars is a dict
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 1
- Comments: 30 (6 by maintainers)
Commits related to this issue
- filter_plugins: handle lazy loaded hostvars Ensure that the openshift_master.py filter plugin handles ansible 2.4 and 2.5 hostvars gracefully. This is required due to the changes introduced in ansib... — committed to abn/openshift-ansible by abn 6 years ago
- filter_plugins: handle lazy loaded hostvars Ensure that the openshift_master.py filter plugin handles ansible 2.4 and 2.5 hostvars gracefully. This is required due to the changes introduced in ansib... — committed to section6nz/openshift-ansible by abn 6 years ago
- filter_plugins: handle lazy loaded hostvars Ensure that the openshift_master.py filter plugin handles ansible 2.4 and 2.5 hostvars gracefully. This is required due to the changes introduced in ansib... — committed to abn/openshift-ansible by abn 6 years ago
- filter_plugins: handle lazy loaded hostvars Ensure that the openshift_master.py filter plugin handles ansible 2.4 and 2.5 hostvars gracefully. This is required due to the changes introduced in ansib... — committed to vrutkovs/openshift-ansible by abn 6 years ago
- filter_plugins: handle lazy loaded hostvars Ensure that the openshift_master.py filter plugin handles ansible 2.4 and 2.5 hostvars gracefully. This is required due to the changes introduced in ansib... — committed to vrutkovs/openshift-ansible by abn 6 years ago
OK. I think I understand what’s happening and how I got around the problem, though, I’m at least a week away from knowing enough python to prove/disprove anything.
In /etc/ansible/playbooks/openshift-ansible/roles/openshift_master_certificates/tasks/main.yml around line 63 I simply changed the with_items clause from
- "{{ hostvars[inventory_hostname] | certificates_to_synchronize }}"to- "{{ hostvars[inventory_hostname]['ansible_facts'] | certificates_to_synchronize }}"and everything progressed.I think since the hostvars[inventory] is magic it doesn’t exist as a dictionary until accessed. So, accessing a dictionary variable ansible_facts solves 2 problems of instantiating the variable and passing an actual dictionary to the customer filter.
Don’t know how to raise this as a bug (possible), but if someone in the know ever reads this please let me know if I guessed right as to why the work-a-round worked and how to place this as a bug report.
By changing the below lines it solved for me In /etc/ansible/playbooks/openshift-ansible/roles/openshift_master_certificates/tasks/main.yml around line 63 I simply changed the with_items clause from
The openshift/origin-ansible container v3.9 has the same issue (3.9.33) tag v3.9.28 does work.
BTW, I tested the patch. It worked for me.
I change line 95 in openshift-ansible/roles/openshift_master_certificates/tasks/main.yml and success:
Line 95:
certificates_to_synchronize is a custom filter in lib_utils
#- “{{ hostvars[inventory_hostname] | certificates_to_synchronize }}” to
For release-3.9 and Ansible 2.6.0.0 this solved it for me: https://github.com/abn/openshift-ansible/commit/b20684b6560ecbe5c68b4412069beb2f24960504