From 505bbe363ba7a2c4978d0f40f7f04a5d96d1ef0f Mon Sep 17 00:00:00 2001 From: hcornet Date: Wed, 18 Dec 2024 08:04:25 +0100 Subject: [PATCH] first sync --- .env | 97 ++++++++++++++++++++++- .pre-commit-config.yaml | 62 +++++++++++++++ .secrets.baseline | 171 ++++++++++++++++++++++++++++++++++++++++ ansible.cfg | 2 + docker-compose.yml | 169 +++++++++++++++++++++++++++++++++------ hosts.yml | 13 +++ playbook.yml | 37 +++++++++ 7 files changed, 526 insertions(+), 25 deletions(-) create mode 100644 .pre-commit-config.yaml create mode 100644 .secrets.baseline create mode 100644 ansible.cfg create mode 100644 hosts.yml create mode 100644 playbook.yml diff --git a/.env b/.env index 630b323..4f7a996 100644 --- a/.env +++ b/.env @@ -1 +1,96 @@ -# Template \ No newline at end of file +# +# postgres +# +POSTGRES_IMAGE_TAG=postgres:15.6-alpine +POSTGRE_DB_NAME=semaphore_db +POSTGRE_DB_USER=semaphore_user +POSTGRE_DB_PASSWORD=P@ssword!Here!123456 +POSTGRE_DB_DATA=/var/lib/postgresql/data/semaphore + +# +# semaphore +# +SEMAPHORE_VERSION=latest + +POSTGRE_DB_NAME=semaphore_db +POSTGRE_DB_USER=semaphore_user +POSTGRE_DB_PASS=P@ssword!Here!123456 + +SEMAPHORE_ADMIN=administrateur +SEMAPHORE_ADMIN_PASSWORD=P@ssword!Here!123456 +SEMAPHORE_ADMIN_NAME=Administrateur +SEMAPHORE_ADMIN_EMAIL=admin@tips-of-mine.fr + +SEMAPHORE_PORT=3000 + +SEMAPHORE_TMP_PATH=/tmp/semaphore +SEMAPHORE_WEB_ROOT=https://semaphore.tips-of-mine.com +MAX_TASK_DURATION_SEC=60 +SEMAPHORE_MAX_PARALLEL_TASKS=10 +SEMAPHORE_PASSWORD_LOGIN_DISABLED=False + +# +# Runner +# +SEMAPHORE_USE_REMOTE_RUNNER=True +SEMAPHORE_RUNNER_REGISTRATION_TOKEN=H1wDyorbg6gTSwJlVwle2Fne + +# +# +# +SEMAPHORE_NON_ADMIN_CAN_CREATE_PROJECT=False +SEMAPHORE_MAX_TASKS_PER_TEMPLATE=60 + +# +# Email +# +SEMAPHORE_EMAIL_ALERT=True +SEMAPHORE_EMAIL_SENDER=hostinfo@tips-of-mine.fr +SEMAPHORE_EMAIL_HOST=semaphore-msmtpd +SEMAPHORE_EMAIL_PORT=2500 +SEMAPHORE_EMAIL_SECURE=False} + +# +# local +# +SEMAPHORE_LDAP_ENABLE=False + +# +# Active Directory +# +#SEMAPHORE_LDAP_ACTIVATED: 'yes' +#SEMAPHORE_LDAP_HOST: dc01.local.tips-of-mine.local +#SEMAPHORE_LDAP_PORT: '636' +#SEMAPHORE_LDAP_NEEDTLS: 'yes' +#SEMAPHORE_LDAP_DN_BIND: 'uid=bind_user,cn=users,cn=accounts,dc=tips-of-mine,dc=local' +#SEMAPHORE_LDAP_PASSWORD: 'ldap_bind_account_password' +#SEMAPHORE_LDAP_DN_SEARCH: 'dc=tips-of-mine,dc=local' +#SEMAPHORE_LDAP_SEARCH_FILTER: "(\u0026(uid=%s)(memberOf=cn=ipausers,cn=groups,cn=accounts,dc=tips-of-mine,dc=local))" + +# +# Authentik +# +#SEMAPHORE_LDAP_ACTIVATED: "yes" +#SEMAPHORE_LDAP_SERVER: "ldap:3389" +#SEMAPHORE_LDAP_NEEDTLS: +#SEMAPHORE_LDAP_BIND_DN: "cn=ldapservice,ou=users,dc=ldap,dc=goauthentik,dc=io" +#SEMAPHORE_LDAP_PASSWORD: 'ldap_bind_account_password' +#SEMAPHORE_LDAP_SEARCH_DN: "ou=users,dc=ldap,dc=goauthentik,dc=io" +#SEMAPHORE_LDAP_SEARCH_FILTER: "(&(objectClass=inetOrgPerson)(cn=%s))" +#SEMAPHORE_NON_ADMIN_CAN_CREATE_PROJECT: "yes" +#SEMAPHORE_LDAP_MAPPING_DN: "dn" +#SEMAPHORE_LDAP_MAPPING_MAIL: "mail" +#SEMAPHORE_LDAP_MAPPING_UID: "uid" +#SEMAPHORE_LDAP_MAPPING_CN: "cn" + +# +# Gotify +# +SEMAPHORE_GOTIFY_ALERT=False +SEMAPHORE_GOTIFY_URL=https://gotify.tips-of-mine.com/#/applicationsd +SEMAPHORE_GOTIFY_TOKEN=AARDW0DNlz.eb1cd + +# +# Ansible +# +ANSIBLE_HOST_KEY_CHECKING=False \ No newline at end of file diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..97da6c6 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,62 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-added-large-files + - id: detect-private-key + - id: check-merge-conflict + - id: double-quote-string-fixer + - id: check-ast + - id: detect-aws-credentials + name: detect-aws-credentials + entry: detect-secrets + types: [file] + language: python + additional_dependencies: [detect-secrets==1.4.0] + files: .aws/credentials + + - repo: https://github.com/psf/black + rev: 24.4.2 + hooks: + - id: black + + - repo: https://github.com/PyCQA/isort + rev: 5.13.2 + hooks: + - id: isort + args: [--profile=black] + + - repo: https://github.com/Yelp/detect-secrets + rev: v1.5.0 + hooks: + - id: detect-secrets + args: ["--baseline", ".secrets.baseline"] + exclude: package.lock.json + + - repo: https://github.com/PyCQA/flake8 + rev: 7.1.0 + hooks: + - id: flake8 + + - repo: https://github.com/Lucas-C/pre-commit-hooks-safety + rev: v1.3.3 + hooks: + - id: python-safety-dependencies-check + + - repo: https://github.com/adrienverge/yamllint.git + rev: "v1.35.1" # Remplacez par la version actuelle de yamllint + hooks: + - id: yamllint + + - repo: https://github.com/ansible/ansible-lint + rev: "v24.6.1" # Remplacez par la version actuelle d'ansible-lint + hooks: + - id: ansible-lint + + - repo: https://github.com/biozz/ansible-pre-commit-hooks + rev: v0.0.1 + hooks: + - id: ansible-vault-encrypted diff --git a/.secrets.baseline b/.secrets.baseline new file mode 100644 index 0000000..8cb1979 --- /dev/null +++ b/.secrets.baseline @@ -0,0 +1,171 @@ +{ + "version": "1.5.0", + "plugins_used": [ + { + "name": "ArtifactoryDetector" + }, + { + "name": "AWSKeyDetector" + }, + { + "name": "AzureStorageKeyDetector" + }, + { + "name": "Base64HighEntropyString", + "limit": 4.5 + }, + { + "name": "BasicAuthDetector" + }, + { + "name": "CloudantDetector" + }, + { + "name": "DiscordBotTokenDetector" + }, + { + "name": "GitHubTokenDetector" + }, + { + "name": "GitLabTokenDetector" + }, + { + "name": "HexHighEntropyString", + "limit": 3.0 + }, + { + "name": "IbmCloudIamDetector" + }, + { + "name": "IbmCosHmacDetector" + }, + { + "name": "IPPublicDetector" + }, + { + "name": "JwtTokenDetector" + }, + { + "name": "KeywordDetector", + "keyword_exclude": "" + }, + { + "name": "MailchimpDetector" + }, + { + "name": "NpmDetector" + }, + { + "name": "OpenAIDetector" + }, + { + "name": "PrivateKeyDetector" + }, + { + "name": "PypiTokenDetector" + }, + { + "name": "SendGridDetector" + }, + { + "name": "SlackDetector" + }, + { + "name": "SoftlayerDetector" + }, + { + "name": "SquareOAuthDetector" + }, + { + "name": "StripeDetector" + }, + { + "name": "TelegramBotTokenDetector" + }, + { + "name": "TwilioKeyDetector" + } + ], + "filters_used": [ + { + "path": "detect_secrets.filters.allowlist.is_line_allowlisted" + }, + { + "path": "detect_secrets.filters.common.is_baseline_file", + "filename": ".secrets.baseline" + }, + { + "path": "detect_secrets.filters.common.is_ignored_due_to_verification_policies", + "min_level": 2 + }, + { + "path": "detect_secrets.filters.heuristic.is_indirect_reference" + }, + { + "path": "detect_secrets.filters.heuristic.is_likely_id_string" + }, + { + "path": "detect_secrets.filters.heuristic.is_lock_file" + }, + { + "path": "detect_secrets.filters.heuristic.is_not_alphanumeric_string" + }, + { + "path": "detect_secrets.filters.heuristic.is_potential_uuid" + }, + { + "path": "detect_secrets.filters.heuristic.is_prefixed_with_dollar_sign" + }, + { + "path": "detect_secrets.filters.heuristic.is_sequential_string" + }, + { + "path": "detect_secrets.filters.heuristic.is_swagger_file" + }, + { + "path": "detect_secrets.filters.heuristic.is_templated_secret" + } + ], + "results": { + "docker-compose.yml": [ + { + "type": "Secret Keyword", + "filename": "docker-compose.yml", + "hashed_secret": "fb360f9c09ac8c5edb2f18be5de4e80ea4c430d0", + "is_verified": false, + "line_number": 9 + }, + { + "type": "Secret Keyword", + "filename": "docker-compose.yml", + "hashed_secret": "61a4f51eb85a16603bd63347ef7cc8b7779b5963", + "is_verified": false, + "line_number": 12 + }, + { + "type": "Secret Keyword", + "filename": "docker-compose.yml", + "hashed_secret": "fa9beb99e4029ad5a6615399e7bbae21356086b3", + "is_verified": false, + "line_number": 26 + }, + { + "type": "Secret Keyword", + "filename": "docker-compose.yml", + "hashed_secret": "fc544380162745e4826f7040176ce443d4d345b9", + "is_verified": false, + "line_number": 38 + } + ], + "hosts.yml": [ + { + "type": "Secret Keyword", + "filename": "hosts.yml", + "hashed_secret": "b3a5425f7ebac5a1b19d0d34418ce0a4f64a7a51", + "is_verified": false, + "line_number": 11 + } + ] + }, + "generated_at": "2024-07-05T02:45:41Z" +} diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 0000000..c75b36b --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,2 @@ +[privilege_escalation] +become_ask_pass = true diff --git a/docker-compose.yml b/docker-compose.yml index 4054566..24d017b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,41 +2,162 @@ networks: traefik_front_network: external: true - back_network_: + back_network_semaphore: driver: bridge attachable: true #### SERVICES services: -### hello_world - hello_world: - container_name: gitea-app - hostname: gitea-app - image: hello-world - environment: +### semaphore + semaphore: + container_name: semaphore-app + hostname: semaphore-app + image: docker.io/semaphoreui/semaphore:${SEMAPHORE_VERSION:-latest} restart: always - networks: -# - back_network_gitea - - traefik_front_network + environment: + SEMAPHORE_DB_DIALECT: postgres + SEMAPHORE_DB_HOST: semaphore-postgres + SEMAPHORE_DB_NAME: ${POSTGRE_DB_NAME:-semaphore_db} + SEMAPHORE_DB_USER: ${POSTGRE_DB_USER:-semaphore_user} + SEMAPHORE_DB_PASS: ${POSTGRE_DB_PASS:-P@ssword!Here!123456} + + SEMAPHORE_ADMIN: ${SEMAPHORE_ADMIN:-administrateur} + SEMAPHORE_ADMIN_PASSWORD: ${SEMAPHORE_ADMIN_PASSWORD:-P@ssword!Here!123456} + SEMAPHORE_ADMIN_NAME: ${SEMAPHORE_ADMIN_NAME:-Administrateur} + SEMAPHORE_ADMIN_EMAIL: ${SEMAPHORE_ADMIN_EMAIL:-admin@tips-of-mine.fr} + + SEMAPHORE_PORT: ${SEMAPHORE_PORT:-3000} + + SEMAPHORE_TMP_PATH: ${SEMAPHORE_TMP_PATH:-/tmp/semaphore} + SEMAPHORE_WEB_ROOT: ${SEMAPHORE_WEB_ROOT:-https://semaphore.tips-of-mine.com} + MAX_TASK_DURATION_SEC: ${MAX_TASK_DURATION_SEC:-60} + SEMAPHORE_MAX_PARALLEL_TASKS: ${SEMAPHORE_MAX_PARALLEL_TASKS:-10} + SEMAPHORE_PASSWORD_LOGIN_DISABLED: ${SEMAPHORE_PASSWORD_LOGIN_DISABLED:-False} + + SEMAPHORE_USE_REMOTE_RUNNER: ${SEMAPHORE_USE_REMOTE_RUNNER:-True} + SEMAPHORE_RUNNER_REGISTRATION_TOKEN: ${SEMAPHORE_RUNNER_REGISTRATION_TOKEN:-H1wDyorbg6gTSwJlVwle2Fne} + + SEMAPHORE_NON_ADMIN_CAN_CREATE_PROJECT: ${SEMAPHORE_NON_ADMIN_CAN_CREATE_PROJECT:-False} + SEMAPHORE_MAX_TASKS_PER_TEMPLATE: ${SEMAPHORE_MAX_TASKS_PER_TEMPLATE:-60} + + SEMAPHORE_EMAIL_ALERT: ${SEMAPHORE_EMAIL_ALERT:-True} + SEMAPHORE_EMAIL_SENDER: $SEMAPHORE_EMAIL_SENDER:-hostinfo@tips-of-mine.fr} + SEMAPHORE_EMAIL_HOST: ${SEMAPHORE_EMAIL_HOST:-semaphore-msmtpd} + SEMAPHORE_EMAIL_PORT: ${SEMAPHORE_EMAIL_PORT:-2500} + SEMAPHORE_EMAIL_SECURE: ${SEMAPHORE_EMAIL_SECURE:-False} + + SEMAPHORE_LDAP_ENABLE: ${:-False} + SEMAPHORE_LDAP_BIND_DN: ${SEMAPHORE_LDAP_BIND_DN:-} + SEMAPHORE_LDAP_BIND_PASSWORD: ${SEMAPHORE_LDAP_BIND_PASSWORD:-} + SEMAPHORE_LDAP_SERVER: ${SEMAPHORE_LDAP_SERVER:-} + SEMAPHORE_LDAP_SEARCH_DN: ${SEMAPHORE_LDAP_SEARCH_DN:-} + SEMAPHORE_LDAP_SEARCH_FILTER: ${SEMAPHORE_LDAP_SEARCH_FILTER:-} + SEMAPHORE_LDAP_NEEDTLS: ${SEMAPHORE_LDAP_NEEDTLS:-} + SEMAPHORE_LDAP_MAPPING_DN: ${SEMAPHORE_LDAP_MAPPING_DN:-} + SEMAPHORE_LDAP_MAPPING_MAIL: ${SEMAPHORE_LDAP_MAPPING_MAIL:-} + SEMAPHORE_LDAP_MAPPING_UID: ${SEMAPHORE_LDAP_MAPPING_UID:-} + SEMAPHORE_LDAP_MAPPING_CN: ${SEMAPHORE_LDAP_MAPPING_CN:-} + + SEMAPHORE_GOTIFY_ALERT: ${SEMAPHORE_GOTIFY_ALERT:-False} + SEMAPHORE_GOTIFY_URL: ${SEMAPHORE_GOTIFY_URL:-https://gotify.tips-of-mine.com/#/applicationsd} + SEMAPHORE_GOTIFY_TOKEN: ${SEMAPHORE_GOTIFY_TOKEN:-AARDW0DNlz.eb1cd} + + ANSIBLE_HOST_KEY_CHECKING: ${ANSIBLE_HOST_KEY_CHECKING:-False} + depends_on: + postgres: + condition: service_healthy + restart: true + msmtpd: + condition: service_healthy + restart: true volumes: + - ./data:/var/lib/semaphore + - ./config:/etc/semaphore + - ./tmp:/tmp/semaphore + networks: + - back_network_semaphore + - traefik_front_network labels: - "traefik.enable=true" - "traefik.docker.network=traefik_front_network" # HTTP - - "traefik.http.routers.hello-world-http.rule=Host(`hello-world.tips-of-mine.com`)" - - "traefik.http.routers.hello-world-http.entrypoints=http" - - "traefik.http.routers.hello-world-http.priority=49" + - "traefik.http.routers.semaphore-http.rule=Host(`semaphore.tips-of-mine.com`)" + - "traefik.http.routers.semaphore-http.entrypoints=http" + - "traefik.http.routers.semaphore-http.priority=49" # HTTPS - - "traefik.http.routers.hello-world-https.rule=Host(`hello-world.tips-of-mine.com`)" - - "traefik.http.routers.hello-world-https.entrypoints=https" - - "traefik.http.routers.hello-world-https.tls=true" - - "traefik.http.routers.hello-world-https.priority=50" - - "traefik.http.routers.gitea.service=gitea-https-service" + - "traefik.http.routers.semaphore-https.rule=Host(`semaphore.tips-of-mine.com`)" + - "traefik.http.routers.semaphore-https.entrypoints=https" + - "traefik.http.routers.semaphore-https.tls=true" + - "traefik.http.routers.semaphore-https.priority=50" + - "traefik.http.routers.semaphore.service=semaphore-https-service" # Middleware # Service -# - "traefik.http.services.gitea-https-service.loadbalancer.server.port=3000" -# - "traefik.http.services.gitea-https-service.loadbalancer.server.scheme=https" -# - "traefik.http.services.gitea-https-service.loadbalancer.healthcheck.hostname=gitea.traefik.me" -# - "traefik.http.services.gitea-https-service.loadbalancer.healthcheck.method=foobar" -# - "traefik.http.services.gitea-https-service.loadbalancer.healthcheck.timeout=10" -# - "traefik.http.services.gitea-https-service.loadbalancer.healthcheck.interval=30" + - "traefik.http.services.semaphore-https-service.loadbalancer.server.port=3000" +# - "traefik.http.services.semaphore-https-service.loadbalancer.server.scheme=https" +# - "traefik.http.services.semaphore-https-service.loadbalancer.healthcheck.hostname=semaphore.traefik.me" +# - "traefik.http.services.semaphore-https-service.loadbalancer.healthcheck.method=foobar" +# - "traefik.http.services.semaphore-https-service.loadbalancer.healthcheck.timeout=10" +# - "traefik.http.services.semaphore-https-service.loadbalancer.healthcheck.interval=30" + +### runner + runner: + container_name: semaphore-runner + hostname: semaphore-runner + image: docker.io/semaphoreui/runner:${SEMAPHORE_VERSION:-latest} + restart: always + environment: + SEMAPHORE_WEB_ROOT: ${SEMAPHORE_WEB_ROOT:-http://server:3000} + SEMAPHORE_RUNNER_API_URL: ${SEMAPHORE_RUNNER_API_URL:-http://server:3000/internal} + SEMAPHORE_RUNNER_REGISTRATION_TOKEN: ${SEMAPHORE_RUNNER_REGISTRATION_TOKEN:-H1wDyorbg6gTSwJlVwle2Fne} + networks: + - back_network_semaphore + +### postgres + postgres: + container_name: semaphore-postgres + hostname: semaphore-postgres + image: ${POSTGRES_IMAGE_TAG} + environment: + PGDATA: ${POSTGRE_DB_DATA} + POSTGRES_DB: ${POSTGRE_DB_NAME:-semaphore_db} + POSTGRES_PASSWORD: ${POSTGRE_DB_PASSWORD:-P@ssword!Here!123456} + POSTGRES_USER: ${POSTGRE_DB_USER:-semaphore_user} + TZ: Europe/Paris + networks: + - back_network_semaphore + healthcheck: + test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"] + interval: 30s + timeout: 10s + retries: 10 + restart: always + volumes: + - ./data:/var/lib/postgresql/data:rw + +### + msmtpd: + container_name: semaphore-msmtpd + hostname: semaphore-msmtpd + image: crazymax/msmtpd:latest + networks: + - back_network_semaphore + environment: + - "TZ=Europe/Paris" + - "PUID=1500" + - "PGID=1500" + - "SMTP_HOST=10.0.4.52" + - "SMTP_PORT=587" + - "SMTP_TLS=on" + - "SMTP_STARTTLS=on" + - "SMTP_TLS_CHECKCERT=off" + - "SMTP_AUTH=on" + - "SMTP_USER=hostinfo@tips-of-mine.fr" + - "SMTP_PASSWORD=P@ssw0rd!12345+" + - "SMTP_DOMAIN=localhost" + - "SMTP_FROM=hostinfo@tips-of-mine.fr" + restart: always + healthcheck: + test: ["CMD-SHELL", "echo EHLO localhost"] + interval: 5s + timeout: 5s + retries: 5 \ No newline at end of file diff --git a/hosts.yml b/hosts.yml new file mode 100644 index 0000000..09dfc0a --- /dev/null +++ b/hosts.yml @@ -0,0 +1,13 @@ +all: + vars: + ansible_user: ubuntu + ansible_ssh_common_args: '-o StrictHostKeyChecking=no' +prod: + hosts: + client: + ansible_host: 52.90.84.191 + vars: + env: production + ansible_password: centos + red_color: "red" + blue_color: "blue" diff --git a/playbook.yml b/playbook.yml new file mode 100644 index 0000000..a1bbd50 --- /dev/null +++ b/playbook.yml @@ -0,0 +1,37 @@ +--- +- name: Deploy Docker containers with different colors + hosts: prod + become: true + tasks: + - name: Deploy web-color container with default color + community.docker.docker_container: + name: web-color + image: "kodekloud/webapp-color" + env: + APP_COLOR: "{{ default_color | default('') }}" + ports: + - "8080:8080" + tags: + - deploy + + - name: Deploy web-color container with red color + community.docker.docker_container: + name: web-red-color + image: "kodekloud/webapp-color" + env: + APP_COLOR: "{{ red_color }}" + ports: + - "80:8080" + tags: + - red_color + + - name: Deploy web-color container with yellow color + community.docker.docker_container: + name: web-blue-color + image: "kodekloud/webapp-color" + env: + APP_COLOR: "{{ blue_color }}" + ports: + - "443:8080" + tags: + - blue_color