Jenkins es una de las herramientas de CI/CD (Integración Continua y Despliegue Continuo) más populares que existen. Es muy apreciada en la comunidad tecnológica porque es gratuita, de código abierto y autohospedada. Hay muchas razones por las que podría querer desplegar un servidor Jenkins: para construir proyectos personales, practicar con el software, para uso en producción de la empresa, etc. Sea cual sea su razón, una cosa es segura, desplegar su servidor con Ansible hará que el proceso sea automático, repetible, reutilizable, versionable y compartible. Hoy veremos cómo crear un playbook de Ansible que despliegue Jenkins en un servidor remoto, con un certificado SSL gratuito de Letsencrypt (que se renueva automáticamente).
He subido todo el código de este proyecto aquí en Github.
Vamos a empezar 🚀
1. Adquirir un servidor remoto
El primer paso para desplegar Jenkins en un servidor es adquirir el propio servidor. Un servidor remoto puede ser aprovisionado desde muchos lugares diferentes. Proveedores de la nube como DigitalOcean, Google Cloud, AWS, etc., ofrecen algunos de los planes de VPS (servidor privado virtual) más rentables del mercado. Dependiendo de sus necesidades, puede aprovisionar un servidor ya sea manualmente o a través de IaC (Infraestructura como Código) desde cualquiera de estos proveedores.
Para el propósito de este tutorial, asegúrese de aprovisionar su instancia de servidor con acceso a la internet pública (y por lo tanto a una dirección IPv4 pública).
Se considera una buena práctica ejecutar comandos de ansible en un nodo a través de un usuario dedicado. Para ayudar a acelerar el proceso de creación de un usuario dedicado con los permisos adecuados para Ansible, utilice el siguiente script de inicio userdata para lanzar su VPS.
#cloud-config
ssh_pwauth: false
users:
- name: ansible
gecos: Ansible User
groups: users,admin,wheel
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
lock_passwd: true
ssh_authorized_keys:
- "ssh-public-key"Reemplace "ssh-public-key" con la clave pública SSH adecuada para la conexión a su servidor.
2. Configuración para Ansible
Antes de sumergirnos en la creación de nuestro Playbook, necesitamos configurar algunas cosas para asegurarnos de que nuestro flujo de trabajo tenga éxito.
2.1 Verificar la conectividad SSH al servidor remoto
Ansible se conecta a los servidores de nodo a través de SSH. Dado que estamos tratando con un solo servidor para este tutorial, necesitaremos conectarnos a él inicialmente, de forma manual, para verificar la conectividad.
Parte del proceso de despliegue de un VPS es configurar el acceso SSH a él. Dondequiera que despliegue su VPS, debe tener acceso al archivo de clave privada para la conexión SSH a su servidor.
Inicie una conexión SSH a su servidor utilizando
ssh -i location/to/keyfile username@server_ip Asegúrese de guardar su clave privada SSH de forma segura en su host de Ansible, y haga un seguimiento de su ubicación porque se utilizará en un paso posterior para otorgar a Ansible acceso a su VPS.
2.2 Configurar registros DNS para nuestro dominio Jenkins
Para asegurar el acceso a su servidor Jenkins desde el dominio apropiado, necesita apuntar su nombre de dominio a la dirección IP de su servidor. Esto se logrará creando un A record DNS. Esto se puede hacer de varias maneras diferentes (a través de una variedad de interfaces) dependiendo del Servicio de Nombres de Dominio a cargo de su dominio. Los detalles específicos están fuera del alcance de este tutorial.
Sin el registro DNS configurado correctamente, su Playbook fallará al emitir SSL para su servidor Jenkins porque Certbot (el cliente utilizado para emitir los certificados) será incapaz de verificar que usted controla el dominio para el cual se emitirá el certificado SSL. Esto causará que su despliegue falle, así que asegúrese de configurar el registro DNS apropiado.
2.3 Crear un archivo de configuración de Ansible
Para funcionar correctamente, Ansible necesita configurar algunas cosas importantes. Hacemos esto en el archivo ansible.cfg. Ansible revisa este archivo automáticamente antes de la ejecución, para encontrar las cosas importantes que necesita para funcionar. Nuestro archivo ansible.cfg tendrá el siguiente contenido.
[defaults]
inventory = inventory.txt
private_key_file = key.txt
remote_user = ansibleEste archivo configura las siguientes cosas importantes:
- Le dice a Ansible que nuestro archivo de inventario, el archivo que lista las direcciones de todos los servidores que nos gustaría que ansible administrara, es un archivo llamado
inventory.txty se encuentra en el directorio actual. - Le dice a ansible que el archivo de clave privada para la conectividad SSH al host es un archivo llamado
key.txt, ubicado también en el directorio actual - Configura el nombre de usuario
ansiblepara la conexión SSH al servidor. Este será el caso si configuró su servidor con el script cloud-init proporcionado anteriormente, si no, siéntase libre de cambiar este valor a lo que sea suusername.
De acuerdo con esta configuración, debe almacenar el archivo de clave privada SSH para la conexión al servidor en un archivo llamado key.txt en el directorio actual, para que Ansible pueda encontrarlo.
Recuerde NO registrar su archivo key.txt en el control de versiones. Especialmente en un repositorio público en Github.
Una vez que haya verificado la conectividad SSH a su servidor, haya configurado el registro DNS apropiado y haya creado un archivo de configuración, está listo para crear su Playbook.
3. Crear el Playbook
Es hora de crear su Playbook de Ansible. Para mantener nuestra solución simple y modular, vamos a hacer uso de los roles de Ansible. Aquí hay un resumen de los pasos que conducen a nuestro resultado deseado:
- Configurar un proxy Nginx para Jenkins
- Adquirir un certificado SSL para nuestro servidor
- Instalar Jenkins
Ahora en código:
---
- hosts: all
become: true
roles:
- nginx-proxy
- hosts: all
become: true
roles:
- certbot
- hosts: all
become: true
roles:
- jenkins4. Crear Roles complementarios
A continuación, necesita crear los roles para los diferentes aspectos del flujo de trabajo. La estructura de directorios para sus roles debería verse así:

