cloudscale-ch / ansible-collection-cloudscale

cloudscale.ch Ansible Collection
https://galaxy.ansible.com/cloudscale_ch/cloud
GNU General Public License v3.0
7 stars 3 forks source link

cloudscale_ch.cloud.server does not work with ansible 6.0 #77

Closed id101010 closed 2 years ago

id101010 commented 2 years ago

Hi all

There seems to be an Issue with the cloudscale_ch.cloud.server module when using ansible 6.0. The module fails with the following error: msg: dictionary requested, could not parse JSON or key=value

Steps to reproduce:

href commented 2 years ago

I am unable to reproduce this on my end. This is what I tried:

First, I created a virtual environment and installed ansible:

python -m venv venv
source venv/bin/activate
pip install ansible

Then, I ran the following playbook using ansible-playbook playbook.yml, after having set my API token using export CLOUDSCALE_API_TOKEN="xxx":

- name: Example playbook
  hosts: localhost
  tasks:
    - cloudscale_ch.cloud.server:
        name: test
        image: debian-10
        flavor: flex-2
        ssh_keys: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMVqyjTfnq2hGSF9lFjr2qyBLicJ3bcD15yk9HVEBzvT denis.krienbuehl@cloudscale.ch
        zone: lpg1

Can you give us some more details on how your server block looks like? I suspect there may be an issue with one of the values of your YAML.

id101010 commented 2 years ago

Hi @href

I was able to further debug the issue and to pinpoint the culprit. The issue is in fact not with the cloudscale_ch.cloud.server module, but consists of a breaking change introduced with Ansible 6.0. Our call to the cloudscale server module is rather complex and includes some customized facts, such as:

- name: assemble interface list
  ansible.builtin.set_fact:
    interfaces: "{{ cloudscale_interfaces_public | default([]) }} + {{ cloudscale_interfaces_private }}"

However, since arithmetic operations and concatenations outside jinja2 templates are not allowed anymore, the list we pass as interface parameter will not be of type list anymore but simply become a string. Hence, the TypeError which gets correctly thrown by your module.

# ansible 5.8.0:
ok: [redacted.example.com] =>
  msg:
  - network: public
  - addresses:
    - address: ''
      subnet: some-network-uuid

# ansible 6.0:
ok: [redacted.example.com] =>
  msg: '[{''network'': ''public''}] + [{''addresses'': [{''subnet'': ''some-network-uuid'', ''address'': ''''}]}]'

So the error is clearly on our end and I apologize deeply for the false accusations :smile:

href commented 2 years ago

No worries, thank you for getting back to us and pointing to the exact cause. Should we stumble upon this as well, we'll already be aware. 🙂