Abr 24 2022

Registrar un Esclavo de Jenkins con Ansible

Published by at 18:06 under Ansible,Devops,Jenkins

Anteriormente vimos cómo agregar un esclavo Jenkins llamando a una API REST con Curl. ¡Automaticemos esto con Ansible para tener un nuevo nodo disponible en minutos!

Primero necesitará un usuario de Jenkins y su token asociado con los permisos correctos. «Agent connect» y «create» deberían ser suficientes. Simplemente llamaré a este usuario «node». Inicie sesión en Jenkins con este usuario y cree un nuevo token.

Esclavo de Jenkins con Ansible


Los detalles del nuevo nodo deben pasarse a la URL REST. Incrustemos estos ajustes en una template Jinja2 como esta:

{
   "name": "{{ jenkins_node }}",
   "nodeDescription": "slave {{ jenkins_node }}",
   "numExecutors": "{{ jenkins_numExecutors }}",
   "remoteFS": "{{ jenkins_remoteFS }}",
   "labelString": "{{ jenkins_label }}",
   "mode": "EXCLUSIVE",
   "": [
      "hudson.slaves.JNLPLauncher",
      "hudson.slaves.RetentionStrategy$Always"
   ],
   "launcher": {
      "stapler-class": "hudson.slaves.JNLPLauncher",
      "$class": "hudson.slaves.JNLPLauncher",
      "workDirSettings": {
         "disabled": true,
         "workDirPath": "",
         "internalDir": "remoting",
         "failIfWorkDirIsMissing": false
      },
      "tunnel": "",
      "vmargs": ""
   },
   "retentionStrategy": {
      "stapler-class": "hudson.slaves.RetentionStrategy$Always",
      "$class": "hudson.slaves.RetentionStrategy$Always"
   },
   "nodeProperties": {
      "stapler-class-bag": "true",
      "hudson-slaves-EnvironmentVariablesNodeProperty": {
         "env": [
            {
               "key": "JAVA_HOME",
               "value": "{{ java_home }}"
            }
         ]
      },
      "_comment:": {
         "hudson-tools-ToolLocationNodeProperty": {
           "locations": [
               {
                  "key": "hudson.model.JDK$DescriptorImpl@JAVA-8",
                  "home": "/usr/bin/java"
               }
            ]
         }
      }
   }
}


Adapta el modelo según sus necesidades, si quiere un agente SSH por ejemplo.

Las variables que se reemplazarán en la template se pueden definir en el siguiente archivo «predeterminado»:

jenkins_slave_user: jenkins-slave
jenkins_token: xxxxxxde2152xxxxxxaa339exxxxxx48d6
jenkins_user: node
jenkins_url: https://jenkins.domain.lan
jenkins_node: "{{ansible_hostname}}"
jenkins_numExecutors: 4
jenkins_remoteFS: /home/jenkins-slave
jenkins_label: "label_1 label_2 label_3"
java_home: /usr/lib/jvm/java-8-openjdk-amd64/


jenkins_user se conectará al maestro y creará el nuevo nodo, autenticándose con el jenkins_token creado anteriormente.
jenkins_slave_user es el usuario sistema que iniciará el servicio de Jenkins en el nodo.

Ahora podemos agregar una tarea de Ansible a nuestro rol. Primero llamamos a la API REST:

- name: crear el nodo en el maestro Jenkins
  uri:
    url: "{{jenkins_url}}/computer/doCreateItem?name={{ jenkins_node }}&type=hudson.slaves.DumbSlave"
    method: POST
    body_format: form-urlencoded
    force_basic_auth: yes
    user: "{{ jenkins_user }}"
    password: "{{jenkins_token }}"
    body: "json={{ lookup('template', 'node.json.j2', convert_data=False) }}"
    return_content: yes
    status_code: 200, 302, 400
  register: webpage


Agregué el código de retorno 400 en caso de que el nodo ya exista, pero puede eliminarlo si prefiere que se detenga en este caso. Lo paso fail si el error no es ‘ya existe’:

- name: continuar en caso de que el agente ya exista
  fail:
  when: >
          webpage.status == '400'
          and 'already exists' not in webpage.x_error


El servicio agente de Jenkins necesita una clave del maestro para comenzar. La clave está disponible en la página del agente en formato XML.

- name: recuperar el contenido de la página del agente
  uri:
    url: "{{jenkins_url}}/computer/{{jenkins_node}}/slave-agent.jnlp"
    method: POST
    body_format: form-urlencoded
    force_basic_auth: yes
    user: "{{ jenkins_user }}"
    password: "{{ jenkins_token }}"
    return_content: yes
    status_code: 200
  register: slavepage

- name: recuperar la clave contenida en el xml
  xml:
    xmlstring: "{{slavepage.content}}"
    xpath: /jnlp/application-desc/argument
    content: text
  register: secretxml


La clave se almacenará en el archivo /etc/default/jenkins-slave del usuario sistema que se carga cuando se inicia el servicio.
Aquí está la template:

JENKINS_USER="jenkins-slave"
JENKINS_WORKDIR=$(eval echo "~$JENKINS_USER")
JENKINS_URL={{ jenkins_url }}
JENKINS_NODENAME=$(hostname)
JENKINS_SECRET={{ jenkins_secret }}
JAVA_ARGS="-Xmx6g"


Agregue el script de inicio. Ahora podemos copiar estos 2 archivos:

- name: copiar el archivo de configuración de jenkins-slave
  template:
    src: jenkins-slave-default.j2
    dest: /etc/default/jenkins-slave
    owner: jenkins-slave
    group: jenkins-slave
    mode: 0600
  vars:
    jenkins_secret: "{{secretxml.matches[0].argument}}"
  register: jenkins_config

- name: Copiar el init script jenkins-slave
  copy:
    src: jenkins-slave-init
    dest: /etc/init.d/jenkins-slave
    owner: root
    group: root
    mode: 0755


Y nos aseguramos de que el servicio se inicie correctamente:

- name: reiniciar y activar el servicio jenkins-slave si es necesario
  service:
    name: jenkins-slave
    enabled: yes
    state: restarted
  when: jenkins_config.changed

- name: iniciar y activar el servicio jenkins-slave
  service:
    name: jenkins-slave
    enabled: yes
    state: started


Estos pasos son los básicos, pero puede hacer mucho más, como agregar la creación de usuario sistema Jenkins, agregar su propia CA si tiene una IP privada y mucho más.

Vea también cómo acelerar Ansible y optimizar sus tiempos de implementación.


No responses yet

Comments RSS

Leave a Reply