4.1 Dentro del rol nginx-proxy
Cree un archivo tasks/mail.yml
Con el siguiente contenido:
- name: Install NginX
tags: nginx,install
ansible.builtin.apt:
name: nginx
state: latest
update_cache: true
- name: Enable NginX
ansible.builtin.service:
name: nginx
enabled: true
- name: Config Jenkins Proxy
ansible.builtin.template:
src: "jenkins-proxy.j2"
dest: /etc/nginx/sites-available/jenkins-proxy.conf
owner: root
group: root
mode: 0644
notify: restart_nginx
- name: Enable Proxy
ansible.builtin.file:
src: /etc/nginx/sites-available/jenkins-proxy.conf
dest: /etc/nginx/sites-enabled/jenkins-proxy.conf
state: link
notify: restart_nginxCree un archivo handlers/mail.yml
Con el siguiente contenido:
- name: restart_nginx
ansible.builtin.service:
name: nginx
state: restartedCree un archivo templates/jenkins-proxy.j2
Con el siguiente contenido:
server {
listen 80; # Port for incoming traffic (e.g., 80 for HTTP, 443 for HTTPS)
server_name {{ server_name }}; # Your domain name or IP address
# Location block for handling proxied requests
location / {
proxy_pass {{ jenkins_localhost }}; # Upstream server address (e.g., http://127.0.0.1:8080)
# Optional settings:
proxy_set_header Host $host; # Preserve host header for upstream server
proxy_set_header X-Real-IP $remote_addr; # Forward client IP address
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # Forward proxy chain
# Additional settings as needed (e.g., caching, rewrites)
}
}
4.2 Dentro del rol certbot
Cree un archivo tasks/mail.yml
Con el siguiente contenido:
- name: Install Snapd
ansible.builtin.apt:
name: snapd
state: latest
- name: Install Certbot
community.general.snap:
name: certbot
classic: true
state: present
- name: Create symlink
ansible.builtin.file:
src: /snap/bin/certbot
dest: /usr/bin/certbot
state: link
- name: Run certbot
ansible.builtin.shell:
cmd: certbot --nginx -n --agree-tos --email {{ server_email }} --domains {{ server_name }}4.3 Dentro del rol jenkins
Cree un archivo tasks/mail.yml
Con el siguiente contenido:
- name: Install JDK
ansible.builtin.apt:
pkg:
- fontconfig
- openjdk-17-jre
- name: Get Jenkins Repo Key
ansible.builtin.get_url:
url: https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key
dest: /usr/share/keyrings/jenkins-keyring.asc
- name: Set Jenkins Source
ansible.builtin.lineinfile:
path: /etc/apt/sources.list.d/jenkins.list
line: deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] https://pkg.jenkins.io/debian-stable binary/
create: yes
- name: Install Jenkins
ansible.builtin.apt:
name: jenkins
state: present
update_cache: true
- name: Enable Jenkins
ansible.builtin.service:
name: jenkins
enabled: true5. Configurar las salidas de depuración de Jenkins
La primera vez que configura su servidor Jenkins, para comenzar a usar la interfaz de usuario web, debe recuperar una clave secreta de un archivo en el servidor Jenkins, para demostrar que controla el servidor. Podemos recuperar esta clave y hacer que Ansible nos la muestre agregando las siguientes líneas a nuestro archivo role/jenkins/tasks/main.yml:
- name: Check Jenkins Status
ansible.builtin.shell:
cmd: systemctl status jenkins
register: check_jens
- name: Debug
debug:
msg: "{{ check_jens.stdout_lines }}"Esta adición imprime el valor de
systemctl status jenkins6. Desplegar su playbook
Aquí es donde despliega su Playbook y hace que Jenkins se configure automáticamente. Para desplegar su Playbook debe proporcionar los valores apropiados a las 3 variables definidas en nuestros roles.
- La variable
{{jenkins_localhost}}apunta a la dirección de host local de Jenkins. Esta suele serhttp://localhost:8080 - La variable
{{server_name}}proporciona el nombre de dominio en el que el servidor Jenkins será accesible. Este es el dominio para el que configuró los registros DNS anteriormente. - La variable
{{server_email}}proporciona la dirección de correo electrónico del administrador del servidor (esto es obligatorio).
Puede elegir proporcionar el valor a estas variables de diferentes maneras. Podría proporcionarlos en tiempo de ejecución, en cuyo caso desplegaría su Playbook con el siguiente comando:
ansible-playbook --extra-vars "server_name=domain-name jenkins_localhost=http://127.0.0.1:8080
server_email=email" playbook.yml Reemplazando domain-name y email con los valores apropiados.
Aquí hay un ejemplo:
ansible-playbook --extra-vars "server_name=jen.obimadu.pro
jenkins_localhost=http://127.0.0.1:8080
server_email=hello@obimadu.pro" playbook.ymlPara formas adicionales de proporcionar el valor de las variables, visite Using Variables
Y ESO ES TODO 🎉 🎉 ¡Ahora tiene una forma totalmente automatizada de desplegar (y/o re-desplegar) su Servidor Jenkins!
Leer más
Proyecto Self-Hosting (Infraestructura DevOps desde Cero)
Una guía completa para construir una infraestructura DevOps autoalojada desde cero utilizando Terraform, Ansible y Docker.
Implementación del flujo de trabajo central de Terraform en colaboración, a través de Github Pull Requests, Actions, Bot, Environments y un Backend Remoto.
Implemente un flujo de trabajo colaborativo de Terraform utilizando GitHub Actions, pull requests y un backend remoto para equipos de producción.
Desplegar un servidor en Digital Ocean a través de Terraform (Cómo hacerlo)
Una guía paso a paso para aprovisionar un droplet de DigitalOcean utilizando Terraform y prácticas básicas de Infraestructura como Código.
