added the a preparing ansible playbooks for automating new servers

This commit is contained in:
rezayaghobi-dev
2026-08-23 22:11:09 +03:30
parent e8422c0006
commit aedfdbddb7
73 changed files with 2971 additions and 44 deletions

View File

@@ -0,0 +1,20 @@
---
#- synchronize:
# mode: pull
# #src: "rsync://{{ ansible_host }}{{ docker_root_directory }}/volumes/{{ traefik_backup_volume_name }}/_data/"
# src: rsync://{{ ansible_host }}/opt/
# dest: "{{ traefik_destination_backup_dir }}"
- name: Copy a "traefik certificate" file on the remote machine to controller host
copy:
src: "{{ docker_root_directory }}/volumes/{{ traefik_backup_volume_name }}/_data/"
remote_src: yes
dest: "{{ traefik_destination_backup_dir }}"
directory_mode: true
- name: Copy a "nexus data" file on the remote machine to controller host
copy:
src: "{{ docker_root_directory }}/volumes/{{ nexus_backup_volume_name }}/_data/"
dest: "{{ nexus_destination_backup_dir }}"
directory_mode: true
remote_src: yes

View File

@@ -0,0 +1,20 @@
---
# download images
- name: Docker module dependency | Login and pull image
apt:
name: "{{ item }}"
force_apt_get: yes
with_items:
- python3-docker
- docker-compose
register: apt_action
retries: 100
until: apt_action is success or ('Failed to lock apt for exclusive operation' not in apt_action.msg and '/var/lib/dpkg/lock' not in apt_action.msg)
- name: docker images pull
docker_image:
name: "{{ item }}"
source: pull
with_items:
- "{{ TRAEFIK_IMAGE }}:{{ TRAEFIK_VERSION }}"
- "{{ NEXUS_IMAGE }}:{{ NEXUS_VERSION }}"

View File

@@ -0,0 +1,10 @@
---
- name: pull all image
include: image-pull.yaml
- name: config and setup all service
include: repo-setup.yaml
#- name: get volumes backup
# include: get-backup.yaml
# tags: repo_get_backup

View File

@@ -0,0 +1,45 @@
---
- name: Creates directory
file:
path: "{{ item }}"
state: directory
loop:
- "{{ REPO_DIRE_NAME }}"
- "{{ REPO_DIRE_NAME }}/traefik"
- "{{ REPO_DIRE_NAME }}/traefik/certs"
- name: copy bash script
template:
src: nexus-setup-with-api.sh.j2
dest: "{{ REPO_DIRE_NAME }}/nexus-setup-with-api.sh"
- name: Copy trafik config file.
template:
src: traefik.yaml.j2
dest: "{{ REPO_DIRE_NAME }}/traefik/config.yml"
- name: copy Docker Compose files
template:
src: docker-compose.yaml.j2
dest: "{{ REPO_DIRE_NAME }}/docker-compose.yaml"
#- name: Build the docker-compose stack
# shell: docker compose -f "{{ REPO_DIRE_NAME }}"/docker-compose.yaml up -d
- name: Run `docker-compose up` again
docker_compose:
project_src: "{{ REPO_DIRE_NAME }}"
build: no
files:
- docker-compose.yaml
register: output
- debug:
var: output
- name: Pause for 2 minutes to run nexus service
pause:
minutes: 2
- name: Execute the script
command: bash "{{ REPO_DIRE_NAME }}/nexus-setup-with-api.sh"

View File

