feat: Create docker outpost
This commit is contained in:
parent
293e18a821
commit
993a91f380
@ -1,3 +1,5 @@
|
||||
dns_server:
|
||||
admin_username: "{{ secrets.admin_username }}"
|
||||
admin_password: "{{ secrets.admin_password }}"
|
||||
|
||||
portainer_agent_secret: "{{ secrets.portainer_agent_secret }}"
|
||||
|
73
ansible/jumper.yml
Normal file
73
ansible/jumper.yml
Normal file
@ -0,0 +1,73 @@
|
||||
---
|
||||
- name: Install
|
||||
hosts: jumper
|
||||
remote_user: ubuntu
|
||||
vars:
|
||||
pv_disks:
|
||||
- /dev/sda
|
||||
vg_name: vg1
|
||||
lv_name: pvs
|
||||
lv_size: +100%FREE
|
||||
fs_type: ext4
|
||||
mount_path: /mnt/docker
|
||||
extra_docker_daemon_options: |
|
||||
"data-root": "/mnt/docker/docker-root"
|
||||
tasks:
|
||||
- import_role: name=dns-client
|
||||
|
||||
- import_role: name=lvm
|
||||
|
||||
- name: Ensure docker root exists
|
||||
become: true
|
||||
file:
|
||||
path: /mnt/docker/docker-root
|
||||
state: directory
|
||||
mode: "0755"
|
||||
|
||||
- import_role: name=docker
|
||||
|
||||
- name: Run portainer agent
|
||||
become: true
|
||||
docker_container:
|
||||
name: portainer_agent
|
||||
image: portainer/agent:2.16.2
|
||||
ports:
|
||||
- "9001:9001"
|
||||
env:
|
||||
AGENT_SECRET: "{{ portainer_agent_secret }}"
|
||||
restart_policy: unless-stopped
|
||||
mounts:
|
||||
- type: bind
|
||||
source: /var/run/docker.sock
|
||||
target: /var/run/docker.sock
|
||||
- type: bind
|
||||
source: /mnt/docker/docker-root/volumes
|
||||
target: /var/lib/docker/volumes
|
||||
|
||||
- name: Mount extra shares
|
||||
tags: [extra-shares]
|
||||
hosts: jumper
|
||||
vars:
|
||||
shares:
|
||||
- src: truenas.local:/mnt/emc14t9/lfs/media
|
||||
path: /mnt/media
|
||||
opts: rw,_netdev,hard,intr,nolock
|
||||
fstype: nfs
|
||||
state: mounted
|
||||
tasks:
|
||||
- name: Ensure mount directory exists
|
||||
become: true
|
||||
file:
|
||||
path: "{{ item.path }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
loop: "{{ shares }}"
|
||||
- name: Mount media share
|
||||
become: true
|
||||
mount:
|
||||
src: "{{ item.src }}"
|
||||
path: "{{ item.path }}"
|
||||
opts: "{{ item.opts }}"
|
||||
state: "{{ item.state | default('mounted') }}"
|
||||
fstype: "{{ item.fstype }}"
|
||||
loop: "{{ shares }}"
|
@ -10,33 +10,5 @@
|
||||
lv_size: "{{ lvm.lv_size }}"
|
||||
fs_type: "{{ lvm.fs_type }}"
|
||||
mount_path: "{{ lvm.mount_path }}"
|
||||
tasks:
|
||||
- name: Create a volume group
|
||||
community.general.lvg:
|
||||
vg: "{{ vg_name }}"
|
||||
pvs: "{{ pv_disks }}"
|
||||
pvresize: yes
|
||||
|
||||
- name: Create Logical Volume for data persistence
|
||||
community.general.lvol:
|
||||
vg: "{{ vg_name }}"
|
||||
lv: "{{ lv_name }}"
|
||||
size: "{{ lv_size }}"
|
||||
|
||||
- name: Create filesystem on LV
|
||||
community.general.filesystem:
|
||||
fstype: "{{ fs_type }}"
|
||||
resizefs: true
|
||||
dev: /dev/mapper/{{ vg_name }}-{{ lv_name }}
|
||||
|
||||
- name: Get LV UUID
|
||||
ansible.builtin.command: lsblk /dev/mapper/{{ vg_name }}-{{ lv_name }} -no UUID
|
||||
register: lv_uuid
|
||||
changed_when: false
|
||||
|
||||
- name: Mount created filesystem
|
||||
ansible.posix.mount:
|
||||
path: "{{ mount_path }}"
|
||||
src: UUID={{ lv_uuid.stdout }}
|
||||
state: mounted
|
||||
fstype: "{{ fs_type }}"
|
||||
roles:
|
||||
- lvm
|
||||
|
20
ansible/roles/dns-client/tasks/main.yml
Normal file
20
ansible/roles/dns-client/tasks/main.yml
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
- name: Set DNS servers
|
||||
become: true
|
||||
tags: [set_dns_servers]
|
||||
copy:
|
||||
content: |
|
||||
[Resolve]
|
||||
DNS=10.0.123.123
|
||||
# FallbackDNS=1.1.1.1
|
||||
dest: /etc/systemd/resolved.conf
|
||||
register: dns_servers_configuration
|
||||
|
||||
- name: Restart systemd-resolved
|
||||
tags: [set_dns_servers]
|
||||
service:
|
||||
name: systemd-resolved
|
||||
state: restarted
|
||||
when: dns_servers_configuration.changed
|
||||
retries: 2
|
||||
|
@ -1,52 +1,4 @@
|
||||
---
|
||||
- name: Create /etc/docker
|
||||
become: true
|
||||
file:
|
||||
path: /etc/docker
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Set docker daemon settings
|
||||
become: true
|
||||
# Otherwise we risk conflicts on the host subnet
|
||||
copy:
|
||||
content: |
|
||||
{
|
||||
"default-address-pools": [
|
||||
{
|
||||
"base": "172.17.0.0/12",
|
||||
"size": 20
|
||||
},
|
||||
{
|
||||
"base": "172.168.0.0/16",
|
||||
"size": 24
|
||||
}
|
||||
],
|
||||
"dns": ["10.0.123.123"]
|
||||
}
|
||||
dest: /etc/docker/daemon.json
|
||||
|
||||
- name: Install dependencies
|
||||
become: true
|
||||
apt:
|
||||
name:
|
||||
- python3
|
||||
- python3-pip
|
||||
- python3-docker
|
||||
- docker.io
|
||||
- docker-buildx
|
||||
- docker-compose-v2
|
||||
- python3-jsondiff
|
||||
- apache2-utils
|
||||
update_cache: yes
|
||||
|
||||
- name: Enable docker
|
||||
become: true
|
||||
service:
|
||||
name: docker
|
||||
state: started
|
||||
enabled: true
|
||||
|
||||
- name: Init swarm
|
||||
when: inventory_hostname == groups.swarm_managers[0]
|
||||
become: true
|
||||
|
1
ansible/roles/docker/defaults/main.yml
Normal file
1
ansible/roles/docker/defaults/main.yml
Normal file
@ -0,0 +1 @@
|
||||
extra_docker_daemon_options: ""
|
51
ansible/roles/docker/tasks/main.yml
Normal file
51
ansible/roles/docker/tasks/main.yml
Normal file
@ -0,0 +1,51 @@
|
||||
---
|
||||
- name: Create /etc/docker
|
||||
become: true
|
||||
file:
|
||||
path: /etc/docker
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Set docker daemon settings
|
||||
become: true
|
||||
# Otherwise we risk conflicts on the host subnet
|
||||
copy:
|
||||
content: |
|
||||
{
|
||||
{{ extra_docker_daemon_options }},
|
||||
"default-address-pools": [
|
||||
{
|
||||
"base": "172.17.0.0/12",
|
||||
"size": 20
|
||||
},
|
||||
{
|
||||
"base": "172.168.0.0/16",
|
||||
"size": 24
|
||||
}
|
||||
],
|
||||
"dns": ["10.0.123.123"]
|
||||
}
|
||||
dest: /etc/docker/daemon.json
|
||||
register: docker_daemon_conf
|
||||
|
||||
- name: Install dependencies
|
||||
become: true
|
||||
apt:
|
||||
name:
|
||||
- python3
|
||||
- python3-pip
|
||||
- python3-docker
|
||||
- docker.io
|
||||
- docker-buildx
|
||||
- docker-compose-v2
|
||||
- python3-jsondiff
|
||||
- apache2-utils
|
||||
update_cache: yes
|
||||
|
||||
- name: Enable docker
|
||||
become: true
|
||||
service:
|
||||
name: docker
|
||||
state: "{{ 'restarted' if docker_daemon_conf.changed else 'started' }}"
|
||||
enabled: true
|
||||
|
36
ansible/roles/lvm/tasks/main.yml
Normal file
36
ansible/roles/lvm/tasks/main.yml
Normal file
@ -0,0 +1,36 @@
|
||||
---
|
||||
- name: Create a volume group
|
||||
become: true
|
||||
community.general.lvg:
|
||||
vg: "{{ vg_name }}"
|
||||
pvs: "{{ pv_disks }}"
|
||||
pvresize: yes
|
||||
|
||||
- name: Create Logical Volume for data persistence
|
||||
become: true
|
||||
community.general.lvol:
|
||||
vg: "{{ vg_name }}"
|
||||
lv: "{{ lv_name }}"
|
||||
size: "{{ lv_size }}"
|
||||
|
||||
- name: Create filesystem on LV
|
||||
become: true
|
||||
community.general.filesystem:
|
||||
fstype: "{{ fs_type }}"
|
||||
resizefs: true
|
||||
dev: /dev/mapper/{{ vg_name }}-{{ lv_name }}
|
||||
|
||||
- name: Get LV UUID
|
||||
become: true
|
||||
ansible.builtin.command: lsblk /dev/mapper/{{ vg_name }}-{{ lv_name }} -no UUID
|
||||
register: lv_uuid
|
||||
changed_when: false
|
||||
|
||||
- name: Mount created filesystem
|
||||
become: true
|
||||
ansible.posix.mount:
|
||||
path: "{{ mount_path }}"
|
||||
src: UUID={{ lv_uuid.stdout }}
|
||||
state: mounted
|
||||
fstype: "{{ fs_type }}"
|
||||
|
@ -8,24 +8,6 @@
|
||||
state: mounted
|
||||
fstype: nfs
|
||||
|
||||
- name: Set DNS servers
|
||||
become: true
|
||||
tags: [set_dns_servers]
|
||||
copy:
|
||||
content: |
|
||||
[Resolve]
|
||||
DNS=10.0.123.123
|
||||
# FallbackDNS=1.1.1.1
|
||||
dest: /etc/systemd/resolved.conf
|
||||
register: dns_servers_configuration
|
||||
|
||||
- name: Restart systemd-resolved
|
||||
tags: [set_dns_servers]
|
||||
service:
|
||||
name: systemd-resolved
|
||||
state: restarted
|
||||
when: dns_servers_configuration.changed
|
||||
retries: 2
|
||||
|
||||
- import_tasks: traefik.yml
|
||||
- import_tasks: portainer.yml
|
||||
|
@ -3,15 +3,6 @@ networks:
|
||||
traefik:
|
||||
external: true
|
||||
|
||||
volumes:
|
||||
portainer_data:
|
||||
driver: local
|
||||
driver_opts:
|
||||
o: bind
|
||||
type: none
|
||||
device: {{nfs_mount_path}}/portainer/data
|
||||
name: portainer_data
|
||||
|
||||
services:
|
||||
agent:
|
||||
image: portainer/agent:latest
|
||||
@ -34,7 +25,7 @@ services:
|
||||
- "9000:9000"
|
||||
- "8000:8000"
|
||||
volumes:
|
||||
- portainer_data:/data
|
||||
- {{nfs_mount_path}}/portainer/data:/data
|
||||
networks:
|
||||
- portainer
|
||||
- traefik
|
||||
|
@ -2,6 +2,9 @@ api:
|
||||
dashboard: true
|
||||
insecure: true
|
||||
|
||||
# accessLog:
|
||||
# filePath: /var/log/traefik/access.log
|
||||
|
||||
providers:
|
||||
swarm:
|
||||
exposedByDefault: false
|
||||
|
@ -4,15 +4,6 @@ networks:
|
||||
attachable: true
|
||||
name: traefik
|
||||
|
||||
volumes:
|
||||
traefik:
|
||||
driver: local
|
||||
driver_opts:
|
||||
o: bind
|
||||
type: none
|
||||
device: {{nfs_mount_path}}/traefik
|
||||
name: traefik
|
||||
|
||||
secrets:
|
||||
cf_dns_api_token:
|
||||
file: "{{nfs_mount_path}}/traefik/secrets/cf-dns-api-token.secret"
|
||||
@ -34,7 +25,7 @@ services:
|
||||
- "CF_DNS_API_TOKEN_FILE=/run/secrets/cf_dns_api_token"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- traefik:/data
|
||||
- {{nfs_mount_path}}/traefik:/data
|
||||
networks:
|
||||
- traefik
|
||||
deploy:
|
||||
|
@ -3,6 +3,8 @@
|
||||
hosts: swarm
|
||||
tags: [swarm-init]
|
||||
roles:
|
||||
- dns-client
|
||||
- docker
|
||||
- docker-swarm
|
||||
- swarm-bootstrap
|
||||
|
||||
|
@ -1,16 +1,15 @@
|
||||
---
|
||||
version: "3.8"
|
||||
|
||||
networks:
|
||||
traefik:
|
||||
external: true
|
||||
media:
|
||||
|
||||
# Argh, mounting the configuration on the NFS drive is not a good idea!
|
||||
# The sqlite databases in these volumes can have pretty high random RW, so
|
||||
# we should keep these local. But fuck, managing them on a non-network drive
|
||||
# on Swarm is such a pain...
|
||||
# Maybe we can get these to connect to a different DB?
|
||||
volumes:
|
||||
jellyseerr_config:
|
||||
transmission_config:
|
||||
prowlarr_config:
|
||||
radarr_config:
|
||||
sonarr_config:
|
||||
|
||||
services:
|
||||
transmission-openvpn:
|
||||
@ -21,7 +20,7 @@ services:
|
||||
- traefik
|
||||
- media
|
||||
volumes:
|
||||
- ${TRANSMISSION_CONFIG_DIRECTORY:-/mnt/stingray/media/transmission-openvpn/config}:/config
|
||||
- transmission_config:/config
|
||||
- ${MEDIA_DIRECTORY:-/mnt/media}/torrents:${MEDIA_DIRECTORY:-/mnt/media}/torrents
|
||||
environment:
|
||||
- PUID=${PUID:-8796}
|
||||
@ -43,18 +42,14 @@ services:
|
||||
- TRANSMISSION_WEB_UI=flood-for-transmission
|
||||
- TZ=America/Vancouver
|
||||
- LOCAL_NETWORK=10.0.0.0/16
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.transmission_openvpn.rule=Host(`${TRANSMISSION_HOST:-tovpn.jumper.mnke.org}`)"
|
||||
- "traefik.http.routers.transmission_openvpn.entrypoints=websecure"
|
||||
- "traefik.http.routers.transmission_openvpn.tls=true"
|
||||
- "traefik.http.services.transmission_openvpn.loadbalancer.server.port=9091"
|
||||
- "traefik.docker.network=traefik"
|
||||
deploy:
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.transmission_openvpn.rule=Host(`${TRANSMISSION_HOST:-tovpn.stingray.mnke.org}`)"
|
||||
- "traefik.http.routers.transmission_openvpn.entrypoints=websecure"
|
||||
- "traefik.http.routers.transmission_openvpn.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.services.transmission_openvpn.loadbalancer.server.port=9091"
|
||||
- "traefik.swarm.network=traefik"
|
||||
mode: replicated
|
||||
replicas: 1
|
||||
placement:
|
||||
constraints: [node.role != manager]
|
||||
resources:
|
||||
limits:
|
||||
cpus: '0.50'
|
||||
@ -73,17 +68,15 @@ services:
|
||||
- media
|
||||
- traefik
|
||||
volumes:
|
||||
- ${PROWLARR_CONFIG_DIRECTORY:-/mnt/stingray/media/prowlarr/config}:/config
|
||||
- prowlarr_config:/config
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.prowlarr.rule=Host(`${PROWLARR_HOST:-prowlarr.jumper.mnke.org}`)"
|
||||
- "traefik.http.routers.prowlarr.entrypoints=websecure"
|
||||
- "traefik.http.routers.prowlarr.tls=true"
|
||||
- "traefik.http.services.prowlarr.loadbalancer.server.port=9696"
|
||||
- "traefik.docker.network=traefik"
|
||||
deploy:
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.prowlarr.rule=Host(`${PROWLARR_HOST:-prowlarr.stingray.mnke.org}`)"
|
||||
- "traefik.http.routers.prowlarr.entrypoints=websecure"
|
||||
- "traefik.http.routers.prowlarr.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.services.prowlarr.loadbalancer.server.port=9696"
|
||||
- "traefik.swarm.network=traefik"
|
||||
placement:
|
||||
constraints: [node.role != manager]
|
||||
resources:
|
||||
limits:
|
||||
cpus: '0.5'
|
||||
@ -102,20 +95,20 @@ services:
|
||||
- media
|
||||
- traefik
|
||||
volumes:
|
||||
- ${RADARR_CONFIG_DIRECTORY:-/mnt/stingray/media/radarr/config}:/config
|
||||
- radarr_config:/config
|
||||
- ${MEDIA_DIRECTORY:-/mnt/media}:${MEDIA_DIRECTORY:-/mnt/media}
|
||||
depends_on:
|
||||
transmission-openvpn:
|
||||
condition: service_healthy
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.radarr.rule=Host(`${RADARR_HOST:-radarr.jumper.mnke.org}`)"
|
||||
- "traefik.http.routers.radarr.entrypoints=websecure"
|
||||
- "traefik.http.routers.radarr.tls=true"
|
||||
- "traefik.http.services.radarr.loadbalancer.server.port=7878"
|
||||
- "traefik.docker.network=traefik"
|
||||
deploy:
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.radarr.rule=Host(`${RADARR_HOST:-radarr.stingray.mnke.org}`)"
|
||||
- "traefik.http.routers.radarr.entrypoints=websecure"
|
||||
- "traefik.http.routers.radarr.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.services.radarr.loadbalancer.server.port=7878"
|
||||
- "traefik.swarm.network=traefik"
|
||||
mode: replicated
|
||||
replicas: 1
|
||||
placement:
|
||||
constraints: [node.role != manager]
|
||||
resources:
|
||||
limits:
|
||||
cpus: '0.5'
|
||||
@ -134,20 +127,19 @@ services:
|
||||
- media
|
||||
- traefik
|
||||
volumes:
|
||||
- ${SONARR_CONFIG_DIRECTORY:-/mnt/stingray/media/sonarr/config}:/config
|
||||
- sonarr_config:/config
|
||||
- ${MEDIA_DIRECTORY:-/mnt/media}:${MEDIA_DIRECTORY:-/mnt/media}
|
||||
depends_on:
|
||||
transmission-openvpn:
|
||||
condition: service_healthy
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.sonarr.rule=Host(`${SONARR_HOST:-sonarr.jumper.mnke.org}`)"
|
||||
- "traefik.http.routers.sonarr.entrypoints=websecure"
|
||||
- "traefik.http.routers.sonarr.tls=true"
|
||||
- "traefik.http.services.sonarr.loadbalancer.server.port=8989"
|
||||
- "traefik.docker.network=traefik"
|
||||
deploy:
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.sonarr.rule=Host(`${SONARR_HOST:-sonarr.stingray.mnke.org}`)"
|
||||
- "traefik.http.routers.sonarr.entrypoints=websecure"
|
||||
- "traefik.http.routers.sonarr.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.services.sonarr.loadbalancer.server.port=8989"
|
||||
- "traefik.swarm.network=traefik"
|
||||
mode: replicated
|
||||
replicas: 1
|
||||
placement:
|
||||
constraints: [node.role != manager]
|
||||
resources:
|
||||
limits:
|
||||
cpus: '0.5'
|
||||
@ -168,10 +160,6 @@ services:
|
||||
# ports:
|
||||
# - "${PORT:-8191}:8191"
|
||||
deploy:
|
||||
mode: replicated
|
||||
replicas: 1
|
||||
placement:
|
||||
constraints: [node.role != manager]
|
||||
resources:
|
||||
limits:
|
||||
cpus: '0.25'
|
||||
@ -183,25 +171,26 @@ services:
|
||||
jellyseerr:
|
||||
image: fallenbagel/jellyseerr
|
||||
environment:
|
||||
- LOG_LEVEL=debug
|
||||
# - LOG_LEVEL=debug
|
||||
- TZ=America/Vancouver
|
||||
networks:
|
||||
- media
|
||||
- traefik
|
||||
volumes:
|
||||
- ${JELLYSEERR_CONFIG_DIRECTORY:-/mnt/stingray/media/jellyseerr/config}:/app/config
|
||||
- jellyseerr_config:/app/config
|
||||
depends_on:
|
||||
radarr:
|
||||
condition: service_started
|
||||
sonarr:
|
||||
condition: service_started
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.jellyseerr.rule=Host(`${JELLYSEERR_HOST:-seerr.jumper.mnke.org}`)"
|
||||
- "traefik.http.routers.jellyseerr.entrypoints=websecure"
|
||||
- "traefik.http.routers.jellyseerr.tls=true"
|
||||
- "traefik.http.services.jellyseerr.loadbalancer.server.port=5055"
|
||||
- "traefik.docker.network=traefik"
|
||||
deploy:
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.jellyseerr.rule=Host(`${JELLYSEERR_HOST:-seerr.stingray.mnke.org}`)"
|
||||
- "traefik.http.routers.jellyseerr.entrypoints=websecure"
|
||||
- "traefik.http.routers.jellyseerr.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.services.jellyseerr.loadbalancer.server.port=5055"
|
||||
- "traefik.swarm.network=traefik"
|
||||
mode: replicated
|
||||
replicas: 1
|
||||
placement:
|
||||
constraints: [node.role != manager]
|
||||
resources:
|
||||
limits:
|
||||
cpus: '0.5'
|
68
docker/compose/traefik/docker-compose.yml
Normal file
68
docker/compose/traefik/docker-compose.yml
Normal file
@ -0,0 +1,68 @@
|
||||
networks:
|
||||
traefik:
|
||||
attachable: true
|
||||
name: traefik
|
||||
|
||||
volumes:
|
||||
traefik:
|
||||
|
||||
services:
|
||||
traefik:
|
||||
image: traefik:v3.3
|
||||
command:
|
||||
# - "--log.level=DEBUG"
|
||||
- "--api.dashboard=true"
|
||||
- "--api.insecure=true"
|
||||
- "--providers.docker.exposedByDefault=false"
|
||||
- "--providers.docker.endpoint=unix:///var/run/docker.sock"
|
||||
# HTTP
|
||||
- "--entrypoints.web.address=:80"
|
||||
# Redirect to HTTPS
|
||||
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
|
||||
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
|
||||
- "--entrypoints.websecure.address=:443"
|
||||
# TLS
|
||||
- "--certificatesresolvers.letsencrypt.acme.dnschallenge=true"
|
||||
- "--certificatesresolvers.letsencrypt.acme.dnschallenge.provider=cloudflare"
|
||||
- "--certificatesresolvers.letsencrypt.acme.dnschallenge.resolvers[0]=1.1.1.1"
|
||||
- "--certificatesresolvers.letsencrypt.acme.dnschallenge.resolvers[1]=1.0.0.1"
|
||||
- "--certificatesresolvers.letsencrypt.acme.caserver=https://acme-v02.api.letsencrypt.org/directory"
|
||||
- "--certificatesresolvers.letsencrypt.acme.email=${CF_EMAIL}"
|
||||
- "--certificatesresolvers.letsencrypt.acme.storage=/data/acme.json"
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
- "8080:8080"
|
||||
environment:
|
||||
- "CF_EMAIL=${CF_EMAIL:-tonydu121@hotmail.com}"
|
||||
- "CF_DNS_API_TOKEN=${CF_DNS_API_TOKEN}"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- traefik:/data
|
||||
networks:
|
||||
- traefik
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.api.rule=Host(`traefik.jumper.mnke.org`)"
|
||||
- "traefik.http.routers.api.entrypoints=websecure"
|
||||
- "traefik.http.routers.api.service=api@internal"
|
||||
- "traefik.http.routers.api.middlewares=auth"
|
||||
- "traefik.http.routers.api.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.routers.api.tls.domains[0].main=mnke.org"
|
||||
- "traefik.http.routers.api.tls.domains[0].sans=*.mnke.org"
|
||||
- "traefik.http.routers.api.tls.domains[1].main=jumper.mnke.org"
|
||||
- "traefik.http.routers.api.tls.domains[1].sans=*.jumper.mnke.org"
|
||||
- "traefik.http.middlewares.auth.basicauth.users=${TRAEFIK_HTPASSWD}"
|
||||
- "traefik.http.services.dummy-svc.loadbalancer.server.port=9999"
|
||||
|
||||
whoami:
|
||||
image: "traefik/whoami"
|
||||
networks:
|
||||
- traefik
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.whoami.rule=Host(`whoami.jumper.mnke.org`)"
|
||||
- "traefik.http.routers.whoami.entrypoints=websecure"
|
||||
- "traefik.http.routers.whoami.tls=true"
|
||||
- "traefik.http.services.whoami.loadbalancer.server.port=80"
|
||||
- "traefik.docker.network=traefik"
|
@ -4,7 +4,7 @@ locals {
|
||||
}
|
||||
|
||||
module "dns_server" {
|
||||
source = "${path.module}/modules/dns-server"
|
||||
source = "./modules/dns-server"
|
||||
|
||||
vm_id = "200"
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
module "docker_swarm_stingray" {
|
||||
source = "${path.module}/modules/docker-swarm"
|
||||
source = "./modules/docker-swarm"
|
||||
|
||||
swarm_name = "stingray"
|
||||
vm_id_prefix = "8"
|
||||
subnet_cidr = "10.0.42.0/24"
|
||||
gateway = "10.0.0.1"
|
||||
gateway = var.gateway
|
||||
manager_count = 3
|
||||
worker_count = 3
|
||||
dns_server_ip = local.dns_server_ip
|
||||
|
@ -1,11 +1,11 @@
|
||||
module "k8s_dolo" {
|
||||
source = "${path.module}/modules/k8s"
|
||||
source = "./modules/k8s"
|
||||
started = true
|
||||
|
||||
cluster_name = "dolo"
|
||||
vm_id_prefix = "1"
|
||||
subnet_cidr = "10.0.185.0/24"
|
||||
gateway = "10.0.0.1"
|
||||
gateway = var.gateway
|
||||
control_plane_count = 3
|
||||
worker_count = 3
|
||||
storage_worker_count = 3
|
||||
@ -20,7 +20,7 @@ module "k8s_dolo" {
|
||||
}
|
||||
|
||||
module "k8s_folly" {
|
||||
source = "${path.module}/modules/k8s"
|
||||
source = "./modules/k8s"
|
||||
|
||||
started = false
|
||||
|
||||
|
115
tf/outpost.tf
Normal file
115
tf/outpost.tf
Normal file
@ -0,0 +1,115 @@
|
||||
resource "proxmox_virtual_environment_file" "jumper" {
|
||||
content_type = "snippets"
|
||||
datastore_id = var.proxmox_image_storage
|
||||
node_name = "pve"
|
||||
|
||||
source_raw {
|
||||
data = <<EOF
|
||||
${local.common_cloud_init}
|
||||
|
||||
hostname: jumper
|
||||
EOF
|
||||
file_name = "jumper.cloud-config.yaml"
|
||||
}
|
||||
}
|
||||
|
||||
resource "proxmox_virtual_environment_vm" "jumper_storage_dummy" {
|
||||
name = "jumper-dummy"
|
||||
description = "Managed by Terraform"
|
||||
tags = ["terraform", "disk-dummy"]
|
||||
|
||||
node_name = "pve"
|
||||
vm_id = 7101
|
||||
|
||||
started = false
|
||||
on_boot = false
|
||||
|
||||
disk {
|
||||
datastore_id = var.proxmox_vm_storage
|
||||
file_format = "qcow2"
|
||||
interface = "scsi0"
|
||||
size = 32
|
||||
}
|
||||
}
|
||||
|
||||
resource "proxmox_virtual_environment_vm" "jumper" {
|
||||
# Don't forget to change the cloud init file if this is changed
|
||||
name = "jumper"
|
||||
description = "Managed by Terraform"
|
||||
tags = ["terraform", "ubuntu", "outpost"]
|
||||
|
||||
node_name = "pve"
|
||||
vm_id = 7001
|
||||
|
||||
cpu {
|
||||
cores = 4
|
||||
type = "host"
|
||||
}
|
||||
|
||||
memory {
|
||||
dedicated = 4096
|
||||
floating = 4096
|
||||
}
|
||||
|
||||
agent {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
startup {
|
||||
order = "1"
|
||||
up_delay = "60"
|
||||
down_delay = "60"
|
||||
}
|
||||
|
||||
disk {
|
||||
datastore_id = var.proxmox_vm_storage
|
||||
file_id = proxmox_virtual_environment_file.ubuntu_cloud_image.id
|
||||
interface = "virtio0"
|
||||
iothread = true
|
||||
discard = "on"
|
||||
size = 32
|
||||
file_format = "qcow2"
|
||||
}
|
||||
|
||||
initialization {
|
||||
ip_config {
|
||||
ipv4 {
|
||||
address = "10.0.44.2/16"
|
||||
gateway = var.gateway
|
||||
}
|
||||
}
|
||||
datastore_id = var.proxmox_image_storage
|
||||
|
||||
user_data_file_id = proxmox_virtual_environment_file.jumper.id
|
||||
}
|
||||
|
||||
dynamic "disk" {
|
||||
for_each = { for idx, val in proxmox_virtual_environment_vm.jumper_storage_dummy.disk : idx => val }
|
||||
iterator = data_disk
|
||||
content {
|
||||
datastore_id = data_disk.value["datastore_id"]
|
||||
path_in_datastore = data_disk.value["path_in_datastore"]
|
||||
file_format = data_disk.value["file_format"]
|
||||
size = data_disk.value["size"]
|
||||
# assign from scsi1 and up
|
||||
interface = "scsi${data_disk.key + 1}"
|
||||
}
|
||||
}
|
||||
|
||||
network_device {
|
||||
bridge = "vmbr0"
|
||||
}
|
||||
|
||||
operating_system {
|
||||
type = "l26"
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
}
|
||||
}
|
||||
|
||||
resource "ansible_host" "jumper" {
|
||||
name = "jumper.local"
|
||||
groups = ["jumper", "portainer_agent"]
|
||||
}
|
||||
|
@ -8,6 +8,10 @@ terraform {
|
||||
source = "hashicorp/local"
|
||||
version = "2.5.2"
|
||||
}
|
||||
ansible = {
|
||||
source = "ansible/ansible"
|
||||
version = "1.3.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,10 @@ variable "proxmox_api_token" {
|
||||
description = "Proxmox API token bpg proxmox provider with ID and token"
|
||||
}
|
||||
|
||||
variable "gateway" {
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "s3_backend_endpoint" {
|
||||
type = string
|
||||
# example = "http://s3.local"
|
||||
|
@ -1,5 +1,6 @@
|
||||
proxmox_image_storage = "proxmox-local-directory"
|
||||
proxmox_vm_storage = "proxmox-local-directory"
|
||||
gateway = "10.0.0.1"
|
||||
|
||||
username = "tony"
|
||||
ssh_import_id = "gh:tonyd33"
|
||||
|
Loading…
x
Reference in New Issue
Block a user