Restore from Gitea ZIP snapshot (12.08.2026) after full instance reinstall
Git history was lost when the previous Gitea instance was wiped and reinstalled due to an unresolved corruption bug — this commit is the last known-good file content, exported before the reinstall. Prior commit history is not recoverable through this path.
This commit is contained in:
+11
@@ -0,0 +1,11 @@
|
|||||||
|
FROM semaphoreui/semaphore:latest
|
||||||
|
|
||||||
|
USER root
|
||||||
|
|
||||||
|
# Установка kubectl (latest stable на 2025)
|
||||||
|
RUN curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" && \
|
||||||
|
chmod +x kubectl && \
|
||||||
|
mv kubectl /usr/local/bin/kubectl && \
|
||||||
|
kubectl version --client
|
||||||
|
|
||||||
|
USER semaphore
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
- name: Utility - Change User Password
|
||||||
|
hosts: masters,workers
|
||||||
|
gather_facts: false
|
||||||
|
vars:
|
||||||
|
# Переменная requested_password придет из Survey в Semaphore
|
||||||
|
target_user: "ubuntu"
|
||||||
|
tasks:
|
||||||
|
- name: Update password for {{ target_user }} using chpasswd
|
||||||
|
become: true
|
||||||
|
# Мы передаем пароль через стандартный поток ввода (stdin) прямо в системную утилиту
|
||||||
|
shell: "echo '{{ target_user }}:{{ requested_password }}' | chpasswd"
|
||||||
|
# Чтобы пароль не светился в логах Semaphore даже в режиме Debug
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Confirm update
|
||||||
|
debug:
|
||||||
|
msg: "Password for {{ target_user }} has been updated successfully."
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
---
|
||||||
|
- name: Stage 1 - Terraform Infrastructure
|
||||||
|
hosts: localhost
|
||||||
|
connection: local
|
||||||
|
gather_facts: false
|
||||||
|
become: false
|
||||||
|
vars:
|
||||||
|
tf_dir: "{{ playbook_dir }}/../terraform"
|
||||||
|
tasks:
|
||||||
|
- name: Create terraform mirror config
|
||||||
|
copy:
|
||||||
|
dest: "/tmp/.terraformrc"
|
||||||
|
content: |
|
||||||
|
provider_installation {
|
||||||
|
network_mirror { url = "https://terraform-mirror.yandexcloud.net/" }
|
||||||
|
direct { exclude = ["registry.terraform.io/*/*"] }
|
||||||
|
}
|
||||||
|
|
||||||
|
- name: Cleanup old terraform files
|
||||||
|
shell: "rm -rf .terraform .terraform.lock.hcl"
|
||||||
|
args:
|
||||||
|
chdir: "{{ tf_dir }}"
|
||||||
|
|
||||||
|
- name: Terraform Init and Apply
|
||||||
|
shell: |
|
||||||
|
terraform init -reconfigure -no-color && \
|
||||||
|
terraform apply -auto-approve -no-color -lock=false
|
||||||
|
args:
|
||||||
|
chdir: "{{ tf_dir }}"
|
||||||
|
register: tf_result
|
||||||
|
ignore_errors: true
|
||||||
|
environment:
|
||||||
|
TF_CLI_CONFIG_FILE: "/tmp/.terraformrc"
|
||||||
|
TF_HTTP_ADDRESS: "{{ lookup('env', 'TF_HTTP_ADDRESS') }}"
|
||||||
|
TF_HTTP_USERNAME: "{{ lookup('env', 'TF_HTTP_USERNAME') }}"
|
||||||
|
TF_HTTP_PASSWORD: "{{ lookup('env', 'TF_HTTP_PASSWORD') }}"
|
||||||
|
TF_VAR_proxmox_api_token_id: "{{ lookup('env', 'TF_VAR_proxmox_api_token_id') }}"
|
||||||
|
TF_VAR_proxmox_api_token_secret: "{{ lookup('env', 'TF_VAR_proxmox_api_token_secret') }}"
|
||||||
|
TF_VAR_proxmox_api_url: "{{ lookup('env', 'TF_VAR_proxmox_api_url') }}"
|
||||||
|
|
||||||
|
- name: Add Master to memory
|
||||||
|
add_host:
|
||||||
|
name: "k8s-master"
|
||||||
|
groups: ["masters_group", "k8s_nodes"]
|
||||||
|
ansible_host: "10.33.33.201"
|
||||||
|
ansible_user: "ubuntu"
|
||||||
|
ansible_ssh_extra_args: "-o StrictHostKeyChecking=no"
|
||||||
|
|
||||||
|
- name: Add Workers to memory
|
||||||
|
add_host:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
groups: ["workers_group", "k8s_nodes"]
|
||||||
|
ansible_host: "{{ item.ip }}"
|
||||||
|
ansible_user: "ubuntu"
|
||||||
|
ansible_ssh_extra_args: "-o StrictHostKeyChecking=no"
|
||||||
|
loop:
|
||||||
|
- { name: 'k8s-worker-1', ip: '10.33.33.202' }
|
||||||
|
- { name: 'k8s-worker-2', ip: '10.33.33.203' }
|
||||||
|
|
||||||
|
- name: Stage 2 - Wait for SSH
|
||||||
|
hosts: k8s_nodes
|
||||||
|
gather_facts: false
|
||||||
|
tasks:
|
||||||
|
- name: Wait for connection
|
||||||
|
wait_for_connection:
|
||||||
|
timeout: 300
|
||||||
|
|
||||||
|
- name: Stage 3 - Install K8s
|
||||||
|
import_playbook: change_password.yml
|
||||||
|
|
||||||
|
- name: Stage 4 - Install K8s
|
||||||
|
import_playbook: k8s_setup.yml
|
||||||
|
|
||||||
|
- name: Stage 5 - Final Config
|
||||||
|
import_playbook: k8s_post_install.yml
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
---
|
||||||
|
- name: Deploy latest stable AWX using AWX Operator on Kubernetes
|
||||||
|
hosts: localhost
|
||||||
|
connection: local
|
||||||
|
become: false
|
||||||
|
gather_facts: false
|
||||||
|
|
||||||
|
vars:
|
||||||
|
# Основные параметры — переопределяй в Semaphore Variable Group
|
||||||
|
awx_namespace: awx
|
||||||
|
awx_instance_name: awx
|
||||||
|
awx_service_type: NodePort # NodePort / ClusterIP / LoadBalancer
|
||||||
|
awx_operator_version: 2.19.1 # Последняя стабильная на декабрь 2025
|
||||||
|
kubeconfig_path: "/home/semaphore/.kube/config"
|
||||||
|
awx_storage_class: local-path # Предполагаем k3s или аналогичный кластер с local-path provisioner. Изменить на свой SC
|
||||||
|
awx_projects_persistence: false # Отключаем persistence для projects для теста (чтобы избежать PVC проблем)
|
||||||
|
awx_projects_storage_size: 8Gi # Если persistence: true
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Fail if kubeconfig not found inside container
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: "{{ kubeconfig_path }}"
|
||||||
|
register: kubeconfig_stat
|
||||||
|
failed_when: not kubeconfig_stat.stat.exists
|
||||||
|
delegate_to: localhost
|
||||||
|
|
||||||
|
- name: Create namespace for AWX
|
||||||
|
kubernetes.core.k8s:
|
||||||
|
state: present
|
||||||
|
kubeconfig: "{{ kubeconfig_path }}"
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: "{{ awx_namespace }}"
|
||||||
|
|
||||||
|
- name: Apply AWX Operator from GitHub kustomize
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: >-
|
||||||
|
kubectl apply -k "github.com/ansible/awx-operator/config/default?ref={{ awx_operator_version }}"
|
||||||
|
environment:
|
||||||
|
KUBECONFIG: "{{ kubeconfig_path }}"
|
||||||
|
changed_when: true
|
||||||
|
register: operator_apply
|
||||||
|
failed_when: operator_apply.rc != 0 and 'already exists' not in operator_apply.stderr | default('')
|
||||||
|
|
||||||
|
- name: Wait for AWX Operator to be ready
|
||||||
|
kubernetes.core.k8s_info:
|
||||||
|
kubeconfig: "{{ kubeconfig_path }}"
|
||||||
|
api_version: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: awx-operator-controller-manager
|
||||||
|
namespace: "{{ awx_namespace }}"
|
||||||
|
register: operator_status
|
||||||
|
until: >-
|
||||||
|
operator_status.resources | length > 0 and
|
||||||
|
operator_status.resources[0].status.readyReplicas is defined and
|
||||||
|
operator_status.resources[0].status.readyReplicas >= 1
|
||||||
|
retries: 40
|
||||||
|
delay: 15
|
||||||
|
|
||||||
|
- name: Ensure default StorageClass for persistence (assume local-path for k3s-like clusters)
|
||||||
|
kubernetes.core.k8s:
|
||||||
|
state: present
|
||||||
|
kubeconfig: "{{ kubeconfig_path }}"
|
||||||
|
definition:
|
||||||
|
apiVersion: storage.k8s.io/v1
|
||||||
|
kind: StorageClass
|
||||||
|
metadata:
|
||||||
|
name: "{{ awx_storage_class }}"
|
||||||
|
annotations:
|
||||||
|
storageclass.kubernetes.io/is-default-class: "true"
|
||||||
|
provisioner: rancher.io/local-path # Для k3s; изменить на свой provisioner (e.g., kubernetes.io/no-provisioner)
|
||||||
|
reclaimPolicy: Delete
|
||||||
|
volumeBindingMode: WaitForFirstConsumer # Избежать immediate bind ошибок на multi-node
|
||||||
|
|
||||||
|
- name: Deploy AWX instance
|
||||||
|
kubernetes.core.k8s:
|
||||||
|
state: present
|
||||||
|
kubeconfig: "{{ kubeconfig_path }}"
|
||||||
|
definition:
|
||||||
|
apiVersion: awx.ansible.com/v1beta1
|
||||||
|
kind: AWX
|
||||||
|
metadata:
|
||||||
|
name: "{{ awx_instance_name }}"
|
||||||
|
namespace: "{{ awx_namespace }}"
|
||||||
|
spec:
|
||||||
|
service_type: "{{ awx_service_type }}"
|
||||||
|
postgres_storage_class: "{{ awx_storage_class }}" # Указываем SC для postgres PVC
|
||||||
|
projects_persistence: "{{ awx_projects_persistence }}" # false для теста, чтобы избежать дополнительного PVC
|
||||||
|
projects_storage_class: "{{ awx_storage_class }}" # Если persistence: true
|
||||||
|
projects_storage_size: "{{ awx_projects_storage_size }}"
|
||||||
|
|
||||||
|
- name: Wait for AWX pods to be running (increased retries for slow storage provisioning)
|
||||||
|
kubernetes.core.k8s_info:
|
||||||
|
kubeconfig: "{{ kubeconfig_path }}"
|
||||||
|
kind: Pod
|
||||||
|
namespace: "{{ awx_namespace }}"
|
||||||
|
label_selectors:
|
||||||
|
- "app.kubernetes.io/managed-by=awx-operator"
|
||||||
|
register: awx_pods
|
||||||
|
until: >-
|
||||||
|
awx_pods.resources | selectattr('status.phase', 'equalto', 'Running') | list | length >= 2
|
||||||
|
retries: 90 # Увеличено для ожидания provisioning PVC/PV
|
||||||
|
delay: 20
|
||||||
|
|
||||||
|
- name: Retrieve AWX admin password
|
||||||
|
kubernetes.core.k8s_info:
|
||||||
|
kubeconfig: "{{ kubeconfig_path }}"
|
||||||
|
api_version: v1
|
||||||
|
kind: Secret
|
||||||
|
name: "{{ awx_instance_name }}-admin-password"
|
||||||
|
namespace: "{{ awx_namespace }}"
|
||||||
|
register: awx_secret
|
||||||
|
|
||||||
|
- name: Display AWX login information
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: |
|
||||||
|
AWX deployed successfully!
|
||||||
|
Access URL: http://<your-node-ip>:<node-port>
|
||||||
|
(get port: kubectl get svc {{ awx_instance_name }}-service -n {{ awx_namespace }})
|
||||||
|
Username: admin
|
||||||
|
Password: {{ awx_secret.resources[0].data.password | b64decode }}
|
||||||
|
Note: If persistence issues persist, ensure your cluster has a working provisioner (e.g., local-path in k3s) and default StorageClass set.
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
[masters]
|
||||||
|
10.33.33.201 node_name=master-01
|
||||||
|
|
||||||
|
[workers]
|
||||||
|
10.33.33.202 node_name=worker-01
|
||||||
|
10.33.33.203 node_name=worker-02
|
||||||
|
|
||||||
|
[all:vars]
|
||||||
|
ansible_user=ubuntu
|
||||||
|
ansible_ssh_private_key_file=/tmp/semaphore/keys/your_key_id
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
---
|
||||||
|
- name: CNI Fix
|
||||||
|
hosts: k8s_nodes
|
||||||
|
become: true
|
||||||
|
tasks:
|
||||||
|
- name: 1. Исправление сетевых путей (Все плагины сразу)
|
||||||
|
shell: |
|
||||||
|
mkdir -p /usr/lib/cni
|
||||||
|
ln -s /opt/cni/bin/cilium-cni /usr/lib/cni/cilium-cni
|
||||||
|
changed_when: true
|
||||||
|
|
||||||
|
- name: 2. Перезапуск Kubelet
|
||||||
|
shell: systemctl restart kubelet
|
||||||
|
|
||||||
|
- name: Cluster Resources
|
||||||
|
hosts: masters_group
|
||||||
|
become: false
|
||||||
|
tasks:
|
||||||
|
- name: Install Storage
|
||||||
|
shell: kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml
|
||||||
|
|
||||||
|
- name: Install MetalLB
|
||||||
|
shell: kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.8/config/manifests/metallb-native.yaml
|
||||||
|
|
||||||
|
- name: Wait for MetalLB
|
||||||
|
shell: kubectl wait --namespace metallb-system --for=condition=ready pod -l app=metallb,component=controller --timeout=120s
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Fix Webhook
|
||||||
|
shell: kubectl delete validatingwebhookconfiguration metallb-webhook-configuration
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Config IP Pool
|
||||||
|
shell: |
|
||||||
|
cat <<EOF | kubectl apply -f -
|
||||||
|
apiVersion: metallb.io/v1beta1
|
||||||
|
kind: IPAddressPool
|
||||||
|
metadata:
|
||||||
|
name: main-pool
|
||||||
|
namespace: metallb-system
|
||||||
|
spec:
|
||||||
|
addresses:
|
||||||
|
- 10.33.33.210-10.33.33.250
|
||||||
|
---
|
||||||
|
apiVersion: metallb.io/v1beta1
|
||||||
|
kind: L2Advertisement
|
||||||
|
metadata:
|
||||||
|
name: l2-adv
|
||||||
|
namespace: metallb-system
|
||||||
|
EOF
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
---
|
||||||
|
- name: Подготовка всех узлов
|
||||||
|
hosts: k8s_nodes
|
||||||
|
become: true
|
||||||
|
tasks:
|
||||||
|
- name: 0. Ожидание разблокировки APT
|
||||||
|
shell: "while fuser /var/lib/dpkg/lock-frontend >/dev/null 2>&1; do sleep 5; done;"
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: 1. Установка системных зависимостей
|
||||||
|
apt:
|
||||||
|
update_cache: yes
|
||||||
|
name: [apt-transport-https, ca-certificates, curl, gnupg, qemu-guest-agent, socat, conntrack]
|
||||||
|
state: present
|
||||||
|
register: apt_res
|
||||||
|
until: apt_res is success
|
||||||
|
retries: 20
|
||||||
|
delay: 10
|
||||||
|
|
||||||
|
- name: 2. Настройка модулей и sysctl
|
||||||
|
shell: |
|
||||||
|
modprobe overlay && modprobe br_netfilter
|
||||||
|
echo -e "overlay\nbr_netfilter" > /etc/modules-load.d/k8s.conf
|
||||||
|
cat <<EOF > /etc/sysctl.d/k8s.conf
|
||||||
|
net.bridge.bridge-nf-call-iptables = 1
|
||||||
|
net.bridge.bridge-nf-call-ip6tables = 1
|
||||||
|
net.ipv4.ip_forward = 1
|
||||||
|
EOF
|
||||||
|
sysctl --system
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: 3. Установка Containerd
|
||||||
|
apt:
|
||||||
|
name: containerd
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: 4. Конфигурация Containerd
|
||||||
|
shell: |
|
||||||
|
mkdir -p /etc/containerd
|
||||||
|
containerd config default > /etc/containerd/config.toml
|
||||||
|
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
|
||||||
|
systemctl restart containerd
|
||||||
|
changed_when: true
|
||||||
|
|
||||||
|
- name: 5. Добавление репозитория Kubernetes (Tsinghua)
|
||||||
|
shell: |
|
||||||
|
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.32/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg --yes
|
||||||
|
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg arch=amd64] https://mirrors.tuna.tsinghua.edu.cn/kubernetes/core:/stable:/v1.32/deb/ /" > /etc/apt/sources.list.d/kubernetes.list
|
||||||
|
|
||||||
|
- name: 6. Установка пакетов Kubernetes
|
||||||
|
apt:
|
||||||
|
name: [kubelet, kubeadm, kubectl]
|
||||||
|
state: present
|
||||||
|
update_cache: yes
|
||||||
|
register: k8s_apt
|
||||||
|
until: k8s_apt is success
|
||||||
|
retries: 15
|
||||||
|
delay: 10
|
||||||
|
|
||||||
|
- name: Инициализация Master
|
||||||
|
hosts: masters_group
|
||||||
|
become: true
|
||||||
|
tasks:
|
||||||
|
- name: Kubeadm Init
|
||||||
|
shell: "kubeadm init --pod-network-cidr=10.244.0.0/16 --skip-phases=addon/kube-proxy"
|
||||||
|
args:
|
||||||
|
creates: /etc/kubernetes/admin.conf
|
||||||
|
|
||||||
|
- name: Config for ubuntu user
|
||||||
|
shell: |
|
||||||
|
mkdir -p /home/ubuntu/.kube
|
||||||
|
cp -f /etc/kubernetes/admin.conf /home/ubuntu/.kube/config
|
||||||
|
chown ubuntu:ubuntu /home/ubuntu/.kube/config
|
||||||
|
|
||||||
|
- name: Generate Join Command
|
||||||
|
shell: "kubeadm token create --print-join-command"
|
||||||
|
register: join_cmd
|
||||||
|
|
||||||
|
- name: Join Workers
|
||||||
|
hosts: workers_group
|
||||||
|
become: true
|
||||||
|
tasks:
|
||||||
|
- name: Join to cluster
|
||||||
|
shell: "{{ hostvars['k8s-master']['join_cmd']['stdout'] }}"
|
||||||
|
args:
|
||||||
|
creates: /etc/kubernetes/kubelet.conf
|
||||||
|
|
||||||
|
- name: Установка Cilium CNI (Слой сети)
|
||||||
|
hosts: masters_group
|
||||||
|
become: true
|
||||||
|
tasks:
|
||||||
|
- name: Скачивание Cilium CLI
|
||||||
|
get_url:
|
||||||
|
url: https://github.com/cilium/cilium-cli/releases/latest/download/cilium-linux-amd64.tar.gz
|
||||||
|
dest: /tmp/cilium.tar.gz
|
||||||
|
register: cilium_dl
|
||||||
|
until: cilium_dl is success
|
||||||
|
retries: 5
|
||||||
|
delay: 10
|
||||||
|
|
||||||
|
- name: Распаковка Cilium CLI
|
||||||
|
shell: tar xzvf /tmp/cilium.tar.gz -C /usr/local/bin
|
||||||
|
args:
|
||||||
|
creates: /usr/local/bin/cilium
|
||||||
|
|
||||||
|
- name: Установка Cilium в кластер
|
||||||
|
# Выполняем как пользователь ubuntu, чтобы иметь доступ к кубеконфигу
|
||||||
|
become: true
|
||||||
|
become_user: ubuntu
|
||||||
|
shell: /usr/local/bin/cilium install --set kubeProxyReplacement=true
|
||||||
|
ignore_errors: true
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
apiVersion: metallb.io/v1beta1
|
||||||
|
kind: IPAddressPool
|
||||||
|
metadata:
|
||||||
|
name: main-pool
|
||||||
|
namespace: metallb-system
|
||||||
|
spec:
|
||||||
|
addresses:
|
||||||
|
- {{ metallb_ip_range }}
|
||||||
|
---
|
||||||
|
apiVersion: metallb.io/v1beta1
|
||||||
|
kind: L2Advertisement
|
||||||
|
metadata:
|
||||||
|
name: l2-adv
|
||||||
|
namespace: metallb-system
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
mysql:
|
||||||
|
image: mysql:8.0
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
MYSQL_RANDOM_ROOT_PASSWORD: "yes"
|
||||||
|
MYSQL_DATABASE: semaphore
|
||||||
|
MYSQL_USER: semaphore
|
||||||
|
MYSQL_PASSWORD: pass
|
||||||
|
volumes:
|
||||||
|
- mysql-data:/var/lib/mysql
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
|
semaphore:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
image: semaphoreui/semaphore:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "5555:3000"
|
||||||
|
environment:
|
||||||
|
SEMAPHORE_DB_USER: semaphore
|
||||||
|
SEMAPHORE_DB_PASS: pass
|
||||||
|
SEMAPHORE_DB_HOST: mysql
|
||||||
|
SEMAPHORE_DB_PORT: 3306
|
||||||
|
SEMAPHORE_DB_DIALECT: mysql
|
||||||
|
SEMAPHORE_DB: semaphore
|
||||||
|
SEMAPHORE_PLAYBOOK_PATH: /tmp/semaphore/
|
||||||
|
SEMAPHORE_ADMIN: admin
|
||||||
|
SEMAPHORE_ADMIN_PASSWORD: pass
|
||||||
|
SEMAPHORE_ADMIN_NAME: Admin
|
||||||
|
SEMAPHORE_ADMIN_EMAIL: 1@top-sysops.ru
|
||||||
|
SEMAPHORE_ACCESS_KEY_ENCRYPTION: "your-key="
|
||||||
|
volumes:
|
||||||
|
- ./requirements.txt:/etc/semaphore/requirements.txt:ro
|
||||||
|
- semaphore-config:/etc/semaphore
|
||||||
|
- semaphore-projects:/projects
|
||||||
|
- ~/semaphore/config:/home/semaphore/.kube/config
|
||||||
|
depends_on:
|
||||||
|
mysql:
|
||||||
|
condition: service_healthy
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
mysql-data:
|
||||||
|
semaphore-config:
|
||||||
|
semaphore-projects:
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
kubernetes>=25.3.0
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
terraform {
|
||||||
|
required_providers {
|
||||||
|
proxmox = {
|
||||||
|
source = "bpg/proxmox"
|
||||||
|
version = "0.90.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
backend "http" {}
|
||||||
|
}
|
||||||
|
|
||||||
|
provider "proxmox" {
|
||||||
|
endpoint = var.proxmox_api_url
|
||||||
|
api_token = "${var.proxmox_api_token_id}=${var.proxmox_api_token_secret}"
|
||||||
|
insecure = true
|
||||||
|
ssh {
|
||||||
|
agent = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "proxmox_virtual_environment_vm" "k8s_nodes" {
|
||||||
|
for_each = var.vm_nodes
|
||||||
|
node_name = "pve-main"
|
||||||
|
|
||||||
|
name = each.value.name
|
||||||
|
vm_id = each.value.id
|
||||||
|
|
||||||
|
clone {
|
||||||
|
vm_id = 9000
|
||||||
|
}
|
||||||
|
|
||||||
|
cpu {
|
||||||
|
cores = 2
|
||||||
|
type = "x86-64-v2-AES"
|
||||||
|
}
|
||||||
|
|
||||||
|
memory {
|
||||||
|
dedicated = 4096
|
||||||
|
}
|
||||||
|
|
||||||
|
# ИСПРАВЛЕНО: Было network_interface, теперь network_device
|
||||||
|
network_device {
|
||||||
|
bridge = "vmbr0"
|
||||||
|
}
|
||||||
|
|
||||||
|
disk {
|
||||||
|
datastore_id = "local-lvm"
|
||||||
|
interface = "scsi0"
|
||||||
|
size = 20
|
||||||
|
}
|
||||||
|
|
||||||
|
initialization {
|
||||||
|
ip_config {
|
||||||
|
ipv4 {
|
||||||
|
address = "${each.value.ip}/24"
|
||||||
|
gateway = "10.33.33.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
user_account {
|
||||||
|
username = "ubuntu"
|
||||||
|
keys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEEuaCL9fPnGCH4hfxAzzS09aRaj6ptoG685p+oF5vTp semaphore-ansible-key"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
output "vm_ips" {
|
||||||
|
value = { for k, v in var.vm_nodes : k => v.ip }
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
variable "proxmox_api_url" { type = string }
|
||||||
|
variable "proxmox_api_token_id" { type = string }
|
||||||
|
variable "proxmox_api_token_secret" { type = string }
|
||||||
|
|
||||||
|
variable "vm_nodes" {
|
||||||
|
type = map(object({
|
||||||
|
id = number
|
||||||
|
ip = string
|
||||||
|
name = string
|
||||||
|
}))
|
||||||
|
default = {
|
||||||
|
"master" = { id = 201, ip = "10.33.33.201", name = "k8s-master" }
|
||||||
|
"worker1" = { id = 202, ip = "10.33.33.202", name = "k8s-worker-1" }
|
||||||
|
"worker2" = { id = 203, ip = "10.33.33.203", name = "k8s-worker-2" }
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user