@@ -0,0 +1,97 @@
version: '3.4'
networks:
web_net:
external: false
name: web_net
volumes:
traefik-acme:
name: traefik-acme
nexus-data:
name: nexus-data
services:
traefik:
image: "{{TRAEFIK_IMAGE }}:{{TRAEFIK_VERSION}}"
restart: always
container_name: traefik
command:
- "--log.level=INFO"
- "--log.filepath=/log-file.log"
- "--log.format=json"
- "--api=true"
- "--ping=true"
- "--accesslog=true"
- "--accesslog.bufferingsize=100"
- "--api.insecure=true"
- "--providers.docker.endpoint=unix:///var/run/docker.sock"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=web_net"
- "--entrypoints.http.address=:80"
- "--entrypoints.https.address=:443"
- "--metrics.prometheus=true"
- "--entryPoints.metrics.address=:8082"
- "--metrics.prometheus.entryPoint=metrics"
- "--certificatesresolvers.mycert.acme.email={{ TRAEFIK_ACME_EMAIL }}"
- "--certificatesresolvers.mycert.acme.storage=/acme/acme.json"
- "--certificatesresolvers.mycert.acme.tlschallenge=true"
- "--providers.file.filename=/traefik/config.yml"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik:/traefik
- traefik-acme:/acme
networks:
- web_net
labels:
- "traefik.enable=true"
- "traefik.docker.network=web_net"
- "traefik.http.routers.traefik.entrypoints=http"
- "traefik.http.routers.traefik.rule=Host(`{{ TRAEFIK_SUB_DOMAIN }}.{{ DOMAIN_NAME }}`)"
- "traefik.http.routers.traefik.middlewares=https-redirect"
- "traefik.http.middlewares.https-redirect.redirectscheme.scheme=https"
- "traefik.http.middlewares.web-auth.basicauth.users={{ WEB_AUTH_USER }}:{{ WEB_AUTH_PASS }}"
- "traefik.http.routers.traefik-secure.middlewares=web-auth,security@file,hsts@file"
- "traefik.http.routers.traefik-secure.entrypoints=https"
- "traefik.http.routers.traefik-secure.rule=Host(`{{ TRAEFIK_SUB_DOMAIN }}.{{ DOMAIN_NAME }}`)"
- "traefik.http.routers.traefik-secure.tls=true"
- "traefik.http.routers.traefik-secure.tls.options=default"
- "traefik.http.routers.traefik-secure.tls.certresolver=mycert"
- "traefik.http.services.traefik.loadbalancer.server.port=8080"
nexus:
image: "{{ NEXUS_IMAGE }}:{{ NEXUS_VERSION }}"
container_name: nexus
restart: always
volumes:
- "nexus-data:/nexus-data"
networks:
- web_net
labels:
- "traefik.enable=true"
- "traefik.docker.network=web_net"
- "traefik.http.routers.repo.entrypoints=http"
- "traefik.http.routers.repo.rule=Host(`{{NEXUS_SUB_DOMAIN}}.{{ DOMAIN_NAME }}`)"
- "traefik.http.routers.repo.service=repo-secure"
- "traefik.http.routers.repo.middlewares=https-redirect"
- "traefik.http.routers.repo-secure.entrypoints=https"
- "traefik.http.routers.repo-secure.rule=Host(`{{NEXUS_SUB_DOMAIN}}.{{ DOMAIN_NAME }}`)"
- "traefik.http.routers.repo-secure.tls=true"
- "traefik.http.routers.repo-secure.tls.options=default"
- "traefik.http.routers.repo-secure.service=repo-secure"
- "traefik.http.routers.repo-secure.tls.certresolver=mycert"
- "traefik.http.services.repo-secure.loadbalancer.server.port=8081"
- "traefik.http.routers.hubdocker.entrypoints=http"
- "traefik.http.routers.hubdocker.rule=Host(`{{HUB_SUB_DOMAIN}}.{{ DOMAIN_NAME }}`)"
- "traefik.http.routers.hubdocker.middlewares=https-redirect"
- "traefik.http.routers.hubdocker-secure.entrypoints=https"
- "traefik.http.routers.hubdocker.service=hubdocker-secure"
- "traefik.http.routers.hubdocker-secure.rule=Host(`{{HUB_SUB_DOMAIN}}.{{ DOMAIN_NAME }}`)"
- "traefik.http.routers.hubdocker-secure.tls=true"
- "traefik.http.routers.hubdocker-secure.tls.options=default"
- "traefik.http.routers.hubdocker-secure.service=hubdocker-secure"
- "traefik.http.routers.hubdocker-secure.tls.certresolver=mycert"
- "traefik.http.services.hubdocker-secure.loadbalancer.server.port=8090"

