Prepend string to list item and turn it into JSON in Ansible

Viewed 116

I have a list of ports

ports:
  - 123
  - 456
  - 789

that I like to turn into containerPort for usage in a Kubernetes deployment:

"container_ports": [
            {
                "containerPort": 123
            },
            {
                "containerPort": 456
            },
            {
                "containerPort": 789
            }
        ]

The example above is created when I define ports as

ports:
  - containerPort: 123
  - containerPort: 456
  - containerPort: 789

However, I'd like to save the user some typing and add containerPort automatically. I am able to prepend it using

- name: Creating custom ports
  set_fact:
    container_ports: "{{ ports | map('regex_replace', '(^)', '- containerPort: \\1') | list }}"
  when: ports is defined

This does only create

    ok: [localhost] => {
        "container_ports": [
            "- containerPort: 123",
            "- containerPort: 456",
            "- containerPort: 789"
        ]
    }

though, which is close, but not quite right.

2 Answers

You can do this like so:

---
- hosts: localhost
  connection: local
  gather_facts: no
  vars:
    ports:
      - 123
      - 456

  tasks:
    - name: Creating custom ports
      set_fact:
        container_ports: '{{ ports | map("regex_replace", "^(.*)$", "containerPort: \1") | map("from_yaml") | list }}'
    - debug:
        var: container_ports
...

The trick is to convert each item into a YAML hash and then convert that to a Python dict using from_yaml.

Debug output:

ok: [localhost] => {
    "container_ports": [
        {
            "containerPort": 123
        }, 
        {
            "containerPort": 456
        }
    ]
}

An other solution using json_query

---
- hosts: localhost
  gather_facts: false

  vars:
    ports:
      - 123
      - 456

  tasks:
    - name: Tranform raw list to Kubernetes compatible format
      debug:
        msg: "{{ ports | json_query('[].{\"containerPort\": @}') }}"

Which gives:

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

TASK [Tranform raw list to Kubernetes compatible format] *******************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": [
        {
            "containerPort": 123
        },
        {
            "containerPort": 456
        }
    ]
}

PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Related