added the a preparing ansible playbooks for automating new servers
This commit is contained in:
@@ -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
|
||||
@@ -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 }}"
|
||||
@@ -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
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
@@ -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'
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user