Jenkins ist eines der beliebtesten CI/CD-Tools (Continuous Integration und Continuous Deployment) auf dem Markt. Es wird in der Tech-Community sehr geschätzt, da es kostenlos, Open Source und selbst gehostet ist. Es gibt viele Gründe, warum Sie einen Jenkins-Server bereitstellen möchten: zum Erstellen persönlicher Projekte, zum Üben mit der Software, für den produktiven Einsatz im Unternehmen usw. Was auch immer Ihr Grund ist, eines ist sicher: Wenn Sie Ihren Server mit Ansible bereitstellen, wird der Prozess automatisch, wiederholbar, wiederverwendbar, versionierbar und teilbar. Heute werden wir durchgehen, wie man ein Ansible-Playbook erstellt, das Jenkins auf einem Remote-Server bereitstellt, mit einem kostenlosen Letsencrypt-SSL-Zertifikat (das sich automatisch verlängert).
Ich habe die gesamte Codebasis für dieses Projekt hier auf Github hochgeladen.
Lassen Sie uns eintauchen 🚀
1. Einen Remote-Server erwerben
Der erste Schritt zur Bereitstellung von Jenkins auf einem Server besteht darin, den Server selbst zu erwerben. Ein Remote-Server kann an vielen verschiedenen Orten bereitgestellt werden. Cloud-Anbieter wie DigitalOcean, Google Cloud, AWS usw. bieten einige der kostengünstigsten VPS-Pläne (Virtual Private Server) auf dem Markt an. Abhängig von Ihren Anforderungen können Sie einen Server entweder manuell oder über IaC (Infrastructure as Code) von einem dieser Anbieter bereitstellen.
Stellen Sie für dieses Tutorial sicher, dass Sie Ihre Serverinstanz mit Zugriff auf das öffentliche Internet (und damit mit einer öffentlichen IPv4-Adresse) bereitstellen.
Es gilt als Best Practice, ansible-Befehle auf einem Node über einen dedizierten Benutzer auszuführen. Um den Prozess der Erstellung eines dedizierten Benutzers mit den entsprechenden Berechtigungen für Ansible zu beschleunigen, verwenden Sie das folgende userdata-Startskript, um Ihren VPS zu starten.
#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"Ersetzen Sie "ssh-public-key" durch den entsprechenden öffentlichen SSH-Schlüssel für die Verbindung zu Ihrem Server.
2. Setup für Ansible
Bevor wir uns in die Erstellung unseres Playbooks stürzen, müssen wir einige Dinge einrichten, um sicherzustellen, dass unser Workflow erfolgreich ist.
2.1 SSH-Konnektivität zum Remote-Server überprüfen
Ansible verbindet sich mit Node-Servern über SSH. Da wir uns in diesem Tutorial mit einem einzelnen Server befassen, müssen wir uns zunächst manuell mit ihm verbinden, um die Konnektivität zu überprüfen.
Ein Teil des Prozesses der Bereitstellung eines VPS ist die Einrichtung des SSH-Zugriffs darauf. Wo auch immer Sie Ihren VPS bereitstellen, sollten Sie Zugriff auf die private Schlüsseldatei für die SSH-Verbindung zu Ihrem Server haben.
Initiieren Sie eine SSH-Verbindung zu Ihrem Server mit
ssh -i location/to/keyfile username@server_ip Stellen Sie sicher, dass Sie Ihren privaten SSH-Schlüssel sicher auf Ihrem Ansible-Host speichern und seinen Speicherort im Auge behalten, da er in einem nächsten Schritt verwendet wird, um Ansible Zugriff auf Ihren VPS zu gewähren.
2.2 DNS-Einträge für unsere Jenkins-Domain einrichten
Um den Zugriff auf Ihren Jenkins-Server über die entsprechende Domain sicherzustellen, müssen Sie Ihren Domainnamen auf die IP-Adresse Ihres Servers verweisen lassen. Dies wird durch das Erstellen eines DNS-A record erreicht. Dies kann auf verschiedene Weise (über eine Vielzahl von Schnittstellen) erfolgen, abhängig von dem Domain Name Service, der für Ihre Domain zuständig ist. Die genauen Details sprengen den Rahmen dieses Tutorials.
Ohne den richtig gesetzten DNS-Eintrag wird Ihr Playbook kein SSL für Ihren Jenkins-Server ausstellen können, da Certbot (der Client, der zur Ausstellung der Zertifikate verwendet wird) nicht überprüfen kann, ob Sie die Domain kontrollieren, für die das SSL-Zertifikat ausgestellt werden soll. Dies wird dazu führen, dass Ihre Bereitstellung fehlschlägt. Stellen Sie also sicher, dass Sie den entsprechenden DNS-Eintrag einrichten.
2.3 Erstellen einer Ansible-Konfigurationsdatei
Damit Ansible richtig funktioniert, müssen einige wichtige Dinge konfiguriert werden. Wir machen dies in der Datei ansible.cfg. Ansible sucht vor der Ausführung automatisch nach dieser Datei, um die wichtigen Dinge zu finden, die es für seine Funktion benötigt. Unsere ansible.cfg-Datei wird folgenden Inhalt haben.
[defaults]
inventory = inventory.txt
private_key_file = key.txt
remote_user = ansibleDiese Datei konfiguriert die folgenden wichtigen Dinge:
- Sie teilt Ansible mit, dass unsere Inventardatei, die Datei, die die Adressen aller Server auflistet, die Ansible verwalten soll, eine Datei namens
inventory.txtist und im aktuellen Verzeichnis zu finden ist. - Sie teilt Ansible mit, dass die private Schlüsseldatei für die SSH-Konnektivität zum Host eine Datei namens
key.txtist, die sich ebenfalls im aktuellen Verzeichnis befindet. - Sie konfiguriert den Benutzernamen
ansiblefür die SSH-Verbindung zum Server. Dies ist der Fall, wenn Sie Ihren Server mit dem zuvor bereitgestellten cloud-init-Skript konfiguriert haben. Wenn nicht, können Sie diesen Wert gerne in den tatsächlichenusernameändern.
In Übereinstimmung mit dieser Konfiguration sollten Sie die private SSH-Schlüsseldatei für die Verbindung zum Server in einer Datei namens key.txt im aktuellen Verzeichnis speichern, damit Ansible sie finden kann.
Denken Sie daran, Ihre key.txt-Datei NICHT in die Versionskontrolle einzuchecken. Insbesondere nicht in ein öffentliches Repository auf Github.
Sobald Sie die SSH-Konnektivität zu Ihrem Server überprüft, den entsprechenden DNS-Eintrag eingerichtet und eine Konfigurationsdatei erstellt haben, können Sie Ihr Playbook erstellen.
3. Das Playbook erstellen
Es ist Zeit, Ihr Ansible-Playbook zu erstellen. Um unsere Lösung einfach und modular zu halten, werden wir Ansible-Rollen verwenden. Hier ist eine Zusammenfassung der Schritte, die zu unserem gewünschten Ergebnis führen:
- Richten Sie einen Nginx-Proxy für Jenkins ein
- Erwerben Sie ein SSL-Zertifikat für unseren Server
- Installieren Sie Jenkins
Jetzt im Code:
---
- hosts: all
become: true
roles:
- nginx-proxy
- hosts: all
become: true
roles:
- certbot
- hosts: all
become: true
roles:
- jenkins4. Dazugehörige Rollen erstellen
Als Nächstes müssen Sie die Rollen für die verschiedenen Aspekte des Workflows erstellen. Die Verzeichnisstruktur für Ihre Rollen sollte wie folgt aussehen:

