Files
elk-jdbc-sso/elk-k8s-deployment/ansible/playbooks/deploy.yml
tsvetkov f98b15fe73 put
2026-02-27 02:57:37 +00:00

352 lines
15 KiB
YAML

---
# =============================================================================
# ELK Stack on Kubernetes (Minikube) — Main Deployment Playbook
# =============================================================================
# Usage:
# ansible-playbook -i inventory/hosts.yml playbooks/deploy.yml
#
# Tags:
# --tags prereqs Install system dependencies
# --tags certs Generate TLS certificates
# --tags minikube Start/configure Minikube
# --tags namespaces Create K8s namespaces
# --tags secrets Create TLS secrets in K8s
# --tags mysql Deploy MySQL
# --tags elasticsearch Deploy Elasticsearch
# --tags es-setup Run Elasticsearch post-setup
# --tags kibana Deploy Kibana
# --tags logstash Deploy Logstash
# --tags nginx Deploy NGINX proxy
# --tags authentik Deploy Authentik SSO
# --tags dns Configure /etc/hosts
# =============================================================================
- name: Deploy ELK Stack on Kubernetes
hosts: localhost
connection: local
gather_facts: true
tasks:
# =======================================================================
# PHASE 1 — Prerequisites
# =======================================================================
- name: Install system prerequisites
tags: [prereqs]
block:
- name: Update apt cache
become: true
ansible.builtin.apt:
update_cache: true
cache_valid_time: 3600
- name: Install required packages
become: true
ansible.builtin.apt:
name:
- curl
- apt-transport-https
- ca-certificates
- gnupg
- lsb-release
- openssl
- docker.io
- conntrack
state: present
- name: Ensure Docker service is running
become: true
ansible.builtin.systemd:
name: docker
state: started
enabled: true
- name: Add current user to docker group
become: true
ansible.builtin.user:
name: "{{ ansible_user_id }}"
groups: docker
append: true
- name: Install kubectl
become: true
ansible.builtin.shell: |
if ! command -v kubectl &>/dev/null; then
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
rm -f kubectl
fi
args:
creates: /usr/local/bin/kubectl
- name: Install minikube
become: true
ansible.builtin.shell: |
if ! command -v minikube &>/dev/null; then
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
install minikube-linux-amd64 /usr/local/bin/minikube
rm -f minikube-linux-amd64
fi
args:
creates: /usr/local/bin/minikube
# =======================================================================
# PHASE 2 — TLS Certificates
# =======================================================================
- name: Generate TLS certificates
tags: [certs]
block:
- name: Create certs directory
ansible.builtin.file:
path: "{{ certs_dir }}"
state: directory
mode: "0755"
- name: Run certificate generation script
ansible.builtin.command:
cmd: bash "{{ scripts_dir }}/generate-certs.sh" "{{ certs_dir }}"
creates: "{{ certs_dir }}/ca.crt"
# =======================================================================
# PHASE 3 — Minikube
# =======================================================================
- name: Start and configure Minikube
tags: [minikube]
block:
- name: Check if Minikube is running
ansible.builtin.command: minikube status --format='{{.Host}}'
register: minikube_status
ignore_errors: true
changed_when: false
- name: Start Minikube
ansible.builtin.command: >
minikube start
--cpus={{ minikube_cpus }}
--memory={{ minikube_memory }}
--disk-size={{ minikube_disk_size }}
--driver={{ minikube_driver }}
--addons=default-storageclass,storage-provisioner
when: minikube_status.rc != 0 or 'Running' not in minikube_status.stdout
- name: Enable ingress addon
ansible.builtin.command: minikube addons enable ingress
changed_when: false
# =======================================================================
# PHASE 4 — Kubernetes Namespaces
# =======================================================================
- name: Create Kubernetes namespaces
tags: [namespaces]
ansible.builtin.command: kubectl apply -f "{{ k8s_manifests_dir }}/namespaces/namespaces.yaml"
changed_when: false
# =======================================================================
# PHASE 5 — TLS Secrets in Kubernetes
# =======================================================================
- name: Create TLS secrets
tags: [secrets]
block:
- name: Delete existing elk-certificates secret (if any)
ansible.builtin.command: kubectl delete secret elk-certificates -n elk --ignore-not-found
changed_when: false
- name: Create elk-certificates secret in elk namespace
ansible.builtin.command: >
kubectl create secret generic elk-certificates -n elk
--from-file=ca.crt={{ certs_dir }}/ca.crt
--from-file=ca.key={{ certs_dir }}/ca.key
--from-file=elasticsearch.crt={{ certs_dir }}/elasticsearch.crt
--from-file=elasticsearch.key={{ certs_dir }}/elasticsearch.key
--from-file=elasticsearch.p12={{ certs_dir }}/elasticsearch.p12
--from-file=http.p12={{ certs_dir }}/elastic-http.p12
--from-file=kibana.crt={{ certs_dir }}/kibana.crt
--from-file=kibana.key={{ certs_dir }}/kibana.key
--from-file=logstash.crt={{ certs_dir }}/logstash.crt
--from-file=logstash.key={{ certs_dir }}/logstash.key
--from-file=nginx.crt={{ certs_dir }}/nginx.crt
--from-file=nginx.key={{ certs_dir }}/nginx.key
--from-file=authentik.crt={{ certs_dir }}/authentik.crt
--from-file=authentik.key={{ certs_dir }}/authentik.key
# =======================================================================
# PHASE 6 — MySQL (database namespace)
# =======================================================================
- name: Deploy MySQL
tags: [mysql]
block:
- name: Apply MySQL manifests
ansible.builtin.command: kubectl apply -f "{{ k8s_manifests_dir }}/mysql/"
changed_when: false
- name: Wait for MySQL to be ready
ansible.builtin.command: >
kubectl wait --for=condition=ready pod -l app=mysql
-n database --timeout=180s
changed_when: false
# =======================================================================
# PHASE 7 — Elasticsearch
# =======================================================================
- name: Deploy Elasticsearch
tags: [elasticsearch]
block:
- name: Apply Elasticsearch manifests
ansible.builtin.command: kubectl apply -f "{{ k8s_manifests_dir }}/elasticsearch/elasticsearch.yaml"
changed_when: false
- name: Wait for Elasticsearch to be ready
ansible.builtin.command: >
kubectl wait --for=condition=ready pod -l app=elasticsearch
-n elk --timeout=300s
changed_when: false
# =======================================================================
# PHASE 8 — Elasticsearch post-setup
# =======================================================================
- name: Run Elasticsearch setup job
tags: [es-setup]
block:
- name: Delete previous setup job (if any)
ansible.builtin.command: kubectl delete job elasticsearch-setup -n elk --ignore-not-found
changed_when: false
- name: Apply setup job
ansible.builtin.command: kubectl apply -f "{{ k8s_manifests_dir }}/elasticsearch/setup-job.yaml"
changed_when: false
- name: Wait for setup job completion
ansible.builtin.command: >
kubectl wait --for=condition=complete job/elasticsearch-setup
-n elk --timeout=120s
changed_when: false
# =======================================================================
# PHASE 9 — Authentik SSO
# =======================================================================
- name: Deploy Authentik SSO
tags: [authentik]
block:
- name: Apply Authentik manifests
ansible.builtin.command: kubectl apply -f "{{ k8s_manifests_dir }}/authentik/"
changed_when: false
- name: Wait for Authentik PostgreSQL
ansible.builtin.command: >
kubectl wait --for=condition=ready pod -l app=authentik-postgresql
-n elk --timeout=120s
changed_when: false
- name: Wait for Authentik Redis
ansible.builtin.command: >
kubectl wait --for=condition=ready pod -l app=authentik-redis
-n elk --timeout=60s
changed_when: false
- name: Wait for Authentik Server
ansible.builtin.command: >
kubectl wait --for=condition=ready pod -l app=authentik-server
-n elk --timeout=180s
changed_when: false
# =======================================================================
# PHASE 10 — Kibana
# =======================================================================
- name: Deploy Kibana
tags: [kibana]
block:
- name: Apply Kibana manifests
ansible.builtin.command: kubectl apply -f "{{ k8s_manifests_dir }}/kibana/"
changed_when: false
- name: Wait for Kibana to be ready
ansible.builtin.command: >
kubectl wait --for=condition=ready pod -l app=kibana
-n elk --timeout=300s
changed_when: false
# =======================================================================
# PHASE 11 — Logstash
# =======================================================================
- name: Deploy Logstash
tags: [logstash]
block:
- name: Apply Logstash manifests
ansible.builtin.command: kubectl apply -f "{{ k8s_manifests_dir }}/logstash/"
changed_when: false
- name: Wait for Logstash to be ready
ansible.builtin.command: >
kubectl wait --for=condition=ready pod -l app=logstash
-n elk --timeout=180s
changed_when: false
# =======================================================================
# PHASE 12 — NGINX Proxy
# =======================================================================
- name: Deploy NGINX reverse proxy
tags: [nginx]
block:
- name: Apply NGINX manifests
ansible.builtin.command: kubectl apply -f "{{ k8s_manifests_dir }}/nginx/"
changed_when: false
- name: Wait for NGINX to be ready
ansible.builtin.command: >
kubectl wait --for=condition=ready pod -l app=nginx
-n elk --timeout=60s
changed_when: false
# =======================================================================
# PHASE 13 — DNS / /etc/hosts
# =======================================================================
- name: Configure local DNS
tags: [dns]
block:
- name: Get Minikube IP
ansible.builtin.command: minikube ip
register: minikube_ip
changed_when: false
- name: Add kibana.elk.local to /etc/hosts
become: true
ansible.builtin.lineinfile:
path: /etc/hosts
regexp: '.*kibana\.elk\.local.*'
line: "{{ minikube_ip.stdout }} kibana.elk.local authentik.elk.local"
state: present
# =======================================================================
# FINAL — Summary
# =======================================================================
- name: Deployment summary
tags: [always]
block:
- name: Get Minikube IP for summary
ansible.builtin.command: minikube ip
register: minikube_ip_final
changed_when: false
ignore_errors: true
- name: Print access information
ansible.builtin.debug:
msg: |
╔══════════════════════════════════════════════════════════════╗
║ ELK Stack Deployment Complete! ║
╠══════════════════════════════════════════════════════════════╣
║ ║
║ Minikube IP: {{ minikube_ip_final.stdout | default('N/A') }}
║ ║
║ Kibana (NGINX proxy): ║
║ https://kibana.elk.local:30443 ║
║ User: elastic / ElasticP@ss2024! ║
║ ║
║ Authentik Admin: ║
║ https://authentik.elk.local:30944 ║
║ User: akadmin / AdminP@ss2024! ║
║ ║
║ Elasticsearch: ║
║ kubectl port-forward svc/elasticsearch 9200:9200 -n elk ║
║ User: elastic / ElasticP@ss2024! ║
║ ║
╚══════════════════════════════════════════════════════════════╝