View File

@@ -0,0 +1,216 @@
#!/bin/bash
# variable section
ADMIN_USERNAME={{ NEXUS_ADMIN_USERNAME }}
ADMIN_PASSWORD={{ NEXUS_ADMIN_PASSWORD }}
NEXUS_URL={{ NEXUS_SERVICE_URL }}
REPO_USERNAME={{ NEXUS_REPO_USERNAME }}
REPO_PASSWORD={{ NEXUS_REPO_PASSWORD }}
REPO_EMAIL={{ NEXUS_REPO_EMAIL }}
DOCKER_REPO_BLOBSTORE={{ DOCKER_REPO_BLOBSTORE }}
# -----------------------------------------------------
# writable state
curl -k -X 'GET' \
''${NEXUS_URL}'/service/rest/v1/status/writable' \
-H 'accept: application/json'
Nexus_Health=$(curl -k -X 'GET' ''${NEXUS_URL}'/service/rest/v1/status/writable' -H 'accept: application/json' 2>/dev/null)
echo ${Nexus_Health}
until [ -z "$Nexus_Health" ]
do
Nexus_Health=$(curl -k -X 'GET' ''${NEXUS_URL}'/service/rest/v1/status/writable' -H 'accept: application/json' 2>/dev/null)
echo ${Nexus_Health}
echo "Waiting for nexus starting..."
echo ${TIME}
TIME=$((TIME+1))
echo
sleep 1
done
echo "nexus writable state is ok"
# get bootstrap password
BOOTSTRAP_ADMIN_PASSWORD=$(docker exec -i nexus cat /nexus-data/admin.password)
echo ${BOOTSTRAP_ADMIN_PASSWORD}
# change password
curl -k -X 'PUT' \
''${NEXUS_URL}'/service/rest/v1/security/users/admin/change-password' \
-u "admin:${BOOTSTRAP_ADMIN_PASSWORD}" \
-H 'accept: application/json' \
-H 'Content-Type: text/plain' \
-d ''${ADMIN_PASSWORD}''
# delete default repository
curl -k -X 'DELETE' \
''${NEXUS_URL}'/service/rest/v1/repositories/maven-releases' \
-u "${ADMIN_USERNAME}:${ADMIN_PASSWORD}" \
-H 'accept: application/json'
curl -k -X 'DELETE' \
''${NEXUS_URL}'/service/rest/v1/repositories/maven-snapshots' \
-u "${ADMIN_USERNAME}:${ADMIN_PASSWORD}" \
-H 'accept: application/json'
curl -k -X 'DELETE' \
''${NEXUS_URL}'/service/rest/v1/repositories/maven-central' \
-u "${ADMIN_USERNAME}:${ADMIN_PASSWORD}" \
-H 'accept: application/json'
curl -k -X 'DELETE' \
''${NEXUS_URL}'/service/rest/v1/repositories/maven-public' \
-u "${ADMIN_USERNAME}:${ADMIN_PASSWORD}" \
-H 'accept: application/json'
curl -k -X 'DELETE' \
''${NEXUS_URL}'/service/rest/v1/repositories/nuget.org-proxy' \
-u "${ADMIN_USERNAME}:${ADMIN_PASSWORD}" \
-H 'accept: application/json'
curl -k -X 'DELETE' \
''${NEXUS_URL}'/service/rest/v1/repositories/nuget-group' \
-u "${ADMIN_USERNAME}:${ADMIN_PASSWORD}" \
-H 'accept: application/json'
curl -k -X 'DELETE' \
''${NEXUS_URL}'/service/rest/v1/repositories/nuget-hosted' \
-u "${ADMIN_USERNAME}:${ADMIN_PASSWORD}" \
-H 'accept: application/json'
# disable anonymous access
curl -k -X 'PUT' \
''${NEXUS_URL}'/service/rest/v1/security/anonymous' \
-u "${ADMIN_USERNAME}:${ADMIN_PASSWORD}" \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"enabled": false
}'
# activate realms
curl -k -X 'PUT' \
''${NEXUS_URL}'/service/rest/v1/security/realms/active' \
-u "${ADMIN_USERNAME}:${ADMIN_PASSWORD}" \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '[
"DockerToken",
"NexusAuthenticatingRealm",
"NexusAuthorizingRealm"
]'
# create role
curl -k -X 'POST' \
''${NEXUS_URL}'/service/rest/v1/security/roles' \
-u "${ADMIN_USERNAME}:${ADMIN_PASSWORD}" \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"id": "repo-admin",
"name": "repo-admin",
"description": "all repository admin",
"privileges": [
"nx-repository-admin-*-*-*"
]
}'
# create user
curl -k -X 'POST' \
''${NEXUS_URL}'/service/rest/v1/security/users' \
-u "${ADMIN_USERNAME}:${ADMIN_PASSWORD}" \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"userId": "'${REPO_USERNAME}'",
"firstName": "'${REPO_USERNAME}'",
"lastName": "afranet",
"emailAddress": "'${REPO_EMAIL}'",
"password": "'${REPO_PASSWORD}'",
"status": "active",
"roles": [
"repo-admin",
"nx-anonymous"
]
}'
curl -k -X 'POST' \
''${NEXUS_URL}'/service/rest/v1/blobstores/file' \
-u "${ADMIN_USERNAME}:${ADMIN_PASSWORD}" \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"softQuota": {
"type": "spaceRemainingQuota",
"limit": 102400
},
"path": "'${DOCKER_REPO_BLOBSTORE}'",
"name": "'${DOCKER_REPO_BLOBSTORE}'"
}'
# create docker proxy repository
curl -k -X 'POST' \
''${NEXUS_URL}'/service/rest/v1/repositories/docker/proxy' \
-u "${ADMIN_USERNAME}:${ADMIN_PASSWORD}" \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"name": "hub",
"online": true,
"storage": {
"blobStoreName": "'${DOCKER_REPO_BLOBSTORE}'",
"strictContentTypeValidation": true
},
"cleanup": {
"policyNames": [
"string"
]
},
"proxy": {
"remoteUrl": "https://mirror.gcr.io",
"contentMaxAge": 1440,
"metadataMaxAge": 1440
},
"negativeCache": {
"enabled": true,
"timeToLive": 1440
},
"httpClient": {
"blocked": false,
"autoBlock": true
},
"routingRule": "string",
"docker": {
"v1Enabled": true,
"forceBasicAuth": false,
"httpPort": 8090
},
"dockerProxy": {
"indexType": "HUB"
}
}'
# check all repositories
curl -k -X 'GET' \
''${NEXUS_URL}'/service/rest/v1/repositories' \
-u "${ADMIN_USERNAME}:${ADMIN_PASSWORD}" \
-H 'accept: application/json'
# check all blobstore
curl -k -X 'GET' \
''${NEXUS_URL}'/service/rest/v1/blobstores' \
-u "${ADMIN_USERNAME}:${ADMIN_PASSWORD}" \
-H 'accept: application/json'
# check all users and roles
curl -k -X 'GET' \
''${NEXUS_URL}'/service/rest/v1/security/users' \
-u "${ADMIN_USERNAME}:${ADMIN_PASSWORD}" \
-H 'accept: application/json'
curl -k -X 'GET' \
''${NEXUS_URL}'/service/rest/v1/security/roles' \
-u "${ADMIN_USERNAME}:${ADMIN_PASSWORD}" \
-H 'accept: application/json'

View File

@@ -0,0 +1,24 @@
http:
middlewares:
security:
headers:
frameDeny: true
contentTypeNosniff: true
browserXssFilter: true
hsts:
headers:
stsSeconds: 31536000
stsIncludeSubdomains: true
stsPreload: true
forceSTSHeader: true
tls:
options:
default:
minVersion: VersionTLS12
maxVersion: VersionTLS13
cipherSuites:
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
- TLS_AES_256_GCM_SHA384
- TLS_CHACHA20_POLY1305_SHA256