4.1 Innerhalb der Rolle nginx-proxy
Erstellen Sie eine tasks/mail.yml-Datei
Mit folgendem Inhalt:
- 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_nginxErstellen Sie eine handlers/mail.yml-Datei
Mit folgendem Inhalt:
- name: restart_nginx
ansible.builtin.service:
name: nginx
state: restartedErstellen Sie eine templates/jenkins-proxy.j2-Datei
Mit folgendem Inhalt:
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 Innerhalb der Rolle certbot
Erstellen Sie eine tasks/mail.yml-Datei
Mit folgendem Inhalt:
- 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 Innerhalb der Rolle jenkins
Erstellen Sie eine tasks/mail.yml-Datei
Mit folgendem Inhalt:
- 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. Jenkins-Debug-Ausgaben konfigurieren
Wenn Sie Ihren Jenkins-Server zum allerersten Mal einrichten, müssen Sie, um die Web-Benutzeroberfläche nutzen zu können, einen geheimen Schlüssel aus einer Datei auf dem Jenkins-Server abrufen, um zu beweisen, dass Sie den Server kontrollieren. Wir können diesen Schlüssel abrufen und ihn uns von Ansible ausgeben lassen, indem wir die folgenden Zeilen zu unserer role/jenkins/tasks/main.yml-Datei hinzufügen:
- name: Check Jenkins Status
ansible.builtin.shell:
cmd: systemctl status jenkins
register: check_jens
- name: Debug
debug:
msg: "{{ check_jens.stdout_lines }}"Diese Ergänzung gibt den Wert von aus
systemctl status jenkins6. Ihr Playbook bereitstellen
Hier stellen Sie Ihr Playbook bereit und lassen Jenkins automatisch für sich einrichten. Um Ihr Playbook bereitzustellen, müssen Sie den 3 Variablen, die über unsere Rollen hinweg definiert sind, geeignete Werte zuweisen.
- Die Variable
{{jenkins_localhost}}verweist auf die localhost-Adresse von Jenkins. Dies ist normalerweisehttp://localhost:8080 - Die Variable
{{server_name}}gibt den Domainnamen an, unter dem der Jenkins-Server erreichbar sein soll. Dies ist die Domain, für die Sie zuvor DNS-Einträge vorgenommen haben. - Die Variable
{{server_email}}gibt die E-Mail-Adresse des Serveradministrators an (dies ist erforderlich).
Sie können den Wert für diese Variablen auf verschiedene Weise angeben. Sie können sie zur Laufzeit angeben, in diesem Fall würden Sie Ihr Playbook mit dem folgenden Befehl bereitstellen:
ansible-playbook --extra-vars "server_name=domain-name jenkins_localhost=http://127.0.0.1:8080
server_email=email" playbook.yml Ersetzen Sie domain-name und email durch geeignete Werte.
Hier ist ein Beispiel:
ansible-playbook --extra-vars "server_name=jen.obimadu.pro
jenkins_localhost=http://127.0.0.1:8080
server_email=hello@obimadu.pro" playbook.ymlFür weitere Möglichkeiten, den Wert der Variablen bereitzustellen, besuchen Sie Using Variables
UND DAS IST ES 🎉 🎉 Sie haben nun einen vollständig automatisierten Weg, Ihren Jenkins-Server bereitzustellen (und/oder neu bereitzustellen)!
Mehr lesen
Self-Hosting-Projekt (DevOps-Infra from Scratch)
Ein umfassender Leitfaden zum Aufbau einer selbstgehosteten DevOps-Infrastruktur von Grund auf mit Terraform, Ansible und Docker.
Implementierung des Terraform-Kern-Workflows in Zusammenarbeit über Github Pull Requests, Actions, Bot, Environments & ein Remote-Backend.
Implementieren Sie einen kollaborativen Terraform-Workflow unter Verwendung von GitHub Actions, Pull Requests und einem Remote-Backend für Produktionsteams.
Einen Server auf Digital Ocean über Terraform bereitstellen (HowTo)
Eine Schritt-für-Schritt-Anleitung zur Bereitstellung eines DigitalOcean-Droplets mit Terraform und grundlegenden Infrastructure as Code-Praktiken.
