With Ansible, I want to find which port is available in a range on a K8s cluster and use this port to expose a service temporary.
I'm able to find and extract the port but when I'm declaring the Nodeport using that port the tasks fail.
It seems that ansible is not converting my "port" variable to an int with the instruction {{ port|int }}.
- block:
- name: List all ports in range 32200 to 32220
wait_for:
port: "{{ item|int }}"
timeout: 1
state: stopped
msg: "Port {{ item }} is already in use"
register: available_ports
with_sequence: start=32200 end=32220
ignore_errors: yes
- name: extract first unused port from list
set_fact:
port: "{{ available_ports.results | json_query(\"[? state=='stopped'].port\") | first }}"
- debug:
var: port
- name: Expose service as a nodeport service
k8s:
state: present
definition:
apiVersion: v1
kind: Service
metadata:
name: "{{ namespace }}-service-nodeport"
namespace: "{{ namespace }}"
spec:
type: NodePort
selector:
component: my-app
ports:
- protocol: TCP
targetPort: 5432
nodePort: "{{ port|int }}"
port: 5432
This outputs the following:
TASK [../roles/my-role : debug] ***************************************************************************************************************************************************************************************************
ok: [127.0.0.1] => {
"port": "32380"
}
TASK [../roles/my-role : Expose service as a nodeport service] *******************************************************************************************************************************************
fatal: [127.0.0.1]: FAILED! => {"changed": false, "error": 400, "msg": "Failed to create object: b'{\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"Service in version \\\\\"v1\\\\\" cannot be handled as a Service: v1.Service.Spec: v1.ServiceSpec.Ports: []v1.ServicePort: v1.ServicePort.NodePort: readUint32: unexpected character: \\\\ufffd, error found in #10 byte of ...|dePort\\\\\": \\\\\"32380\\\\\", \\\\\"p|..., bigger context ...|rotocol\\\\\": \\\\\"TCP\\\\\", \\\\\"targetPort\\\\\": 5432, \\\\\"nodePort\\\\\": \\\\\"32380\\\\\", \\\\\"port\\\\\": 5432}]}}|...\",\"reason\":\"BadRequest\",\"code\":400}\\n'", "reason": "Bad Request", "status": 400}
If I set the nodeport to a fix value such as 32800, it works.