375 lines
14 KiB
YAML
375 lines
14 KiB
YAML
---
|
|
- name: Swarm
|
|
hosts:
|
|
- swarm
|
|
become: true
|
|
|
|
#
|
|
# corentinth/it-tools:latest => dinguerie
|
|
#
|
|
|
|
# apt-get install sshpass
|
|
|
|
# #
|
|
# # @author Stéphane Gratias (2021).
|
|
#
|
|
|
|
pre_tasks:
|
|
# - name: Create node_exporter cert dir
|
|
# file:
|
|
# path: "{{ item }}"
|
|
# state: directory
|
|
# owner: root
|
|
# group: root
|
|
# loop:
|
|
# - /etc/node_exporter
|
|
|
|
####lala
|
|
### lala
|
|
|
|
# - name: Generate an OpenSSL private key with the default values (4096 bits, RSA)
|
|
# community.crypto.openssl_privatekey:
|
|
# path: /etc/node_exporter/tls.key
|
|
# mode: 0644
|
|
|
|
# # /etc/node_exporter# chmod 644 tls.key
|
|
|
|
# - name: Generate an OpenSSL Certificate Signing Request
|
|
# community.crypto.openssl_csr:
|
|
# path: /etc/node_exporter/tls.csr
|
|
# privatekey_path: /etc/node_exporter/tls.key
|
|
# common_name: "{{ inventory_hostname }}.netbird.cloud"
|
|
|
|
# - name: Generate a Self Signed OpenSSL certificate
|
|
# community.crypto.x509_certificate:
|
|
# path: /etc/node_exporter/tls.cert
|
|
# privatekey_path: /etc/node_exporter/tls.key
|
|
# csr_path: /etc/node_exporter/tls.csr
|
|
# provider: selfsigned
|
|
|
|
# roles:
|
|
# # - { role: geerlingguy.docker, tags: docker }
|
|
# - { role: thomasjpfan.docker-swarm, tags: pip }
|
|
|
|
|
|
# # touch /etc/docker/daemon.json
|
|
# - ansible.builtin.include_role:
|
|
# name: softing.swarm.softing_swarm_server
|
|
# vars:
|
|
# swarm_server_node_ip: "0.0.0.0"
|
|
# swarm_server_hostname: "{{ hostname }}"
|
|
# swarm_server_ca_domain: "{{ domain }}"
|
|
# swarm_server_ca_folder: "/resources/swarm"
|
|
|
|
|
|
|
|
roles:
|
|
- { role: geerlingguy.pip, tags: pip }
|
|
- { role: geerlingguy.docker, tags: docker }
|
|
- { role: asg1612.dockerswarm, tags: swarm }
|
|
|
|
tasks:
|
|
|
|
- name: Create network
|
|
community.docker.docker_network:
|
|
name: "{{ item.name }}"
|
|
scope: swarm
|
|
driver: overlay
|
|
internal: false
|
|
attachable: "{{ item.attachable }}"
|
|
run_once: true
|
|
loop:
|
|
- name: agent_network
|
|
attachable: true
|
|
- name: public
|
|
attachable: false
|
|
when: inventory_hostname in groups['docker_swarm_manager']
|
|
|
|
- name: Create volume
|
|
community.docker.docker_volume:
|
|
name: portainer_data
|
|
run_once: true
|
|
when: inventory_hostname in groups['docker_swarm_manager']
|
|
|
|
- name: Create secret (from a file on the control machine)
|
|
community.docker.docker_secret:
|
|
name: "{{ item.name }}"
|
|
# If the file is JSON or binary, Ansible might modify it (because
|
|
# it is first decoded and later re-encoded). Base64-encoding the
|
|
# file directly after reading it prevents this to happen.
|
|
data: "{{ lookup('file', '{{ playbook_dir }}/{{ item.path }}') | b64encode }}"
|
|
data_is_b64: true
|
|
state: present
|
|
loop:
|
|
- name: wildcard-jingoh-private.crt
|
|
path: /files/swarm/tls/jingoh.private.crt
|
|
- name: wildcard-jingoh-private.key
|
|
path: /files/swarm/tls/jingoh.private.key
|
|
run_once: true
|
|
when: inventory_hostname in groups['docker_swarm_manager']
|
|
|
|
- name: Create config (from a file on the control machine)
|
|
community.docker.docker_config:
|
|
name: traefik-dynamic-configuration
|
|
# If the file is JSON or binary, Ansible might modify it (because
|
|
# it is first decoded and later re-encoded). Base64-encoding the
|
|
# file directly after reading it prevents this to happen.
|
|
data: "{{ lookup('file', '{{ playbook_dir }}/files/swarm/config/traefik-dynamic-configuration.yml') | b64encode }}"
|
|
data_is_b64: true
|
|
state: present
|
|
run_once: true
|
|
when: inventory_hostname in groups['docker_swarm_manager']
|
|
|
|
# - name: Change file ownership, group and permissions
|
|
# ansible.builtin.file:
|
|
# path: /opt/stack.yml
|
|
# owner: root
|
|
# group: root
|
|
# mode: '0644'
|
|
# state: touch
|
|
# when: inventory_hostname in groups['docker_swarm_manager']
|
|
|
|
- name: Copy the stack
|
|
ansible.builtin.copy:
|
|
content: "version: '3.12'"
|
|
dest: /opt/stack.yml
|
|
when: inventory_hostname in groups['docker_swarm_manager']
|
|
|
|
# - name: Copy file with owner and permissions
|
|
# ansible.builtin.copy:
|
|
# src: /{{ playbook_dir }}/files/swarm/stack.yml
|
|
# dest: /opt/stack.yml
|
|
# owner: root
|
|
# group: root
|
|
# mode: '0644'
|
|
# run_once: true
|
|
# when: inventory_hostname in groups['docker_swarm_manager']
|
|
|
|
- name: Deploy stack from a compose file
|
|
community.docker.docker_stack:
|
|
state: present
|
|
name: cluster
|
|
compose:
|
|
- /opt/stack.yml
|
|
- version: '3.12'
|
|
# https://github.com/akhil/traefik-docker-swarm-example/blob/master/traefik.yml
|
|
- services:
|
|
traefik:
|
|
# Image tag (replace with yours)
|
|
image: traefik:latest
|
|
command:
|
|
- "--log.level=DEBUG"
|
|
- "--accesslog=true"
|
|
- "--api.dashboard=true"
|
|
- "--api.insecure=true"
|
|
- "--entryPoints.web.address=:80"
|
|
- "--entryPoints.websecure.address=:443"
|
|
- "--providers.docker=true"
|
|
- "--providers.docker.watch=true"
|
|
- "--providers.swarm=true"
|
|
- "--providers.docker.network=public"
|
|
- "--providers.docker.endpoint=unix:///var/run/docker.sock"
|
|
- "--providers.docker.exposedByDefault=false"
|
|
- "--providers.file.filename=/etc/traefik/configs/traefik-dynamic-configuration.yml"
|
|
# - "--metrics.prometheus=true"
|
|
# - "--metrics.prometheus.buckets=0.1,0.3,1.2,5.0"
|
|
- "--global.checkNewVersion=true"
|
|
- "--global.sendAnonymousUsage=false"
|
|
volumes:
|
|
- "/var/run/docker.sock:/var/run/docker.sock:ro"
|
|
networks:
|
|
- public
|
|
# ports:
|
|
# - "80:80"
|
|
# - "443:443"
|
|
ports:
|
|
- target: 80
|
|
published: 80
|
|
protocol: tcp
|
|
mode: host
|
|
- target: 443
|
|
published: 443
|
|
protocol: tcp
|
|
mode: host
|
|
# - target: 443
|
|
# published: 443
|
|
# protocol: udp
|
|
# mode: host
|
|
# For Mattermost
|
|
# - "8443:8443"
|
|
configs:
|
|
- source: traefik-dynamic-configuration
|
|
target: /etc/traefik/configs/traefik-dynamic-configuration.yml
|
|
secrets:
|
|
- wildcard-jingoh-private.crt
|
|
- wildcard-jingoh-private.key
|
|
labels:
|
|
- "io.portainer.accesscontrol.public"
|
|
deploy:
|
|
mode: replicated
|
|
replicas: 1
|
|
placement:
|
|
constraints:
|
|
- node.role == manager
|
|
update_config:
|
|
delay: 15s
|
|
parallelism: 1
|
|
monitor: 10s
|
|
failure_action: rollback
|
|
max_failure_ratio: 0.55
|
|
labels:
|
|
- "traefik.enable=true"
|
|
# Traefik URL (replace with yours)
|
|
- "traefik.http.routers.dashboard.rule=Host(`traefikswarm.jingoh.private`)"
|
|
- "traefik.http.routers.dashboard.service=api@internal"
|
|
- "traefik.http.routers.dashboard.entrypoints=websecure"
|
|
- "traefik.http.services.dashboard.loadbalancer.server.port=8080"
|
|
- "traefik.http.routers.dashboard.tls=true"
|
|
- "traefik.http.services.dashboard.loadbalancer.passhostheader=true"
|
|
- "traefik.http.routers.http-catchall.rule=HostRegexp(`{host:.+}`)"
|
|
- "traefik.http.routers.http-catchall.entrypoints=web"
|
|
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
|
|
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
|
|
- "traefik.http.middlewares.privatevpn.ipwhitelist.sourcerange=100.96.0.0/16"
|
|
# - "traefik.http.routers.dashboard.middlewares=privatevpn"
|
|
agent:
|
|
image: portainer/agent:latest
|
|
environment:
|
|
# REQUIRED: Should be equal to the service name prefixed by "tasks." when
|
|
# deployed inside an overlay network
|
|
AGENT_CLUSTER_ADDR: tasks.agent
|
|
AGENT_PORT: 9001
|
|
LOG_LEVEL: DEBUG
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
- /var/lib/docker/volumes:/var/lib/docker/volumes
|
|
networks:
|
|
- agent_network
|
|
labels:
|
|
- "io.portainer.accesscontrol.public"
|
|
deploy:
|
|
mode: global
|
|
placement:
|
|
constraints: [node.platform.os == linux]
|
|
|
|
portainer:
|
|
image: portainer/portainer-ce:latest
|
|
command: -H tcp://tasks.agent:9001 --tlsskipverify
|
|
volumes:
|
|
- portainer_data:/data
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
networks:
|
|
- public
|
|
- agent_network
|
|
labels:
|
|
- "io.portainer.accesscontrol.public"
|
|
deploy:
|
|
mode: replicated
|
|
replicas: 1
|
|
placement:
|
|
constraints: [node.role == manager]
|
|
labels:
|
|
# Frontend
|
|
- "traefik.enable=true"
|
|
- "traefik.docker.network=public"
|
|
- "traefik.http.routers.frontend.rule=Host(`portainer.jingoh.private`)"
|
|
- "traefik.http.routers.frontend.entrypoints=websecure"
|
|
- "traefik.http.services.frontend.loadbalancer.server.port=9000"
|
|
- "traefik.http.routers.frontend.service=frontend"
|
|
- "traefik.http.routers.frontend.tls=true"
|
|
- "traefik.http.routers.frontend.middlewares=privatevpn"
|
|
# Edge
|
|
- "traefik.http.routers.edge.rule=Host(`edge.jingoh.private`)"
|
|
- "traefik.http.routers.edge.entrypoints=websecure"
|
|
- "traefik.http.services.edge.loadbalancer.server.port=8000"
|
|
- "traefik.http.routers.edge.service=edge"
|
|
- "traefik.http.routers.edge.tls=true"
|
|
- "traefik.http.routers.edge.middlewares=privatevpn"
|
|
whoami:
|
|
image: "traefik/whoami"
|
|
labels:
|
|
- "io.portainer.accesscontrol.public"
|
|
deploy:
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.docker.network=public"
|
|
- "traefik.http.routers.whoami.rule=Host(`whoamitest.jingoh.private`)"
|
|
- "traefik.http.routers.whoami.entrypoints=websecure"
|
|
- "traefik.http.services.whoami.loadbalancer.server.port=80"
|
|
- "traefik.http.routers.whoami.tls=true"
|
|
- "traefik.http.routers.whoami.middlewares=privatevpn"
|
|
networks:
|
|
- public
|
|
|
|
networks:
|
|
public:
|
|
external: true
|
|
agent_network:
|
|
external: true
|
|
attachable: true
|
|
volumes:
|
|
portainer_data:
|
|
|
|
|
|
|
|
configs:
|
|
traefik-dynamic-configuration:
|
|
external: true
|
|
|
|
secrets:
|
|
wildcard-jingoh-private.crt:
|
|
external: true
|
|
|
|
wildcard-jingoh-private.key:
|
|
external: true
|
|
|
|
run_once: true
|
|
when: inventory_hostname in groups['docker_swarm_manager']
|
|
|
|
# docker network create -d overlay agent_network
|
|
# docker network create -d overlay public
|
|
# docker volume create portainer_data
|
|
|
|
# Create a secret for storing the certificate using the command:
|
|
# docker secret create wildcard-jingoh-private.crt jingoh.private.crt
|
|
|
|
# Create a secret for storing the key using the command:
|
|
# docker secret create wildcard-jingoh-private.key jingoh.private.key
|
|
|
|
# Create a config for storing the Traefik configuration using the command:
|
|
# docker config create traefik-dynamic-configuration.yml traefik-dynamic-configuration.yml
|
|
|
|
# docker stack deploy -c stack.yml stack
|
|
|
|
# - ansible.builtin.include_role:
|
|
# name: softing.swarm.softing_swarm_certs
|
|
# apply:
|
|
# become: false
|
|
# delegate_to: "localhost"
|
|
# run_once: true
|
|
# vars:
|
|
# swarm_certs_domain: "swarm.domain.com"
|
|
# swarm_certs_folder: "{{ playbook_dir }}/resources/swarm"
|
|
# swarm_certs_nodes:
|
|
# - ip: 192.168.50.4
|
|
# hostname: manager
|
|
# domain: domain.com
|
|
# - ip: 192.168.50.40
|
|
# hostname: worker1
|
|
# domain: domain.com
|
|
# - ip: 192.168.50.44
|
|
# hostname: worker2
|
|
# domain: domain.com
|
|
|
|
# - ansible.builtin.include_role:
|
|
# name: softing.swarm.softing_swarm_initialize
|
|
# public: yes
|
|
# vars:
|
|
# swarm_master_ip: 192.168.50.4
|
|
|
|
# - ansible.builtin.include_role:
|
|
# name: "softing_swarm_worker"
|
|
# vars:
|
|
# swarm_worker_token: "{{ worker_token }}"
|
|
# swarm_master_host: "192.168.121.47"
|
|
# when: inventory_hostname in group['testworker'] |