commit 2e68a84ead1e73e8c40af2ee1d47d6387178e355
Author: IaaC Ansible Roles <>
Date: Mon Mar 31 14:06:16 2025 +0300
Initial commit
diff --git a/.ansible-lint b/.ansible-lint
new file mode 100644
index 0000000..1646c4f
--- /dev/null
+++ b/.ansible-lint
@@ -0,0 +1,7 @@
+skip_list:
+ - fqcn
+ - yaml[new-line-at-end-of-file]
+ - yaml[truthy]
+ - yaml[line-length]
+ - var-naming[no-role-prefix]
+ - 'ignore-errors'
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..61671ed
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,173 @@
+# ---> Ansible
+*.retry
+
+# ---> Python
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+# For a library or package, you might want to ignore these files since the code is
+# intended to run in multiple environments; otherwise, check them in:
+# .python-version
+
+# pipenv
+# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+# However, in case of collaboration, if having platform-specific dependencies or dependencies
+# having no cross-platform support, pipenv may install dependencies that don't work, or not
+# install all needed dependencies.
+#Pipfile.lock
+
+# UV
+# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
+# This is especially recommended for binary packages to ensure reproducibility, and is more
+# commonly ignored for libraries.
+#uv.lock
+
+# poetry
+# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
+# This is especially recommended for binary packages to ensure reproducibility, and is more
+# commonly ignored for libraries.
+# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
+#poetry.lock
+
+# pdm
+# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
+#pdm.lock
+# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
+# in version control.
+# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
+.pdm.toml
+.pdm-python
+.pdm-build/
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+
+# Cython debug symbols
+cython_debug/
+
+# PyCharm
+# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
+# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
+# and can be added to the global gitignore or merged into this file. For a more nuclear
+# option (not recommended) you can uncomment the following to ignore the entire idea folder.
+#.idea/
+
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..791c0d1
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,89 @@
+stages:
+ - lint
+ - test
+ - deploy
+ - notify
+
+services:
+ - name: docker:dind
+ command: ["--tls=false"]
+
+variables:
+ DOCKER_IMAGE: "hub.cism-ms.ru/ansible/ansible:latest"
+ DOCKER_TLS_CERTDIR: ""
+ ANSIBLE_FORCE_COLOR: "true"
+
+before_script:
+ - echo "$CI_REGISTRY_PASSWORD" | docker login hub.cism-ms.ru -u "$CI_REGISTRY_USER" --password-stdin
+ - docker pull $DOCKER_IMAGE
+ - echo "Fixing directory permissions..."
+ - chmod o-w $CI_PROJECT_DIR
+
+lint:
+ stage: lint
+ script:
+ - echo "Начинаем стейдж Lint"
+ - echo "Распаковываем секреты..."
+ - ansible-vault decrypt vars/secrets.yml --vault-password-file ./vault-password.txt
+ - echo "Запускаем ansible-lint..."
+ - ansible-lint roles/*
+ - echo "Упаковываем секреты..."
+ - ansible-vault encrypt vars/secrets.yml --encrypt-vault-id default --vault-password-file ./vault-password.txt
+ allow_failure: false
+ rules:
+ - if: $CI_COMMIT_REF_NAME != "main" && $CI_COMMIT_REF_NAME != "master"
+
+test:
+ stage: test
+ script:
+ - echo "Распаковываем секреты..."
+ - ansible-vault decrypt --vault-password-file ./vault-password.txt vars/secrets.yml
+ - echo "Запускаем тесты через Молекулу..."
+ - molecule test --parallel --destroy=always
+ - echo "Упаковываем секреты..."
+ - ansible-vault encrypt vars/secrets.yml --encrypt-vault-id default --vault-password-file ./vault-password.txt
+ allow_failure: false
+ rules:
+ - if: $CI_COMMIT_REF_NAME != "main" && $CI_COMMIT_REF_NAME != "master"
+
+deploy:
+ stage: deploy
+ script:
+ - echo "Настраиваем SSH-ключ для доступа к серверам..."
+ # Создаем директорию .ssh и настраиваем права доступа
+ - mkdir -p ~/.ssh
+ - chmod 700 ~/.ssh
+ # Записываем SSH-ключ в файл ~/.ssh/id_rsa
+ - echo "$SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa
+ - chmod 600 ~/.ssh/id_rsa
+ # Запускаем основной пайплайн
+ - echo "Распаковываем секреты..."
+ - ansible-vault decrypt --vault-password-file ./vault-password.txt vars/secrets.yml
+ - echo "Все ок. Деплоим в прод..."
+ - ansible-playbook roles/deploy.yaml
+ - echo "Упаковываем секреты..."
+ - ansible-vault encrypt vars/secrets.yml --encrypt-vault-id default --vault-password-file ./vault-password.txt
+ # Удаляем ключ
+ - rm -rf ~/.ssh
+ rules:
+ - if: $CI_COMMIT_REF_NAME != "main" && $CI_COMMIT_REF_NAME != "master"
+ when: manual
+
+notify:
+ stage: notify
+ script:
+ - |
+ if [ "$CI_JOB_STATUS" == "success" ]; then
+ MESSAGE="✅ Пайплайн успешно завершен!%0AПроект: $CI_PROJECT_NAME%0AВетка: $CI_COMMIT_REF_NAME%0AСтатус: $CI_JOB_STATUS"
+ else
+ MESSAGE="❌ Пайплайн завершен с ошибкой!%0AПроект: $CI_PROJECT_NAME%0AВетка: $CI_COMMIT_REF_NAME%0AСтатус: $CI_JOB_STATUS"
+ fi
+# curl -s -X POST "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage" \
+# -d "chat_id=$TELEGRAM_CHAT_ID" \
+# -d "text=$MESSAGE"
+ rules:
+ - if: $CI_JOB_STATUS # Отправлять уведомление только после завершения пайплайна
+
+after_script:
+ - echo "Работа пайплайна завершена"
+
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/AnsibleTemplate.iml b/.idea/AnsibleTemplate.iml
new file mode 100644
index 0000000..db32fb1
--- /dev/null
+++ b/.idea/AnsibleTemplate.iml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..95a0fdb
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..a6dd401
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..febcd53
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..aa8fc36
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,60 @@
+# Используем более легкий базовый образ
+FROM python:3.12.9-slim-bullseye
+
+# Добавляем метаданные
+LABEL maintainer="Сергей Антропов "
+LABEL description="Этот Dockerfile создан для внедрения подхода IaC в Ansible."
+LABEL version="0.1"
+LABEL contact.website="https://devops.org.ru"
+
+# Устанавливаем переменные окружения
+ENV PYTHONUNBUFFERED=1
+ENV EDITOR=nano
+
+# Устанавливаем системные зависимости
+RUN apt-get update && \
+ apt-get install -y --no-install-recommends \
+ git \
+ ssh \
+ gcc \
+ libffi-dev \
+ libssl-dev \
+ make \
+ sudo \
+ sshpass \
+ openssh-client \
+ nano \
+ less \
+ ca-certificates \
+ curl \
+ gnupg \
+ lsb-release \
+ && mkdir -p /etc/apt/keyrings \
+ && curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg \
+ && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian bullseye stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null \
+ && apt-get update && \
+ apt-get install -y --no-install-recommends \
+ docker-ce-cli \
+ && rm -rf /var/lib/apt/lists/*
+
+# Устанавливаем зависимости Python для Ansible и Molecule
+RUN pip install --upgrade pip && \
+ pip install \
+ ansible \
+ ansible-lint \
+ ansible-vault \
+ molecule \
+ molecule-docker \
+ molecule-plugins \
+ ansible-compat \
+ docker
+
+# Копируем ssh ключ
+#COPY id_rsa /root/.ssh/id_rsa
+#RUN chmod 600 /root/.ssh/id_rsa
+
+# Устанавливаем рабочую директорию
+WORKDIR /ansible
+
+# Команда по умолчанию
+CMD ["/bin/bash"]
diff --git a/Dockerfile-CentOS b/Dockerfile-CentOS
new file mode 100644
index 0000000..0e4a063
--- /dev/null
+++ b/Dockerfile-CentOS
@@ -0,0 +1,22 @@
+# Сборка контейнера с systemd для удобного тестирования ролей Ansible через Molecule
+
+# Используем официальный образ Fedora
+FROM quay.io/fedora/python-312
+
+USER root
+
+# Обновляем пакеты и устанавливаем systemd
+RUN dnf -y update && \
+ dnf -y install systemd rsync && \
+ dnf clean all && \
+ rm -rf /var/cache/dnf /tmp/* /var/tmp/*
+
+# Настраиваем окружение для systemd
+ENV container=docker
+STOPSIGNAL SIGRTMIN+3
+
+# Создаем необходимые директории для systemd
+VOLUME [ "/sys/fs/cgroup" ]
+
+# Запускаем systemd при старте контейнера
+CMD ["/sbin/init"]
\ No newline at end of file
diff --git a/Dockerfile-Ubuntu b/Dockerfile-Ubuntu
new file mode 100644
index 0000000..7c3ed80
--- /dev/null
+++ b/Dockerfile-Ubuntu
@@ -0,0 +1,20 @@
+# Сборка контейнера с systemd для удобного тестирования ролей Ansible через Molecule
+
+# Используем официальный образ Ubuntu 20.04
+FROM geerlingguy/docker-ubuntu2004-ansible:latest
+
+# Обновляем пакеты и устанавливаем systemd
+RUN apt-get update && \
+ apt-get install -y systemd systemd-sysv rsync && \
+ apt-get clean && \
+ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
+
+# Указываем, что контейнер использует systemd в качестве init-системы
+ENV container=docker
+STOPSIGNAL SIGRTMIN+3
+
+# Создаем необходимые директории для systemd
+VOLUME [ "/sys/fs/cgroup" ]
+
+# Запускаем systemd при старте контейнера
+CMD ["/sbin/init"]
\ No newline at end of file
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..7d96b56
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,151 @@
+# Глобальные переменные
+IMAGE ?= ansible
+TAG ?= 0.1
+REGISTRY ?= hub.cism-ms.ru/ansible
+# По умолчанию используем docker. Для локальной разработки используйте docker-compose
+RUN_MODE ?= docker
+
+# Определение команды RUN в зависимости от RUN_MODE
+ifeq ($(RUN_MODE), docker-compose)
+ RUN = docker compose run --rm $(IMAGE)
+else ifeq ($(RUN_MODE), docker)
+ RUN = docker run -it --rm \
+ --name $(IMAGE) \
+ -v $(PWD):/ansible \
+ -v /var/run/docker.sock:/var/run/docker.sock \
+ -v ~/.ssh/id_rsa:/root/.ssh/id_rsa:ro \
+ -e ANSIBLE_VAULT_PASSWORD_FILE=/ansible/vault-password.txt \
+ --privileged \
+ --workdir /ansible \
+ $(REGISTRY)/$(IMAGE)
+else
+ $(error Invalid RUN_MODE. Use "docker-compose" or "docker")
+endif
+
+view create edit show delete test lint deploy new init build rebuild prune release images push pull shell:
+ @true
+
+####################################################################################################
+# Инициализация новой роли
+####################################################################################################
+init:
+ @echo "Шаг 1: Создание Docker-образа..."
+ @make docker build
+ @echo "Шаг 2: Создание Docker-образов для запуска Molecule..."
+ @make docker images
+ @echo "Шаг 3: Создание нового vault-файла с паролем..."
+ @read -p "Введите пароль для vault: " VAULT_PASSWORD; \
+ echo "$$VAULT_PASSWORD" > vault-password.txt; \
+ make vault create
+ @echo "Шаг 4: Создание нового брэнча в гите..."
+ @make git new
+ @echo "Шаг 5: Создание новой роли..."
+ @make role new
+
+####################################################################################################
+# Управление контейнерами с помощью docker compose или docker run
+####################################################################################################
+docker:
+ @case "$(word 2, $(MAKECMDGOALS))" in \
+ build) \
+ docker buildx create --use --name multiarch-builder --driver docker-container; \
+ if [ "$(RUN_MODE)" = "docker-compose" ]; then \
+ docker compose build $(c); \
+ else \
+ docker build -t $(REGISTRY)/$(IMAGE) .; \
+ fi;; \
+ rebuild) \
+ docker buildx create --use --name multiarch-builder --driver docker-container; \
+ if [ "$(RUN_MODE)" = "docker-compose" ]; then \
+ docker compose build --no-cache $(c); \
+ else \
+ docker build --no-cache -t $(REGISTRY)/$(IMAGE) .; \
+ fi;; \
+ prune) \
+ docker system prune -af;; \
+ shell) \
+ clear; \
+ echo "Entering to Ansible container shell..."; \
+ $(RUN) bash ;; \
+ release) \
+ docker buildx create --use --name multiarch-builder --driver docker-container; \
+ docker login $(REGISTRY); \
+ docker buildx build -t $(REGISTRY)/$(IMAGE):$(TAG) -t $(REGISTRY)/$(IMAGE):latest --platform linux/amd64,linux/arm64 --push .;; \
+ images) \
+ docker buildx create --use --name multiarch-builder --driver docker-container; \
+ docker login $(REGISTRY); \
+ docker buildx build -t $(REGISTRY)/centos:latest --platform linux/amd64,linux/arm64 --push -f Dockerfile-CentOS .; \
+ docker buildx build -t $(REGISTRY)/ubuntu:latest --platform linux/amd64,linux/arm64 --push -f Dockerfile-Ubuntu .;; \
+ *) echo "Unknown action. Available actions: build, rebuild, prune, release";; \
+ esac
+
+####################################################################################################
+# Работа с ролью
+####################################################################################################
+vault:
+ @case "$(word 2, $(MAKECMDGOALS))" in \
+ show) $(RUN) bash -c "ansible-vault view --vault-password-file vault-password.txt vars/secrets.yml";; \
+ create) $(RUN) bash -c "ansible-vault create --encrypt-vault-id default --vault-password-file vault-password.txt vars/secrets.yml";; \
+ edit) $(RUN) bash -c "ansible-vault edit --vault-password-file vault-password.txt vars/secrets.yml";; \
+ delete) $(RUN) bash -c "rm vars/secrets.yml";; \
+ rekey) $(RUN) bash -c "ansible-vault rekey --vault-password-file vault-password.txt vars/secrets.yml";; \
+ decrypt) $(RUN) bash -c "ansible-vault decrypt --vault-password-file vault-password.txt vars/secrets.yml";; \
+ encrypt) $(RUN) bash -c "ansible-vault encrypt --encrypt-vault-id default --vault-password-file vault-password.txt vars/secrets.yml";; \
+ *) echo "Unknown action";; \
+ esac
+
+role:
+ @case "$(word 2, $(MAKECMDGOALS))" in \
+ new) \
+ clear; \
+ echo "Введите название новой роли на английском:"; \
+ read ROLE_NAME; \
+ echo "Введите описание роли:"; \
+ read ROLE_DESC; \
+ cp -r default/ "roles/$${ROLE_NAME}"; \
+ printf "\n- name: $${ROLE_DESC}" >> roles/deploy.yaml; \
+ printf "\n import_playbook: $${ROLE_NAME}/deploy.yaml" >> roles/deploy.yaml; \
+ printf '\n - ../../roles/%s' "$$ROLE_NAME" >> molecule/default/converge.yml; \
+ printf "\n - $${ROLE_NAME}" >> roles/$$ROLE_NAME/deploy.yaml;; \
+ lint) \
+ clear; \
+ echo "Check your role..."; \
+ $(RUN) bash -c "ansible-vault decrypt --vault-password-file vault-password.txt vars/secrets.yml"; \
+ $(RUN) bash -c "ansible-lint roles/*"; \
+ $(RUN) bash -c "ansible-vault encrypt vars/secrets.yml --encrypt-vault-id default --vault-password-file vault-password.txt";; \
+ test) \
+ clear; \
+ echo "Running test roles..."; \
+ $(RUN) bash -c "ansible-vault decrypt --vault-password-file vault-password.txt vars/secrets.yml"; \
+ $(RUN) bash -c "docker login $(REGISTRY) && molecule test --parallel --destroy=always"; \
+ $(RUN) bash -c "ansible-vault encrypt vars/secrets.yml --encrypt-vault-id default --vault-password-file vault-password.txt";; \
+ deploy) \
+ clear; \
+ echo "Deploying roles to production..."; \
+ $(RUN) bash -c "ansible-playbook roles/deploy.yaml";; \
+ *) echo "Unknown action";; \
+ esac
+
+####################################################################################################
+# Работа с Git
+####################################################################################################
+git:
+ @case "$(word 2, $(MAKECMDGOALS))" in \
+ push) \
+ git branch; \
+ read -p "Выберите ветку для пуша: " BRANCH; \
+ read -p "Введите описание коммита: " COMMIT; \
+ commitname=$$COMMIT; \
+ git add . ; \
+ git commit -m "$$commitname"; \
+ git push -u origin $$BRANCH; \
+ echo "Изменения внесены в Git";; \
+ pull) \
+ git pull;; \
+ new) \
+ read -p "Введите имя новой ветки: " BRANCH_NAME; \
+ NEW_BRANCH="$$BRANCH_NAME"; \
+ git checkout -b $$NEW_BRANCH; \
+ echo "Создана и переключена на новую ветку: $$NEW_BRANCH";; \
+ *) echo "Unknown action. Available actions: push, pull, cluster-branch";; \
+ esac
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..4c967db
--- /dev/null
+++ b/README.md
@@ -0,0 +1,61 @@
+# AnsibleTemplate
+
+Темплейт для создания, проверки и тестирование ролей Ansible с помощью контейнеров Docker.
+
+### С чего начать?
+
+На вашей машине вам необходимо сбилдить образ, где будут запускаться все роли через docker-compose.
+
+Это можно сделать самостоятельно:
+
+- **make docker build** - создание контейнера
+- **make docker rebuild** - пересоздание контейнера, если были внесены изменения в Dockerfile
+- **make docker prune** - очистить систему от лишних образов
+- **make docker shell** - войти в контейнер Shell
+- **make docker release** - собирает образ контейнера и пушит его в докер реджистри
+- **make docker images** - собрать образы контейнеров с systemd, для удобного тестирования ролей.
+
+Или ввести команду:
+
+- **make init** - которая создаст файл секретов с паролем. Сбилдит образ. И создаст новую роль.
+
+### Работа с ролью
+- **make role new** - создать новую роль из шаблона. Название роли пишется на английском, описание роли на любом языке
+- **make role lint** - проверяет все роли в папке roles/* на наличие ошибок
+- **make role test** - позволяет тестировать роль, указанную в molecule/default/converge.yml
+сразу на двух контейнерах (RedHat и Ubuntu)
+- **make role deploy** - запускает роль в продакшен. Все хосты берет из файла inventory/hosts
+
+### Работа с файлом переменных
+
+Все переменные защищены через **Ansible-Vault** и находятся в папке vars/secrets.yml
+
+Для смены пароля измените его в файле **./vault-password.txt**
+
+- **make vault create** - создать новый файл с учетом пароля в файле **./vault-password.txt**
+- **make vault delete** - удалить файл с переменными
+- **make vault edit** - отредактировать файл переменных
+- **make vault show** - показать содержимое файла переменных
+- **make vault rekey** - сменить пароль шифрования
+- **make vault encrypt** - зашифровать файл секретов
+- **make vault decrypt** - расшифровать файл секретов
+
+### Работа с Git
+
+- **make git push** - запушить изменения. С выбором ветки и вводом коммита.
+- **make git pull** - получить изменения из репы
+- **make git new** - создание нового брэнча имя cluster-branch_name для IaC подхода.
+
+### Добавить свой образ контейнера для тестов
+
+Что бы добавить или изменить докер-образы для тестирования ролей измените файл настроек молекулы
+molecule/default/molecule.yml
+```yaml
+ - name: ubuntu-instance
+ image: "your.docker-registry.com/your-image:latest"
+ privileged: true
+ pre_build_image: true
+ volumes:
+ - /sys/fs/cgroup:/sys/fs/cgroup:ro
+```
+Помните, что образ обязательно должен содержать python не ниже версии 3.12 и systemd для нормального тестирования ролей.
\ No newline at end of file
diff --git a/ansible.cfg b/ansible.cfg
new file mode 100644
index 0000000..d43f8b2
--- /dev/null
+++ b/ansible.cfg
@@ -0,0 +1,8 @@
+[defaults]
+inventory = inventory/hosts
+vault_password_file = vault-password.txt
+remote_user = devops
+host_key_checking = False
+enable_plugins = yaml, ini
+roles_path = roles/
+interpreter_python = auto
\ No newline at end of file
diff --git a/default/defaults/.gitkeep b/default/defaults/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/default/deploy.yaml b/default/deploy.yaml
new file mode 100644
index 0000000..61ab8b8
--- /dev/null
+++ b/default/deploy.yaml
@@ -0,0 +1,10 @@
+---
+- name: Deploy roles
+ hosts: all
+ become: true
+ become_user: root
+ become_method: ansible.builtin.sudo
+ gather_facts: true
+ vars_files:
+ - ../../vars/secrets.yml
+ roles:
\ No newline at end of file
diff --git a/default/files/.gitkeep b/default/files/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/default/handlers/.gitkeep b/default/handlers/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/default/meta/.gitkeep b/default/meta/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/default/tasks/debian/main.yaml b/default/tasks/debian/main.yaml
new file mode 100644
index 0000000..4c32e03
--- /dev/null
+++ b/default/tasks/debian/main.yaml
@@ -0,0 +1,4 @@
+---
+- name: Пример таски
+ debug:
+ msg: "Привет! Я запустился на Debian/Ubuntu!"
diff --git a/default/tasks/main.yaml b/default/tasks/main.yaml
new file mode 100644
index 0000000..2b9ddee
--- /dev/null
+++ b/default/tasks/main.yaml
@@ -0,0 +1,12 @@
+---
+- name: "Определяем ОС"
+ set_fact:
+ os_family: "{{ ansible_facts['os_family'] }}"
+
+- name: "Подключаем таски для RedHat совместимых"
+ include_tasks: "redhat/main.yaml"
+ when: os_family == "RedHat"
+
+- name: "Подключаем таски для Debian/Ubuntu совместимых"
+ include_tasks: "debian/main.yaml"
+ when: os_family == "Debian"
diff --git a/default/tasks/redhat/main.yaml b/default/tasks/redhat/main.yaml
new file mode 100644
index 0000000..64e5c36
--- /dev/null
+++ b/default/tasks/redhat/main.yaml
@@ -0,0 +1,4 @@
+---
+- name: Пример таски
+ debug:
+ msg: "Привет! Я запустился на RedHat/CentOS/Fedora!"
diff --git a/default/templates/.gitkeep b/default/templates/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/default/tests/.gitkeep b/default/tests/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/docker-compose.yaml b/docker-compose.yaml
new file mode 100644
index 0000000..88f68de
--- /dev/null
+++ b/docker-compose.yaml
@@ -0,0 +1,15 @@
+services:
+ ansible:
+ build:
+ context: .
+ ssh:
+ - default
+ container_name: ansible
+ volumes:
+ - .:/ansible
+ - /var/run/docker.sock:/var/run/docker.sock
+ environment:
+ - ANSIBLE_VAULT_PASSWORD_FILE=./vault-password.txt
+ tty: true
+ privileged: true
+ working_dir: /ansible
\ No newline at end of file
diff --git a/gitlab/config.json b/gitlab/config.json
new file mode 100644
index 0000000..66d6151
--- /dev/null
+++ b/gitlab/config.json
@@ -0,0 +1,8 @@
+{
+ "auths": {
+ "hub.cism-ms.ru": {
+ "username": "your-username",
+ "password": "your-password"
+ }
+ }
+}
\ No newline at end of file
diff --git a/gitlab/docker-compose.yaml b/gitlab/docker-compose.yaml
new file mode 100644
index 0000000..8634fa4
--- /dev/null
+++ b/gitlab/docker-compose.yaml
@@ -0,0 +1,33 @@
+services:
+ gitlab-runner:
+ image: gitlab/gitlab-runner:latest
+ container_name: gitlab-runner
+ restart: always
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
+ - ./runner:/etc/gitlab-runner
+ - ./config.json:/root/.docker/config.json
+ environment:
+ - CI_SERVER_URL=https://gitlab.com # Замените на URL вашего GitLab
+ - REGISTRATION_TOKEN=your-registration-token # Замените на ваш токен регистрации
+ - RUNNER_NAME=ansible-runner # Имя раннера
+ - RUNNER_EXECUTOR=docker # Используем Docker как исполнитель
+ - DOCKER_IMAGE=hub.cism-ms.ru/ansible/ansible:latest # Образ Docker по умолчанию
+ - RUNNER_TAGS=docker,linux,ansible # Теги для раннера
+ - DOCKER_PRIVILEGED=true # Привилегированный режим
+ - DOCKER_TLS_VERIFY=false # Отключить проверку TLS
+ - DOCKER_TTY=false # Отключить TTY
+ command: >
+ register --non-interactive
+ --executor ${RUNNER_EXECUTOR}
+ --docker-image ${DOCKER_IMAGE}
+ --url ${CI_SERVER_URL}
+ --registration-token ${REGISTRATION_TOKEN}
+ --description ${RUNNER_NAME}
+ --tag-list ${RUNNER_TAGS}
+ --run-untagged="true"
+ --locked="false"
+ --docker-privileged=${DOCKER_PRIVILEGED}
+ --docker-tlsverify=${DOCKER_TLS_VERIFY}
+ --docker-disable-entrypoint-overwrite="false"
+ --docker-tty=${DOCKER_TTY}
\ No newline at end of file
diff --git a/gitlab/runner/config.toml b/gitlab/runner/config.toml
new file mode 100644
index 0000000..3b5905b
--- /dev/null
+++ b/gitlab/runner/config.toml
@@ -0,0 +1,31 @@
+concurrent = 1
+check_interval = 0
+shutdown_timeout = 0
+
+[session_server]
+ session_timeout = 1800
+
+[[runners]]
+ name = "faa4e539628d"
+ url = "http://git.cism-ms.ru"
+ id = 115
+ token = "glrt-t3_5MD8hLs_69nChDbwXHLM"
+ token_obtained_at = 2025-03-17T15:35:01Z
+ token_expires_at = 0001-01-01T00:00:00Z
+ executor = "docker"
+ [runners.cache]
+ MaxUploadedArchiveSize = 0
+ [runners.cache.s3]
+ [runners.cache.gcs]
+ [runners.cache.azure]
+ [runners.docker]
+ tty = false
+ tls_verify = false
+ image = "hub.cism-ms.ru/ansible/ansible:latest"
+ privileged = true
+ disable_entrypoint_overwrite = false
+ oom_kill_disable = false
+ disable_cache = false
+ volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
+ shm_size = 0
+ network_mtu = 0
\ No newline at end of file
diff --git a/inventory/.gitkeep b/inventory/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/inventory/hosts b/inventory/hosts
new file mode 100644
index 0000000..a4a29bb
--- /dev/null
+++ b/inventory/hosts
@@ -0,0 +1 @@
+[all]
diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml
new file mode 100644
index 0000000..749dcda
--- /dev/null
+++ b/molecule/default/converge.yml
@@ -0,0 +1,6 @@
+---
+- name: Converge
+ hosts: all
+ vars_files:
+ - ../../vars/secrets.yml
+ roles:
\ No newline at end of file
diff --git a/molecule/default/destroy.yml b/molecule/default/destroy.yml
new file mode 100644
index 0000000..82979c7
--- /dev/null
+++ b/molecule/default/destroy.yml
@@ -0,0 +1,8 @@
+- name: Destroy containers on interrupt
+ hosts: localhost
+ tasks:
+ - name: Ensure containers are destroyed
+ docker_container:
+ name: "{{ item.name }}"
+ state: absent
+ loop: "{{ molecule_yml.platforms }}"
\ No newline at end of file
diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml
new file mode 100644
index 0000000..9ceea66
--- /dev/null
+++ b/molecule/default/molecule.yml
@@ -0,0 +1,61 @@
+---
+dependency:
+ name: galaxy
+ enabled: true
+ options:
+ requirements-file: requirements.yml
+
+driver:
+ name: docker
+
+platforms:
+ - name: centos
+ image: "hub.cism-ms.ru/ansible/centos:latest"
+ privileged: true
+ pre_build_image: true
+ volumes:
+ - /sys/fs/cgroup:/sys/fs/cgroup:ro
+ - /var/run/docker.sock:/var/run/docker.sock
+ tmpfs:
+ - /tmp
+ - /run
+ - name: ubuntu
+ image: "hub.cism-ms.ru/ansible/ubuntu:latest"
+ privileged: true
+ pre_build_image: true
+ volumes:
+ - /sys/fs/cgroup:/sys/fs/cgroup:ro
+ - /var/run/docker.sock:/var/run/docker.sock
+ tmpfs:
+ - /tmp
+ - /run
+
+provisioner:
+ name: ansible
+ connection_options:
+ ansible_connection: docker
+ ansible_user: root
+ env:
+ ANSIBLE_PYTHON_INTERPRETER: /usr/bin/python3
+ lint:
+ name: ansible-lint
+
+verifier:
+ name: ansible
+
+scenario:
+ name: default
+ test_sequence:
+ - dependency
+ - cleanup
+ - destroy
+ - syntax
+ - create
+ - prepare
+ - converge
+ - idempotence
+ - side_effect
+ - verify
+ - cleanup
+ - destroy
+
diff --git a/molecule/default/no-prepare.yml b/molecule/default/no-prepare.yml
new file mode 100644
index 0000000..57b792f
--- /dev/null
+++ b/molecule/default/no-prepare.yml
@@ -0,0 +1,43 @@
+- name: Prepare
+ hosts: all
+ tasks:
+ - name: Detect OS family
+ ansible.builtin.setup:
+ gather_subset:
+ - "min"
+
+ - name: Обновляем пакеты для работы с Ansible в RockyLinux (Centos/RedHat)
+ when: ansible_facts['os_family'] == "RedHat"
+ block:
+ - name: Устанавливаем репозиторий AppStream (если его нет)
+ ansible.builtin.raw: dnf config-manager --set-enabled appstream
+ changed_when: false
+
+ - name: Установить rsync
+ ansible.builtin.raw: dnf install -y rsync
+ changed_when: false
+
+ - name: Устанавливаем Python 3.8
+ ansible.builtin.raw: dnf install -y python38 python38-pip
+ changed_when: false
+
+ - name: Обновляем символическую ссылку python3
+ ansible.builtin.raw: alternatives --set python /usr/bin/python3.8
+ changed_when: false
+# - name: Fix repository URLs
+# ansible.builtin.command:
+# cmd: sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
+# changed_when: false
+
+# - name: Update baseurl
+# ansible.builtin.command:
+# cmd: sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
+# changed_when: false
+
+# - name: Install required packages
+# ansible.builtin.yum:
+# name:
+# - epel-release
+# - python3
+# - python3-pip
+# state: present
diff --git a/molecule/default/no-verify.yml b/molecule/default/no-verify.yml
new file mode 100644
index 0000000..5e80115
--- /dev/null
+++ b/molecule/default/no-verify.yml
@@ -0,0 +1,7 @@
+---
+- name: Prepare
+ hosts: all
+ tasks:
+ - name: Reun verify
+ debug:
+ msg: "Hello, Verify!"
diff --git a/requirements.yml b/requirements.yml
new file mode 100644
index 0000000..cf12a33
--- /dev/null
+++ b/requirements.yml
@@ -0,0 +1,4 @@
+---
+collections:
+ - name: maxhoesel.proxmox
+ version: 5.0.1
diff --git a/roles/deploy.yaml b/roles/deploy.yaml
new file mode 100644
index 0000000..73b314f
--- /dev/null
+++ b/roles/deploy.yaml
@@ -0,0 +1 @@
+---
\ No newline at end of file
diff --git a/vars/.gitkeep b/vars/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/vault-password.txt b/vault-password.txt
new file mode 100644
index 0000000..2d27916
--- /dev/null
+++ b/vault-password.txt
@@ -0,0 +1 @@
+password123
\ No newline at end of file