Terraform Upgrade to 1.x (#3)
Co-authored-by: Hashfyre <joy.bhattacherjee@gmail.com>
Diff
.gitignore | 1 +
.terraform-version | 2 +-
HACKING.md | 18 ++++++++++++++++++
data.tf | 8 ++++++++
echoserver.tf | 5 +++--
elibsrv.tf | 16 +++++-----------
firefox-sync.tf | 24 ++++++++++--------------
jupyter.tf | 1 -
kaarana.tf | 21 +++++++++++----------
kayak.tf | 1 -
klaxon.tf | 22 ++++++++--------------
kube-test.tf | 1 -
main.tf | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
miniflux.tf | 17 +++++++----------
nextcloud.tf | 48 ++++++++++++++++--------------------------------
providers.tf | 42 +++++++++++++++++++++++++++---------------
pulse.tf | 1 -
rss-bridge.tf | 22 +++++++++-------------
secrets.tf | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
server.tf | 1 -
state.tf | 1 +
variables.tf | 14 ++++----------
wiki.tf | 42 +++++++++++++++++++-----------------------
znc.tf | 30 +++++++++++++++---------------
cloudflare/main.tf | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
cloudflare/providers.tf | 7 +++++++
cloudflare/variables.tf | 5 +++--
db/network.tf | 1 +
db/outputs.tf | 3 ++-
db/postgres.tf | 17 +++++++++--------
db/providers.tf | 19 +++++++++++++++++++
db/variables.tf | 6 ++++--
db/volumes.tf | 1 +
digitalocean/droplets.tf | 5 +++--
digitalocean/firewall.tf | 55 ++++++++++++++++++++++++++-----------------------------
digitalocean/networking.tf | 5 +++--
digitalocean/providers.tf | 19 +++++++++++++++++++
docker/data.tf | 1 +
docker/got.tf | 7 -------
docker/images.tf | 8 ++++----
docker/locals.tf | 13 +++++--------
docker/lychee.tf | 1 -
docker/main.tf | 1 -
docker/network.tf | 1 +
docker/outputs.tf | 7 ++++---
docker/providers.tf | 19 +++++++++++++++++++
docker/traefik.tf | 55 +++++++++++++++++++++++++++++++------------------------
docker/ubooquity.tf | 59 ++++++++++++++++++++++++++++++++++++-----------------------
docker/variables.tf | 14 +++++++-------
docker/volumes.tf | 1 -
gitea/data.tf | 21 +++++++++++----------
gitea/main.tf | 67 ++++++++++++++++++++++++++++++++++++-------------------------------
gitea/mysql.tf | 1 -
gitea/network.tf | 1 +
gitea/providers.tf | 19 +++++++++++++++++++
gitea/redis.tf | 9 +++++----
gitea/variables.tf | 34 ++++++++++++++++++++++++----------
gitea/volume.tf | 1 +
kaarana/database.tf | 8 +++-----
kaarana/images.tf | 7 ++++---
kaarana/traefik.tf | 20 ++++++++++----------
kaarana/vars.tf | 8 ++++++--
kaarana/wordpress.tf | 21 ++++-----------------
media/airsonic.tf | 15 ---------------
media/data.tf | 1 +
media/emby.tf | 45 +++++++++++++++++++++++++++++----------------
media/jackett.tf | 19 +++++++++++--------
media/lidarr.tf | 29 ++++++++++++++++++++---------
media/navidrome.tf | 13 +++++++------
media/network.tf | 1 +
media/outputs.tf | 5 +++--
media/providers.tf | 19 +++++++++++++++++++
media/radarr.tf | 8 +++++---
media/requestrr.tf | 10 ++++++----
media/sonarr.tf | 7 ++++---
media/transmission.tf | 40 +++++++++++++++++++++++++++-------------
media/variables.tf | 22 ++++++++++++++--------
monitoring/act.tf | 7 +++----
monitoring/cadvisor.tf | 14 ++++----------
monitoring/data.tf | 1 +
monitoring/grafana.tf | 20 +++++++-------------
monitoring/images.tf | 9 +++++----
monitoring/network.tf | 1 +
monitoring/nodeexporter.tf | 11 +++++++----
monitoring/prometheus.tf | 22 ++++++----------------
monitoring/providers.tf | 19 +++++++++++++++++++
monitoring/speedtest.tf | 13 +++----------
monitoring/variables.tf | 16 +++++++++-------
opml/main.tf | 18 ++++++++++--------
opml/network.tf | 1 +
opml/providers.tf | 19 +++++++++++++++++++
opml/redis.tf | 14 ++++++++------
opml/variables.tf | 17 ++++++++++++-----
radicale/config | 4 ++++
radicale/main.tf | 45 ++++++++++++---------------------------------
radicale/providers.tf | 19 +++++++++++++++++++
radicale/variables.tf | 3 ++-
timemachine/main.tf | 28 ++++++++++++++--------------
timemachine/providers.tf | 19 +++++++++++++++++++
timemachine/variables.tf | 18 +++++++++++++-----
docker/conf/traefik.toml | 27 ---------------------------
gitea/conf/conf.ini.tpl | 6 +++---
media/conf/transmission.json | 6 +++---
modules/container/image.tf | 9 +++++++++
modules/container/locals.tf | 45 ++++++++++++++++++++++++++++-----------------
modules/container/main.tf | 203 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
modules/container/providers.tf | 9 +++++++++
modules/container/vars.tf | 64 +++++++++++++++++++++++++++++++++++++++++-----------------------
modules/image/main.tf | 9 +++++----
modules/postgres/main.tf | 9 +++++----
modules/postgres/providers.tf | 19 +++++++++++++++++++
modules/postgres/vars.tf | 5 +++--
112 files changed, 1206 insertions(+), 988 deletions(-)
@@ -1,8 +1,9 @@
*.tfvars
.terraform.tfstate.lock.info
.terraform
*.tfstate
*.tfstate.backup
*.terraform.lock.hcl
*.out
*.backup
secrets
@@ -1,1 +1,1 @@
0.11.13
1.0.9
@@ -1,0 +1,18 @@
# Hacking on the thing
Generate certs as per:
https://gist.github.com/captn3m0/2c2e723b2dcd5cdaad733aad12be59a2
Copy ca.pem, server-cert.pem, server-key.pem to /etc/docker/certs.
Make sure server-key.pem is 0400 in permissions.
Run `systemctl edit docker`
````
/etc/systemd/system/docker.service.d/override.conf
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd --tlsverify --tlscacert=/etc/docker/certs/ca.pem --tlscert=/etc/docker/certs/server-cert.pem --tlskey=/etc/docker/certs/server-key.pem -H=0.0.0.0:2376 -H unix:///var/run/docker.sock
````
@@ -1,3 +1,11 @@
data "docker_network" "bridge" {
name = "bridge"
}
data "cloudflare_zones" "bb8" {
filter {
name = "bb8"
lookup_type = "exact"
match = "bb8.fun"
}
}
@@ -1,11 +1,12 @@
module "echo-server" {
source = "modules/container"
source = "./modules/container"
name = "echo-server"
image = "jmalloc/echo-server:latest"
web {
web = {
expose = "true"
port = 8080
host = "debug.${var.root-domain},debug.in.${var.root-domain}"
}
}
@@ -1,14 +1,14 @@
module "elibsrv" {
name = "elibsrv"
name = "./elibsrv"
source = "./modules/container"
image = "captn3m0/elibsrv"
resource {
resource = {
memory = 512
memory_swap = 512
}
web {
web = {
expose = true
host = "ebooks.${var.root-domain}"
auth = true
@@ -40,12 +40,6 @@
"elibsrv_thumbheight=320",
"elibsrv_title=Scarif Media Archives",
]
networks_advanced = [
{
name = "traefik"
},
{
name = "bridge"
},
]
networks = ["bridge"]
}
@@ -1,24 +1,26 @@
module "firefox-sync" {
name = "firefox-sync"
source = "./modules/container"
image = "mozilla/syncserver:latest"
web {
web = {
expose = true
port = "5000"
host = "firesync.${var.root-domain}"
}
resource {
resource = {
memory = "400"
memory_swap = "400"
}
volumes = [{
host_path = "/mnt/xwing/data/firefox-sync"
container_path = "/data"
}]
volumes = [
{
host_path = "/mnt/xwing/data/firefox-sync"
container_path = "/data"
},
]
env = [
"SYNCSERVER_PUBLIC_URL=https://firesync.${var.root-domain}",
@@ -29,12 +31,6 @@
"PORT=5000",
]
networks_advanced = [
{
name = "traefik"
},
{
name = "bridge"
},
]
networks = ["bridge"]
}
@@ -10,4 +10,3 @@
@@ -1,16 +1,16 @@
module "kaarana" {
source = "./kaarana"
root_db_password = "${data.pass_password.kaarana-root-db-password.password}"
db_password = "${data.pass_password.kaarana-db-password.password}"
providers = {
docker = "docker.sydney"
}
}
data "pass_password" "kaarana-root-db-password" {
path = "KAARANA_DB_ROOT_PASSWORD"
}
@@ -18,3 +18,4 @@
data "pass_password" "kaarana-db-password" {
path = "KAARANA_DB_PASSWORD"
}
@@ -39,4 +39,3 @@
@@ -1,20 +1,20 @@
module "klaxon-db" {
source = "modules/postgres"
source = "./modules/postgres"
name = "klaxon"
password = "${data.pass_password.klaxon-db-password.password}"
password = data.pass_password.klaxon-db-password.password
}
module "klaxon" {
name = "klaxon"
source = "modules/container"
source = "./modules/container"
web {
web = {
expose = true
port = "3000"
host = "klaxon.${var.root-domain}"
}
resource {
resource = {
memory = 1024
memory_swap = 1024
}
@@ -29,18 +29,12 @@
"KLAXON_FORCE_SSL=false",
"KLAXON_COMPILE_ASSETS=true",
"ADMIN_EMAILS=klaxon@captnemo.in",
"MAILER_FROM_ADDRESS=klaxon@sendgrid.captnemo.in"
"MAILER_FROM_ADDRESS=klaxon@sendgrid.captnemo.in",
]
restart = "always"
image = "themarshallproject/klaxon"
networks_advanced = [
{
name = "traefik"
}, {
name = "postgres"
}, {
name = "external"
}]
networks = ["postgres", "external"]
}
@@ -17,4 +17,3 @@
@@ -1,96 +1,97 @@
module "cloudflare" {
source = "cloudflare"
domain = "bb8.fun"
ips = "${var.ips}"
source = "./cloudflare"
domain = "bb8.fun"
zone_id = lookup(data.cloudflare_zones.bb8.zones[0], "id")
ips = var.ips
droplet_ip = "${module.digitalocean.droplet_ipv4}"
droplet_ip = module.digitalocean.droplet_ipv4
}
module "docker" {
source = "docker"
web_username = "${data.pass_password.web_username.password}"
web_password = "${data.pass_password.web_password.password}"
cloudflare_key = "${data.pass_password.cloudflare_key.password}"
source = "./docker"
web_username = data.pass_password.web_username.password
web_password = data.pass_password.web_password.password
cloudflare_key = data.pass_password.cloudflare_key.password
cloudflare_email = "bb8@captnemo.in"
wiki_session_secret = "${data.pass_password.wiki_session_secret.password}"
ips = "${var.ips}"
wiki_session_secret = data.pass_password.wiki_session_secret.password
ips = var.ips
domain = "bb8.fun"
}
module "db" {
source = "db"
postgres-root-password = "${data.pass_password.postgres-root-password.password}"
ips = "${var.ips}"
source = "./db"
postgres-root-password = data.pass_password.postgres-root-password.password
ips = var.ips
}
module "timemachine" {
source = "timemachine"
ips = "${var.ips}"
source = "./timemachine"
ips = var.ips
username-1 = "vikalp"
username-2 = "rishav"
password-1 = "${data.pass_password.timemachine-password-1.password}"
password-2 = "${data.pass_password.timemachine-password-2.password}"
password-1 = data.pass_password.timemachine-password-1.password
password-2 = data.pass_password.timemachine-password-2.password
}
module "gitea" {
source = "gitea"
source = "./gitea"
domain = "git.captnemo.in"
traefik-labels = "${var.traefik-common-labels}"
ips = "${var.ips}"
secret-key = "${data.pass_password.gitea-secret-key.password}"
internal-token = "${data.pass_password.gitea-internal-token.password}"
smtp-password = "${data.pass_password.gitea-smtp-password.password}"
lfs-jwt-secret = "${data.pass_password.gitea-lfs-jwt-secret.password}"
oauth2-jwt-secret = "${data.pass_password.gitea-oauth2-jwt-secret.password}"
traefik-labels = var.traefik-common-labels
ips = var.ips
secret-key = data.pass_password.gitea-secret-key.password
internal-token = data.pass_password.gitea-internal-token.password
smtp-password = data.pass_password.gitea-smtp-password.password
lfs-jwt-secret = data.pass_password.gitea-lfs-jwt-secret.password
oauth2-jwt-secret = data.pass_password.gitea-oauth2-jwt-secret.password
mysql-password = ""
traefik-network-id = "${module.docker.traefik-network-id}"
traefik-network-id = module.docker.traefik-network-id
}
module "opml" {
source = "opml"
source = "./opml"
domain = "opml.bb8.fun"
client-id = "${data.pass_password.opml-github-client-id.password}"
client-secret = "${data.pass_password.opml-github-client-secret.password}"
traefik-network-id = "${module.docker.traefik-network-id}"
client-id = data.pass_password.opml-github-client-id.password
client-secret = data.pass_password.opml-github-client-secret.password
traefik-network-id = module.docker.traefik-network-id
}
module "radicale" {
source = "radicale"
source = "./radicale"
domain = "radicale.bb8.fun"
}
module "media" {
source = "media"
source = "./media"
domain = "bb8.fun"
traefik-labels = "${var.traefik-common-labels}"
ips = "${var.ips}"
traefik-network-id = "${module.docker.traefik-network-id}"
lastfm_api_key = "${data.pass_password.navidrome-lastfm-api-key.password}"
lastfm_secret = "${data.pass_password.navidrome-lastfm-secret.password}"
spotify_id = "${data.pass_password.navidrome-spotify-id.password}"
spotify_secret = "${data.pass_password.navidrome-spotify-secret.password}"
traefik-labels = var.traefik-common-labels
ips = var.ips
traefik-network-id = module.docker.traefik-network-id
lastfm_api_key = data.pass_password.navidrome-lastfm-api-key.password
lastfm_secret = data.pass_password.navidrome-lastfm-secret.password
spotify_id = data.pass_password.navidrome-spotify-id.password
spotify_secret = data.pass_password.navidrome-spotify-secret.password
}
module "monitoring" {
source = "monitoring"
gf-security-admin-password = "${data.pass_password.gf-security-admin-password.password}"
source = "./monitoring"
gf-security-admin-password = data.pass_password.gf-security-admin-password.password
domain = "bb8.fun"
transmission = "${module.media.names-transmission}"
traefik-labels = "${var.traefik-common-labels}"
ips = "${var.ips}"
links-traefik = "${module.docker.names-traefik}"
traefik-network-id = "${module.docker.traefik-network-id}"
transmission = module.media.names-transmission
traefik-labels = var.traefik-common-labels
ips = var.ips
links-traefik = module.docker.names-traefik
traefik-network-id = module.docker.traefik-network-id
}
module "digitalocean" {
source = "digitalocean"
source = "./digitalocean"
}
@@ -1,19 +1,15 @@
module "miniflux-container" {
name = "miniflux"
source = "modules/container"
image = "miniflux/miniflux:2.0.28"
source = "./modules/container"
image = "miniflux/miniflux:2.0.33"
web {
web = {
expose = true
port = 8080
host = "rss.captnemo.in"
}
networks = "${list(
data.docker_network.bridge.id,
module.docker.traefik-network-id,
module.db.postgres-network-id
)}"
networks = ["bridge", "postgres"]
env = [
"DATABASE_URL=postgres://miniflux:${data.pass_password.miniflux-db-password.password}@postgres/miniflux?sslmode=disable",
@@ -22,7 +18,8 @@
}
module "miniflux-db" {
source = "modules/postgres"
source = "./modules/postgres"
name = "miniflux"
password = "${data.pass_password.miniflux-db-password.password}"
password = data.pass_password.miniflux-db-password.password
}
@@ -1,18 +1,20 @@
module "nextcloud-db" {
source = "modules/postgres"
source = "./modules/postgres"
name = "nextcloud"
password = "${data.pass_password.nextcloud-db-password.password}"
password = data.pass_password.nextcloud-db-password.password
}
module "nextcloud-container" {
source = "modules/container"
source = "./modules/container"
name = "nextcloud"
image = "nextcloud:stable-apache"
volumes = [{
container_path = "/var/www/html"
host_path = "/mnt/xwing/data/nextcloud"
}]
volumes = [
{
container_path = "/var/www/html"
host_path = "/mnt/xwing/data/nextcloud"
},
]
env = [
"POSTGRES_DB=nextcloud",
@@ -24,28 +26,18 @@
"REDIS_HOST=nextcloud-redis",
]
resource {
resource = {
memory = 1024
memory_swap = 1024
}
web {
web = {
expose = true
port = 80
host = "c.${var.root-domain}"
}
networks_advanced = [
{
name = "traefik"
},
{
name = "nextcloud"
},
{
name = "postgres"
},
]
networks = ["nextcloud", "postgres"]
}
resource "docker_network" "nextcloud" {
@@ -55,23 +47,15 @@
module "nextcloud-redis" {
name = "nextcloud-redis"
source = "modules/container"
source = "./modules/container"
image = "redis:alpine"
keep_image = true
networks_advanced = [
{
name = "nextcloud"
},
]
web {
expose = "false"
}
networks = ["nextcloud"]
resource {
resource = {
memory = 256
memory_swap = 256
}
}
@@ -1,41 +1,53 @@
provider "docker" {
host = "tcp://docker.vpn.bb8.fun:2376"
cert_path = "./secrets/tatooine"
version = "~> 2.2.0"
}
provider "docker" {
host = "tcp://docker.dovpn.bb8.fun:2376"
cert_path = "./secrets/sydney"
version = "~> 2.2.0"
alias = "sydney"
}
provider "kubernetes" {
host = "https://k8s.bb8.fun:6443"
config_path = "${path.root}/k8s/auth/kubeconfig"
}
provider "cloudflare" {
email = "bb8@captnemo.in"
token = "${data.pass_password.cloudflare_key.password}"
email = "bb8@captnemo.in"
api_key = data.pass_password.cloudflare_key.password
}
provider "postgresql" {
host = "postgres.vpn.bb8.fun"
port = 5432
username = "postgres"
password = "${data.pass_password.postgres-root-password.password}"
password = data.pass_password.postgres-root-password.password
sslmode = "disable"
}
provider "digitalocean" {
token = "${data.pass_password.digitalocean-token.password}"
token = data.pass_password.digitalocean-token.password
}
provider "pass" {
store_dir = "/home/nemo/.password-store/Nebula/"
refresh_store = false
}
terraform {
required_providers {
pass = {
source = "camptocamp/pass"
}
digitalocean = {
source = "digitalocean/digitalocean"
}
postgresql = {
source = "cyrilgdn/postgresql"
}
cloudflare = {
source = "cloudflare/cloudflare"
}
docker = {
source = "kreuzwerker/docker"
}
}
}
@@ -21,4 +21,3 @@
@@ -1,30 +1,26 @@
module "rss-bridge" {
name = "rss-bridge"
source = "modules/container"
source = "./modules/container"
image = "captn3m0/rss-bridge:develop"
resource {
resource = {
memory = 256
memory_swap = 256
}
web {
web = {
expose = "true"
host = "rss-bridge.${var.root-domain}"
}
networks_advanced = [
{
name = "external"
},
networks = ["external"]
volumes = [
{
name = "traefik"
container_path = "/app/whitelist.txt"
host_path = "/mnt/xwing/config/rss-bridge/whitelist.txt"
},
]
volumes = [{
container_path = "/app/whitelist.txt"
host_path = "/mnt/xwing/config/rss-bridge/whitelist.txt"
}]
}
@@ -1,169 +1,174 @@
data "pass_password" "airsonic-smtp-password" {
path = "AIRSONIC_SMTP_PASSWORD"
path = "Nebula/AIRSONIC_SMTP_PASSWORD"
}
data "pass_password" "digitalocean-token" {
path = "DO_TOKEN"
path = "Nebula/DO_TOKEN"
}
data "pass_password" "gitea-internal-token" {
path = "GITEA_INTERNAL_TOKEN"
path = "Nebula/GITEA_INTERNAL_TOKEN"
}
data "pass_password" "gitea-lfs-jwt-secret" {
path = "GITEA_LFS_JWT_SECRET"
path = "Nebula/GITEA_LFS_JWT_SECRET"
}
data "pass_password" "gitea-secret-key" {
path = "GITEA_SECRET_KEY"
path = "Nebula/GITEA_SECRET_KEY"
}
data "pass_password" "gitea-oauth2-jwt-secret" {
path = "GITEA_OAUTH2_JWT_SECRET"
path = "Nebula/GITEA_OAUTH2_JWT_SECRET"
}
data "pass_password" "gf-security-admin-password" {
path = "GRAFANA_ADMIN_PASSWORD"
path = "Nebula/GRAFANA_ADMIN_PASSWORD"
}
data "pass_password" "gitea-smtp-password" {
path = "GITEA_SMTP_PASSWORD"
path = "Nebula/GITEA_SMTP_PASSWORD"
}
data "pass_password" "miniflux-db-password" {
path = "MINIFLUX_DB_PASSWORD"
path = "Nebula/MINIFLUX_DB_PASSWORD"
}
data "pass_password" "cloudflare_key" {
path = "CLOUDFLARE_KEY"
path = "Nebula/CLOUDFLARE_KEY"
}
data "pass_password" "monica-app-key" {
path = "monica-app-key"
path = "Nebula/monica-app-key"
}
data "pass_password" "monica-db-password" {
path = "monica-db-password"
path = "Nebula/monica-db-password"
}
data "pass_password" "monica-hash-salt" {
path = "monica-hash-salt"
path = "Nebula/monica-hash-salt"
}
data "pass_password" "monica-smtp-password" {
path = "monica-smtp-password"
path = "Nebula/monica-smtp-password"
}
data "pass_password" "nextcloud-db-password" {
path = "nextcloud-db-password"
path = "Nebula/nextcloud-db-password"
}
data "pass_password" "opml-github-client-id" {
path = "opml-github-client-id"
path = "Nebula/opml-github-client-id"
}
data "pass_password" "opml-github-client-secret" {
path = "opml-github-client-secret"
path = "Nebula/opml-github-client-secret"
}
data "pass_password" "outline_secret_key" {
path = "outline-secret-key"
path = "Nebula/outline-secret-key"
}
data "pass_password" "outline_slack_app_id" {
path = "outline-slack-app-id"
path = "Nebula/outline-slack-app-id"
}
data "pass_password" "outline_slack_key" {
path = "outline-slack-key"
path = "Nebula/outline-slack-key"
}
data "pass_password" "outline_slack_secret" {
path = "outline-slack-secret"
path = "Nebula/outline-slack-secret"
}
data "pass_password" "outline_slack_verification_token" {
path = "outline-slack-verification-token"
path = "Nebula/outline-slack-verification-token"
}
data "pass_password" "outline_smtp_password" {
path = "outline-smtp-password"
path = "Nebula/outline-smtp-password"
}
data "pass_password" "pihole_password" {
path = "pihole-password"
path = "Nebula/pihole_password"
}
data "pass_password" "syncserver_secret" {
path = "SYNCSERVER_SECRET"
path = "Nebula/SYNCSERVER_SECRET"
}
data "pass_password" "timemachine-password-1" {
path = "timemachine-password-1"
path = "Nebula/timemachine-password-1"
}
data "pass_password" "timemachine-password-2" {
path = "timemachine-password-2"
path = "Nebula/timemachine-password-2"
}
data "pass_password" "postgres-root-password" {
path = "postgres-root-password"
path = "Nebula/postgres-root-password"
}
data "pass_password" "znc_pass" {
path = "znc-pass"
path = "Nebula/znc-pass"
}
data "pass_password" "znc_user" {
path = "znc-user"
path = "Nebula/znc-user"
}
data "pass_password" "wiki_session_secret" {
path = "wiki_session_secret"
path = "Nebula/wiki_session_secret"
}
data "pass_password" "web_username" {
path = "web_username"
path = "Nebula/web_username"
}
data "pass_password" "web_password" {
path = "web_password"
path = "Nebula/web_password"
}
data "pass_password" "stringer-db-password" {
path = "stringer-db-password"
path = "Nebula/stringer-db-password"
}
data "pass_password" "stringer-secret-token" {
path = "stringer-secret-token"
path = "Nebula/stringer-secret-token"
}
data "pass_password" "wiki-db-password" {
path = "wiki-db-password"
path = "Nebula/wiki-db-password"
}
data "pass_password" "klaxon-db-password" {
path = "klaxon-db-password"
path = "Nebula/klaxon-db-password"
}
data "pass_password" "klaxon-secret-key" {
path = "klaxon-secret-key"
path = "Nebula/klaxon-secret-key"
}
data "pass_password" "klaxon-sendgrid-password" {
path = "klaxon-sendgrid-password"
path = "Nebula/klaxon-sendgrid-password"
}
data "pass_password" "navidrome-lastfm-api-key" {
path = "navidrome-lastfm-api-key"
path = "Nebula/navidrome-lastfm-api-key"
}
data "pass_password" "navidrome-lastfm-secret" {
path = "navidrome-lastfm-secret"
path = "Nebula/navidrome-lastfm-secret"
}
data "pass_password" "navidrome-spotify-id" {
path = "navidrome-spotify-id"
path = "Nebula/navidrome-spotify-id"
}
data "pass_password" "navidrome-spotify-secret" {
path = "navidrome-spotify-secret"
path = "Nebula/navidrome-spotify-secret"
}
@@ -1,1 +1,0 @@
@@ -6,3 +6,4 @@
profile = "nebula"
}
}
@@ -1,5 +1,5 @@
variable "ips" {
type = "map"
type = map(string)
default = {
eth0 = "192.168.1.111"
@@ -11,24 +11,17 @@
}
variable "traefik-common-labels" {
type = "map"
type = map(string)
default = {
"traefik.enable" = "true"
"traefik.frontend.headers.SSLTemporaryRedirect" = "true"
"traefik.frontend.headers.STSSeconds" = "2592000"
"traefik.frontend.headers.STSIncludeSubdomains" = "false"
"traefik.frontend.headers.customResponseHeaders" = "X-Powered-By:Allomancy||X-Server:Blackbox||X-Clacks-Overhead:GNU Terry Pratchett"
"traefik.frontend.headers.customFrameOptionsValue" = "ALLOW-FROM https://bb8.fun/"
"traefik.frontend.headers.contentTypeNosniff" = "true"
"traefik.frontend.headers.browserXSSFilter" = "true"
"traefik.frontend.headers.browserXSSFilter" = "true"
"traefik.docker.network" = "traefik"
}
@@ -38,3 +31,4 @@
description = "root domain for most applications"
default = "bb8.fun"
}
@@ -1,50 +1,44 @@
data "template_file" "wiki-config" {
template = "${file("docker/conf/wiki.tpl")}"
vars {
DB_PASSWORD = "${data.pass_password.wiki-db-password.password}"
template = file("docker/conf/wiki.tpl")
vars = {
DB_PASSWORD = data.pass_password.wiki-db-password.password
}
}
resource "local_file" "wiki-config" {
content = "${data.template_file.wiki-config.rendered}"
content = data.template_file.wiki-config.rendered
filename = "docker/conf/wiki.yml"
}
module "wiki-container" {
name = "wiki2"
source = "modules/container"
source = "./modules/container"
image = "requarks/wiki:2"
resource {
resource = {
memory = 1024
memory_swap = 1024
}
web {
web = {
expose = true
port = 3000
host = "wiki.bb8.fun"
}
networks_advanced = [
{
name = "traefik"
}, {
name = "postgres"
}, {
name = "external"
}]
networks = ["postgres", "external"]
uploads = [
{
content = "${file("docker/conf/wiki.yml")}"
content = file("docker/conf/wiki.yml")
file = "/wiki/config.yml"
}
},
]
volumes = [{
host_path = "/mnt/xwing/data/wiki/data"
container_path = "/data"
volumes = [
{
host_path = "/mnt/xwing/data/wiki/data"
container_path = "/data"
},
{
host_path = "/mnt/xwing/data/wiki/databackup"
@@ -53,11 +47,13 @@
{
host_path = "/mnt/xwing/data/wiki/repo"
container_path = "/old/repo"
}]
},
]
}
module "wiki-db" {
source = "modules/postgres"
source = "./modules/postgres"
name = "wikijs"
password = "${data.pass_password.wiki-db-password.password}"
password = data.pass_password.wiki-db-password.password
}
@@ -1,21 +1,21 @@
module "znc" {
source = "modules/container"
source = "./modules/container"
image = "znc:latest"
name = "znc"
web {
expose = "false"
host = ""
}
volumes = [
{
container_path = "/znc-data"
host_path = "/mnt/xwing/config/znc"
},
]
volumes = [{
container_path = "/znc-data"
host_path = "/mnt/xwing/config/znc"
}]
ports = [{
internal = 6697
external = 6697
ip = "${var.ips["tun0"]}"
}]
ports = [
{
internal = "6697"
external = "6697"
ip = var.ips["tun0"]
},
]
}
@@ -1,21 +1,21 @@
/**
* in.bb8.fun
* *.in.bb8.fun
*/
resource "cloudflare_record" "home" {
domain = "${var.domain}"
name = "in"
value = "${var.ips["eth0"]}"
type = "A"
zone_id = var.zone_id
name = "in"
value = var.ips["eth0"]
type = "A"
}
resource "cloudflare_record" "home-wildcard" {
domain = "${var.domain}"
name = "*.in"
value = "${cloudflare_record.home.hostname}"
type = "CNAME"
ttl = 3600
zone_id = var.zone_id
name = "*.in"
value = cloudflare_record.home.hostname
type = "CNAME"
ttl = 3600
}
/**
@@ -23,42 +23,42 @@
* *.bb8.fun -> bb8.fun
*/
resource "cloudflare_record" "internet" {
domain = "${var.domain}"
name = "@"
value = "${var.droplet_ip}"
type = "A"
zone_id = var.zone_id
name = "@"
value = var.droplet_ip
type = "A"
}
resource "cloudflare_record" "internet-wildcard" {
domain = "${var.domain}"
name = "*.${var.domain}"
value = "${cloudflare_record.internet.hostname}"
type = "CNAME"
ttl = 3600
zone_id = var.zone_id
name = var.domain
value = cloudflare_record.internet.hostname
type = "CNAME"
ttl = 3600
}
resource "cloudflare_record" "dns" {
domain = "${var.domain}"
name = "dns"
value = "${var.ips["static"]}"
type = "A"
zone_id = var.zone_id
name = "dns"
value = var.ips["static"]
type = "A"
}
resource "cloudflare_record" "doh" {
domain = "${var.domain}"
name = "doh"
value = "${var.ips["static"]}"
type = "A"
zone_id = var.zone_id
name = "doh"
value = var.ips["static"]
type = "A"
}
resource "cloudflare_record" "acme-no-cname-1" {
domain = "${var.domain}"
name = "_acme-challenge.${var.domain}"
type = "A"
value = "127.0.0.1"
ttl = "300"
zone_id = var.zone_id
name = "_acme-challenge.${var.domain}"
type = "A"
value = "127.0.0.1"
ttl = "300"
}
/**
@@ -66,18 +66,18 @@
* *.vpn.bb8.fun
*/
resource "cloudflare_record" "vpn" {
domain = "${var.domain}"
name = "vpn"
value = "${var.ips["tun0"]}"
type = "A"
zone_id = var.zone_id
name = "vpn"
value = var.ips["tun0"]
type = "A"
}
resource "cloudflare_record" "vpn_wildcard" {
domain = "${var.domain}"
name = "*.vpn.${var.domain}"
value = "${cloudflare_record.vpn.hostname}"
type = "CNAME"
ttl = 3600
zone_id = var.zone_id
name = "*.vpn.${var.domain}"
value = cloudflare_record.vpn.hostname
type = "CNAME"
ttl = 3600
}
/**
@@ -85,25 +85,25 @@
* *.vpn.bb8.fun
*/
resource "cloudflare_record" "dovpn" {
domain = "${var.domain}"
name = "dovpn"
value = "${var.ips["dovpn"]}"
type = "A"
zone_id = var.zone_id
name = "dovpn"
value = var.ips["dovpn"]
type = "A"
}
resource "cloudflare_record" "dovpn_wildcard" {
domain = "${var.domain}"
name = "*.dovpn.${var.domain}"
value = "${cloudflare_record.dovpn.hostname}"
type = "CNAME"
ttl = 3600
zone_id = var.zone_id
name = "*.dovpn.${var.domain}"
value = cloudflare_record.dovpn.hostname
type = "CNAME"
ttl = 3600
}
resource "cloudflare_record" "etcd" {
domain = "${var.domain}"
name = "etcd"
value = "${var.ips["dovpn"]}"
type = "A"
zone_id = var.zone_id
name = "etcd"
value = var.ips["dovpn"]
type = "A"
}
@@ -111,21 +111,21 @@
resource "cloudflare_record" "mailgun-spf" {
domain = "${var.domain}"
name = "l"
value = "v=spf1 include:mailgun.org ~all"
type = "TXT"
zone_id = var.zone_id
name = "l"
value = "v=spf1 include:mailgun.org ~all"
type = "TXT"
}
resource "cloudflare_record" "mailgun-dkim" {
domain = "${var.domain}"
name = "k1._domainkey.l"
value = "k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnbP+IQkuPkgmUhpqCKzIdDSZ0HazaMp+cdBH++LBed8oY8/jmV8BhxMp5JwyePzRTxneT8ASsRtcp7CQ3z4nMC7aFX0kH6Bnu2v+u2JWudxs8x0I02OrPbSaQ5QVQdbAaCUCEfCQ06LJsn8aqPNrRIOWEMnxln+ebFJ0wKGscFQIDAQAB"
type = "TXT"
zone_id = var.zone_id
name = "k1._domainkey.l"
value = "k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnbP+IQkuPkgmUhpqCKzIdDSZ0HazaMp+cdBH++LBed8oY8/jmV8BhxMp5JwyePzRTxneT8ASsRtcp7CQ3z4nMC7aFX0kH6Bnu2v+u2JWudxs8x0I02OrPbSaQ5QVQdbAaCUCEfCQ06LJsn8aqPNrRIOWEMnxln+ebFJ0wKGscFQIDAQAB"
type = "TXT"
}
resource "cloudflare_record" "mailgun-mxa" {
domain = "${var.domain}"
zone_id = var.zone_id
name = "l"
value = "mxa.mailgun.org"
type = "MX"
@@ -133,7 +133,7 @@
}
resource "cloudflare_record" "mailgun-mxb" {
domain = "${var.domain}"
zone_id = var.zone_id
name = "l"
value = "mxb.mailgun.org"
type = "MX"
@@ -141,9 +141,9 @@
}
resource "cloudflare_record" "k8s" {
domain = "${var.domain}"
name = "k8s"
value = "10.8.0.1"
type = "A"
ttl = 3600
zone_id = var.zone_id
name = "k8s"
value = "10.8.0.1"
type = "A"
ttl = 3600
}
@@ -1,0 +1,7 @@
terraform {
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
}
}
}
@@ -1,9 +1,10 @@
variable "domain" {
type = "string"
type = string
}
variable "ips" {
type = "map"
type = map
}
variable "droplet_ip" {}
variable "zone_id" {}
@@ -8,3 +8,4 @@
gateway = "172.20.0.9"
}
}
@@ -1,3 +1,4 @@
output "postgres-network-id" {
value = "${docker_network.postgres.name}"
value = docker_network.postgres.name
}
@@ -1,18 +1,18 @@
resource "docker_container" "postgres" {
name = "postgres"
image = "${docker_image.postgres.latest}"
image = docker_image.postgres.latest
volumes {
volume_name = "${docker_volume.postgres_volume.name}"
volume_name = docker_volume.postgres_volume.name
container_path = "/var/lib/postgresql/data"
host_path = "${docker_volume.postgres_volume.mountpoint}"
host_path = docker_volume.postgres_volume.mountpoint
}
ports {
internal = 5432
external = 5432
ip = "${var.ips["eth0"]}"
ip = var.ips["eth0"]
}
@@ -20,7 +20,7 @@
ports {
internal = 5432
external = 5432
ip = "${var.ips["tun0"]}"
ip = var.ips["tun0"]
}
memory = 256
@@ -32,12 +32,12 @@
"POSTGRES_PASSWORD=${var.postgres-root-password}",
]
networks = ["${docker_network.postgres.id}", "${data.docker_network.bridge.id}"]
networks = [docker_network.postgres.id, data.docker_network.bridge.id]
}
resource "docker_image" "postgres" {
name = "${data.docker_registry_image.postgres.name}"
pull_triggers = ["${data.docker_registry_image.postgres.sha256_digest}"]
name = data.docker_registry_image.postgres.name
pull_triggers = [data.docker_registry_image.postgres.sha256_digest]
}
data "docker_registry_image" "postgres" {
@@ -47,3 +47,4 @@
data "docker_network" "bridge" {
name = "bridge"
}
@@ -1,0 +1,19 @@
terraform {
required_providers {
pass = {
source = "camptocamp/pass"
}
digitalocean = {
source = "digitalocean/digitalocean"
}
postgresql = {
source = "cyrilgdn/postgresql"
}
cloudflare = {
source = "cloudflare/cloudflare"
}
docker = {
source = "kreuzwerker/docker"
}
}
}
@@ -1,10 +1,12 @@
variable "postgres-version" {
description = "postgres version to use for fetching the docker image"
default = "10-alpine"
}
variable "ips" {
type = "map"
type = map(string)
}
variable "postgres-root-password" {}
variable "postgres-root-password" {
}
@@ -1,3 +1,4 @@
resource "docker_volume" "postgres_volume" {
name = "postgres_volume"
}
@@ -1,5 +1,5 @@
resource "digitalocean_droplet" "sydney" {
image = ""
image = "??"
name = "sydney.captnemo.in"
region = "blr1"
size = "s-1vcpu-2gb"
@@ -18,5 +18,6 @@
}
output "droplet_ipv4" {
value = "${digitalocean_droplet.sydney.ipv4_address}"
value = digitalocean_droplet.sydney.ipv4_address
}
@@ -1,38 +1,35 @@
resource "digitalocean_firewall" "web" {
name = "web-inbound"
inbound_rule = [
{
protocol = "tcp"
port_range = "80"
source_addresses = ["0.0.0.0/0", "::/0"]
},
{
protocol = "tcp"
port_range = "443"
source_addresses = ["0.0.0.0/0", "::/0"]
},
]
inbound_rule {
protocol = "tcp"
port_range = "80"
source_addresses = ["0.0.0.0/0", "::/0"]
}
inbound_rule {
protocol = "tcp"
port_range = "443"
source_addresses = ["0.0.0.0/0", "::/0"]
}
}
resource "digitalocean_firewall" "ssh" {
name = "ssh-inbound"
inbound_rule = [
{
protocol = "tcp"
port_range = "22"
source_addresses = ["0.0.0.0/0", "::/0"]
},
{
protocol = "tcp"
port_range = "222"
source_addresses = ["0.0.0.0/0", "::/0"]
},
{
protocol = "tcp"
port_range = "24"
source_addresses = ["0.0.0.0/0", "::/0"]
},
]
inbound_rule {
protocol = "tcp"
port_range = "22"
source_addresses = ["0.0.0.0/0", "::/0"]
}
inbound_rule {
protocol = "tcp"
port_range = "222"
source_addresses = ["0.0.0.0/0", "::/0"]
}
inbound_rule {
protocol = "tcp"
port_range = "24"
source_addresses = ["0.0.0.0/0", "::/0"]
}
}
@@ -1,4 +1,5 @@
resource "digitalocean_floating_ip" "sydney" {
droplet_id = "${digitalocean_droplet.sydney.id}"
region = "${digitalocean_droplet.sydney.region}"
droplet_id = digitalocean_droplet.sydney.id
region = digitalocean_droplet.sydney.region
}
@@ -1,0 +1,19 @@
terraform {
required_providers {
pass = {
source = "camptocamp/pass"
}
digitalocean = {
source = "digitalocean/digitalocean"
}
postgresql = {
source = "cyrilgdn/postgresql"
}
cloudflare = {
source = "cloudflare/cloudflare"
}
docker = {
source = "kreuzwerker/docker"
}
}
}
@@ -9,3 +9,4 @@
data "docker_registry_image" "lychee" {
name = "linuxserver/lychee:latest"
}
@@ -6,22 +6,15 @@
@@ -1,11 +1,11 @@
resource "docker_image" "traefik17" {
name = "${data.docker_registry_image.traefik.name}"
pull_triggers = ["${data.docker_registry_image.traefik.sha256_digest}"]
name = data.docker_registry_image.traefik.name
pull_triggers = [data.docker_registry_image.traefik.sha256_digest]
}
resource "docker_image" "ubooquity" {
name = "${data.docker_registry_image.ubooquity.name}"
pull_triggers = ["${data.docker_registry_image.ubooquity.sha256_digest}"]
name = data.docker_registry_image.ubooquity.name
pull_triggers = [data.docker_registry_image.ubooquity.sha256_digest]
}
@@ -1,20 +1,17 @@
locals {
traefik_common_labels {
traefik_common_labels = {
"traefik.enable" = "true"
"traefik.frontend.headers.SSLTemporaryRedirect" = "true"
"traefik.frontend.headers.STSSeconds" = "2592000"
"traefik.frontend.headers.STSIncludeSubdomains" = "false"
"traefik.frontend.headers.customResponseHeaders" = "${var.xpoweredby}"
"traefik.frontend.headers.customResponseHeaders" = var.xpoweredby
"traefik.frontend.headers.customFrameOptionsValue" = "${var.xfo_allow}"
"traefik.frontend.headers.customFrameOptionsValue" = var.xfo_allow
"traefik.frontend.headers.contentTypeNosniff" = "true"
"traefik.frontend.headers.browserXSSFilter" = "true"
"traefik.docker.network" = "traefik"
"traefik.docker.network" = "traefik"
}
}
@@ -28,4 +28,3 @@
@@ -1,1 +1,0 @@
@@ -1,5 +1,6 @@
resource "docker_network" "traefik" {
name = "traefik"
driver = "bridge"
internal = true
}
@@ -1,15 +1,16 @@
output "names-traefik" {
value = "${docker_container.traefik.name}"
value = docker_container.traefik.name
}
output "traefik-network-id" {
value = "${docker_network.traefik.id}"
value = docker_network.traefik.id
}
output "auth-header" {
value = "${var.basic_auth}"
value = var.basic_auth
}
@@ -1,0 +1,19 @@
terraform {
required_providers {
pass = {
source = "camptocamp/pass"
}
digitalocean = {
source = "digitalocean/digitalocean"
}
postgresql = {
source = "cyrilgdn/postgresql"
}
cloudflare = {
source = "cloudflare/cloudflare"
}
docker = {
source = "kreuzwerker/docker"
}
}
}
@@ -1,70 +1,78 @@
resource "docker_container" "traefik" {
name = "traefik"
image = "${docker_image.traefik17.latest}"
image = docker_image.traefik17.latest
ports {
internal = 1111
external = 1111
ip = "${var.ips["eth0"]}"
ip = var.ips["eth0"]
}
ports {
internal = 1111
external = 1111
ip = "${var.ips["tun0"]}"
ip = var.ips["tun0"]
}
ports {
internal = 80
external = 80
ip = "${var.ips["eth0"]}"
ip = var.ips["eth0"]
}
ports {
internal = 443
external = 443
ip = "${var.ips["eth0"]}"
ip = var.ips["eth0"]
}
ports {
internal = 443
external = 443
ip = "${var.ips["tun0"]}"
ip = var.ips["tun0"]
}
ports {
internal = 80
external = 80
ip = "${var.ips["tun0"]}"
ip = var.ips["tun0"]
}
upload {
content = "${file("${path.module}/conf/traefik.toml")}"
content = file("${path.module}/conf/traefik.toml")
file = "/etc/traefik/traefik.toml"
}
upload {
content = "${file("/home/nemo/projects/personal/certs/git.captnemo.in/fullchain.pem")}"
file = "/etc/traefik/git.captnemo.in.crt"
content = file(
"/home/nemo/projects/personal/certs/git.captnemo.in/fullchain.pem",
)
file = "/etc/traefik/git.captnemo.in.crt"
}
upload {
content = "${file("/home/nemo/projects/personal/certs/git.captnemo.in/privkey.pem")}"
file = "/etc/traefik/git.captnemo.in.key"
content = file(
"/home/nemo/projects/personal/certs/git.captnemo.in/privkey.pem",
)
file = "/etc/traefik/git.captnemo.in.key"
}
upload {
content = "${file("/home/nemo/projects/personal/certs/rss.captnemo.in/fullchain.pem")}"
file = "/etc/traefik/rss.captnemo.in.crt"
content = file(
"/home/nemo/projects/personal/certs/rss.captnemo.in/fullchain.pem",
)
file = "/etc/traefik/rss.captnemo.in.crt"
}
upload {
content = "${file("/home/nemo/projects/personal/certs/rss.captnemo.in/privkey.pem")}"
file = "/etc/traefik/rss.captnemo.in.key"
content = file(
"/home/nemo/projects/personal/certs/rss.captnemo.in/privkey.pem",
)
file = "/etc/traefik/rss.captnemo.in.key"
}
volumes {
@@ -85,17 +93,16 @@
networks = [
"${docker_network.traefik.id}",
"${data.docker_network.bridge.id}",
]
networks_advanced {
name = "traefik"
}
networks_advanced {
name = "bridge"
}
env = [
"CLOUDFLARE_EMAIL=${var.cloudflare_email}",
"CLOUDFLARE_API_KEY=${var.cloudflare_key}",
]
}
data "docker_network" "bridge" {
name = "bridge"
}
@@ -1,6 +1,13 @@
locals {
l = merge(local.traefik_common_labels, {
"traefik.port" = 3000
"traefik.frontend.rule" = "Host:${var.domain}"
})
}
resource "docker_container" "ubooquity" {
name = "ubooquity"
image = "${docker_image.ubooquity.latest}"
image = docker_image.ubooquity.latest
restart = "unless-stopped"
destroy_grace_seconds = 30
@@ -25,32 +32,37 @@
host_path = "/mnt/xwing/media/EBooks/Comics"
container_path = "/comics"
}
labels {
"traefik.enable" = "true"
"traefik.admin.port" = 2203
"traefik.admin.frontend.rule" = "Host:library.${var.domain}"
"traefik.admin.frontend.auth.basic" = "${var.basic_auth}"
"traefik.read.port" = 2202
"traefik.read.frontend.rule" = "Host:read.${var.domain},comics.${var.domain},books.${var.domain}"
"traefik.read.frontend.headers.SSLTemporaryRedirect" = "true"
"traefik.read.frontend.headers.STSSeconds" = "2592000"
"traefik.read.frontend.headers.STSIncludeSubdomains" = "false"
"traefik.read.frontend.headers.contentTypeNosniff" = "true"
"traefik.read.frontend.headers.browserXSSFilter" = "true"
"traefik.read.frontend.headers.customResponseHeaders" = "${var.xpoweredby}"
"traefik.frontend.headers.customFrameOptionsValue" = "${var.xfo_allow}"
"traefik.docker.network" = "traefik"
label = "traefik.enable"
value = "true"
}
labels {
label = "traefik.admin.port"
value = 2203
}
labels {
label = "traefik.admin.frontend.rule"
value = "Host:library.${var.domain}"
}
labels {
label = "traefik.admin.frontend.auth.basic"
value = var.basic_auth
}
labels {
label = "traefik.read.port"
value = 2202
}
labels {
label = "traefik.read.frontend.rule"
value = "Host:read.${var.domain},comics.${var.domain},books.${var.domain}"
}
labels {
label = "traefik.docker.network"
value = "traefik"
}
upload {
content = "${file("${path.module}/conf/ubooquity.json")}"
content = file("${path.module}/conf/ubooquity.json")
file = "/config/preferences.json"
}
@@ -61,3 +73,4 @@
"MAXMEM=800",
]
}
@@ -1,18 +1,18 @@
variable "web_username" {
type = "string"
type = string
}
variable "web_password" {
type = "string"
type = string
}
variable "cloudflare_key" {
type = "string"
type = string
description = "cloudflare API Key"
}
variable "cloudflare_email" {
type = "string"
type = string
description = "cloudflare email address"
}
@@ -39,15 +39,15 @@
}
variable "wiki_session_secret" {
type = "string"
type = string
}
variable "domain" {
type = "string"
type = string
}
variable "ips" {
type = "map"
type = map(string)
}
@@ -1,1 +1,0 @@
@@ -1,6 +1,6 @@
data "docker_registry_image" "gitea" {
name = "gitea/gitea:1.14"
name = "gitea/gitea:1.15"
}
data "docker_registry_image" "redis" {
@@ -8,14 +8,15 @@
}
data "template_file" "gitea-config-file" {
template = "${file("${path.module}/conf/conf.ini.tpl")}"
vars {
secret_key = "${var.secret-key}"
internal_token = "${var.internal-token}"
smtp_password = "${var.smtp-password}"
lfs-jwt-secret = "${var.lfs-jwt-secret}"
mysql-password = "${var.mysql-password}"
oauth2-jwt-secret = "${var.oauth2-jwt-secret}"
template = file("${path.module}/conf/conf.ini.tpl")
vars = {
secret_key = var.secret-key
internal_token = var.internal-token
smtp_password = var.smtp-password
lfs-jwt-secret = var.lfs-jwt-secret
mysql-password = var.mysql-password
oauth2-jwt-secret = var.oauth2-jwt-secret
}
}
@@ -1,71 +1,74 @@
locals {
l = merge(var.traefik-labels, {
"traefik.port" = 3000
"traefik.frontend.rule" = "Host:${var.domain}"
})
}
resource "docker_container" "gitea" {
name = "gitea"
image = "${docker_image.gitea.latest}"
image = docker_image.gitea.latest
labels = "${merge(
var.traefik-labels, map(
"traefik.port", 3000,
"traefik.frontend.rule", "Host:${var.domain}"
))}"
dynamic "labels" {
for_each = local.l
content {
label = labels.key
value = labels.value
}
}
volumes {
volume_name = "${docker_volume.gitea_volume.name}"
volume_name = docker_volume.gitea_volume.name
container_path = "/data"
host_path = "${docker_volume.gitea_volume.mountpoint}"
host_path = docker_volume.gitea_volume.mountpoint
}
upload {
content = "${file("${path.module}/conf/public/img/gitea-lg.png")}"
file = "/data/gitea/public/img/gitea-lg.png"
content_base64 = filebase64("${path.module}/conf/public/img/gitea-lg.png")
file = "/data/gitea/public/img/gitea-lg.png"
}
upload {
content = "${file("${path.module}/conf/public/img/gitea-sm.png")}"
file = "/data/gitea/public/img/gitea-sm.png"
content_base64 = filebase64("${path.module}/conf/public/img/gitea-sm.png")
file = "/data/gitea/public/img/gitea-sm.png"
}
upload {
content = "${file("${path.module}/conf/public/img/gitea-sm.png")}"
file = "/data/gitea/public/img/favicon.png"
executable = false
content_base64 = filebase64("${path.module}/conf/public/img/gitea-sm.png")
file = "/data/gitea/public/img/favicon.png"
executable = false
}
upload {
content = "${file("${path.module}/../docker/conf/humans.txt")}"
content = file("${path.module}/../docker/conf/humans.txt")
file = "/data/gitea/public/humans.txt"
}
upload {
content = "${file("${path.module}/conf/public/robots.txt")}"
content = file("${path.module}/conf/public/robots.txt")
file = "/data/gitea/public/robots.txt"
}
upload {
content = "${file("${path.module}/conf/extra_links.tmpl")}"
content = file("${path.module}/conf/extra_links.tmpl")
file = "/data/gitea/templates/custom/extra_links.tmpl"
}
upload {
content = "${data.template_file.gitea-config-file.rendered}"
content = data.template_file.gitea-config-file.rendered
file = "/data/gitea/conf/app.ini"
}
memory = 800
restart = "always"
destroy_grace_seconds = 10
must_run = true
networks = ["${docker_network.gitea.id}", "${var.traefik-network-id}"]
networks = ["gitea", "traefik"]
}
resource "docker_image" "gitea" {
name = "${data.docker_registry_image.gitea.name}"
pull_triggers = ["${data.docker_registry_image.gitea.sha256_digest}"]
name = data.docker_registry_image.gitea.name
pull_triggers = [data.docker_registry_image.gitea.sha256_digest]
}
@@ -1,1 +1,0 @@
@@ -1,4 +1,5 @@
resource "docker_network" "gitea" {
name = "gitea"
driver = "bridge"
}
@@ -1,0 +1,19 @@
terraform {
required_providers {
pass = {
source = "camptocamp/pass"
}
digitalocean = {
source = "digitalocean/digitalocean"
}
postgresql = {
source = "cyrilgdn/postgresql"
}
cloudflare = {
source = "cloudflare/cloudflare"
}
docker = {
source = "kreuzwerker/docker"
}
}
}
@@ -1,6 +1,6 @@
resource "docker_container" "redis" {
name = "gitea-redis"
image = "${docker_image.redis.latest}"
image = docker_image.redis.latest
volumes {
host_path = "/mnt/xwing/cache/gitea"
@@ -12,11 +12,12 @@
destroy_grace_seconds = 10
must_run = true
networks = ["${docker_network.gitea.id}"]
networks = [docker_network.gitea.id]
}
resource "docker_image" "redis" {
name = "${data.docker_registry_image.redis.name}"
pull_triggers = ["${data.docker_registry_image.redis.sha256_digest}"]
name = data.docker_registry_image.redis.name
pull_triggers = [data.docker_registry_image.redis.sha256_digest]
keep_locally = true
}
@@ -1,18 +1,32 @@
variable "traefik-labels" {
type = "map"
type = map(string)
}
variable "domain" {}
variable "domain" {
}
variable "ips" {
type = "map"
type = map(string)
}
variable "secret-key" {
}
variable "internal-token" {
}
variable "smtp-password" {
}
variable "secret-key" {}
variable "internal-token" {}
variable "smtp-password" {}
variable "lfs-jwt-secret" {}
variable "oauth2-jwt-secret" {}
variable "mysql-password" {}
variable "lfs-jwt-secret" {
}
variable "oauth2-jwt-secret" {
}
variable "mysql-password" {
}
variable "traefik-network-id" {
}
variable "traefik-network-id" {}
@@ -1,3 +1,4 @@
resource "docker_volume" "gitea_volume" {
name = "gitea_volume"
}
@@ -18,7 +18,7 @@
resource "docker_container" "mysql" {
image = "${docker_image.db.latest}"
image = docker_image.db.latest
name = "kaarana-mariadb"
restart = "always"
must_run = true
@@ -35,8 +35,6 @@
container_path = "/var/lib/mysql"
}
networks_advanced {
name = "kaarana-db"
aliases = ["${local.db_hostname}"]
}
networks = ["kaarana-db"]
}
@@ -1,10 +1,10 @@
data "docker_registry_image" "wp" {
name = "wordpress:latest"
}
resource "docker_image" "wp" {
name = "wordpress"
pull_triggers = ["${data.docker_registry_image.wp.sha256_digest}"]
pull_triggers = [data.docker_registry_image.wp.sha256_digest]
}
data "docker_registry_image" "db" {
@@ -13,7 +13,7 @@
resource "docker_image" "db" {
name = "mariadb"
pull_triggers = ["${data.docker_registry_image.db.sha256_digest}"]
pull_triggers = [data.docker_registry_image.db.sha256_digest]
}
data "docker_registry_image" "traefik" {
@@ -22,5 +22,6 @@
resource "docker_image" "traefik" {
name = "traefik"
pull_triggers = ["${data.docker_registry_image.db.sha256_digest}"]
pull_triggers = [data.docker_registry_image.db.sha256_digest]
}
@@ -12,7 +12,7 @@
resource "docker_container" "traefik" {
name = "traefik"
image = "${docker_image.traefik.latest}"
image = docker_image.traefik.latest
@@ -21,7 +21,7 @@
]
upload {
content = "${file("${path.module}/traefik.toml")}"
content = file("${path.module}/traefik.toml")
file = "/etc/traefik/traefik.toml"
}
@@ -53,12 +53,12 @@
destroy_grace_seconds = 10
must_run = true
networks_advanced = [
{
name = "bridge"
},
{
name = "traefik"
},
]
networks_advanced {
name = "bridge"
}
networks_advanced {
name = "traefik"
}
}
@@ -1,8 +1,12 @@
variable "root_db_password" {}
variable "db_password" {}
variable "root_db_password" {
}
variable "db_password" {
}
locals {
username = "wordpress"
database = "wordpress"
db_hostname = "kaarana.db"
}
@@ -1,18 +1,16 @@
resource "docker_container" "wp" {
image = "${docker_image.wp.latest}"
image = docker_image.wp.latest
name = "kaarana-wordpress"
restart = "always"
must_run = true
labels {
labels = {
"traefik.enable" = "true"
"traefik.tcp.routers.kaarana.rule" = "HostSNI(`kaarana.captnemo.in`)"
"traefik.tcp.routers.kaarana.tls" = "true"
"traefik.tcp.services.wordpress.loadbalancer.server.port" = "80"
"traefik.tcp.routers.kaarana.tls.certResolver" = "default"
"traefik.tcp.routers.kaarana.tls.domains[0].main" = "kaarana.captnemo.in"
@@ -37,17 +35,6 @@
ip = "10.8.0.1"
}
networks_advanced = [
{
name = "kaarana-db"
},
{
name = "bridge"
},
{
name = "traefik"
},
]
networks = ["bridge", "kaarana-db"]
}
@@ -1,44 +1,35 @@
@@ -62,16 +53,10 @@
@@ -1,3 +1,4 @@
data "docker_network" "bridge" {
name = "bridge"
}
@@ -1,6 +1,15 @@
locals {
emby_labels = merge(var.traefik-labels, {
"traefik.frontend.rule" = "Host:emby.in.${var.domain},emby.${var.domain}"
"traefik.frontend.passHostHeader" = "true"
"traefik.port" = 8096
})
}
resource "docker_container" "emby" {
name = "emby"
image = "${docker_image.emby.latest}"
image = docker_image.emby.latest
volumes {
host_path = "/mnt/xwing/config/emby"
@@ -12,36 +21,40 @@
container_path = "/media"
}
labels = "${merge(
var.traefik-labels,
map(
"traefik.frontend.rule", "Host:emby.in.${var.domain},emby.${var.domain}",
"traefik.frontend.passHostHeader", "true",
"traefik.port", 8096,
))}"
dynamic "labels" {
for_each = local.emby_labels
content {
label = labels.key
value = labels.value
}
}
networks = ["${docker_network.media.id}", "${var.traefik-network-id}"]
networks = [docker_network.media.id, var.traefik-network-id]
memory = 2048
restart = "unless-stopped"
destroy_grace_seconds = 10
must_run = true
devices {
host_path = "/dev/dri"
container_path = "/dev/dri"
}
env = [
"APP_USER=lounge",
"APP_UID=1004",
"APP_GID=1003",
"APP_CONFIG=/mnt/xwing/config",
"TZ=Asia/Kolkata",
"UID=1004",
"GID=1003",
"GIDLIST=1003"
]
}
resource "docker_image" "emby" {
name = "${data.docker_registry_image.emby.name}"
pull_triggers = ["${data.docker_registry_image.emby.sha256_digest}"]
name = data.docker_registry_image.emby.name
pull_triggers = [data.docker_registry_image.emby.sha256_digest]
}
data "docker_registry_image" "emby" {
name = "emby/embyserver:latest"
}
@@ -1,22 +1,24 @@
module "jackett" {
name = "jackett"
source = "../modules/container"
image = "linuxserver/jackett:latest"
networks = "${list(data.docker_network.bridge.id)}"
web {
web = {
expose = true
port = 9117
host = "jackett.${var.domain}"
}
volumes = [{
host_path = "/mnt/xwing/config/jackett"
container_path = "/config"
}]
volumes = [
{
host_path = "/mnt/xwing/config/jackett"
container_path = "/config"
},
]
resource {
resource = {
memory = "256"
memory_swap = "512"
}
@@ -27,3 +29,4 @@
"TZ=Asia/Kolkata",
]
}
@@ -1,21 +1,31 @@
data "docker_registry_image" "lidarr" {
name = "linuxserver/lidarr:latest"
}
resource "docker_image" "lidarr" {
name = "${data.docker_registry_image.lidarr.name}"
pull_triggers = ["${data.docker_registry_image.lidarr.sha256_digest}"]
name = data.docker_registry_image.lidarr.name
pull_triggers = [data.docker_registry_image.lidarr.sha256_digest]
}
locals {
lidarr_labels = merge(var.traefik-labels, {
"traefik.port" = 8686
"traefik.frontend.rule" = "Host:lidarr.${var.domain}"
})
}
resource "docker_container" "lidarr" {
name = "lidarr"
image = "${docker_image.lidarr.latest}"
image = docker_image.lidarr.latest
dynamic "labels" {
for_each = local.lidarr_labels
content {
label = labels.key
value = labels.value
}
}
labels = "${merge(
var.traefik-labels, map(
"traefik.port", 8686,
"traefik.frontend.rule","Host:lidarr.${var.domain}"
))}"
memory = 512
restart = "unless-stopped"
@@ -43,5 +53,6 @@
"TZ=Asia/Kolkata",
]
networks = ["${docker_network.media.id}", "${var.traefik-network-id}"]
networks = [docker_network.media.id, var.traefik-network-id]
}
@@ -5,12 +5,12 @@
user = 1004
resource {
resource = {
memory = "1024"
memory_swap = "1024"
}
web {
web = {
port = 4533
host = "music.bb8.fun"
expose = true
@@ -22,14 +22,14 @@
"ND_SESSIONTIMEOUT=300h",
"ND_BASEURL=",
"ND_AUTOIMPORTPLAYLISTS=false",
"ND_LASTFM_APIKEY=${var.lastfm_api_key}",
"ND_LASTFM_SECRET=${var.lastfm_secret}",
"ND_SPOTIFY_ID=${var.spotify_id}",
"ND_SPOTIFY_SECRET=${var.spotify_secret}"
"ND_SPOTIFY_SECRET=${var.spotify_secret}",
]
networks = "${list(docker_network.media.id, data.docker_network.bridge.id)}"
volumes = [
{
@@ -40,6 +40,7 @@
host_path = "/mnt/xwing/media/Music"
container_path = "/music"
read_only = true
}
},
]
}
@@ -7,3 +7,4 @@
gateway = "172.18.0.1"
}
}
@@ -1,7 +1,8 @@
output "names-transmission" {
value = "${docker_container.transmission.name}"
value = docker_container.transmission.name
}
output "names-emby" {
value = "${docker_container.emby.name}"
value = docker_container.emby.name
}
@@ -1,0 +1,19 @@
terraform {
required_providers {
pass = {
source = "camptocamp/pass"
}
digitalocean = {
source = "digitalocean/digitalocean"
}
postgresql = {
source = "cyrilgdn/postgresql"
}
cloudflare = {
source = "cloudflare/cloudflare"
}
docker = {
source = "kreuzwerker/docker"
}
}
}
@@ -1,17 +1,18 @@
module "radarr" {
name = "radarr"
source = "../modules/container"
image = "linuxserver/radarr:latest"
networks = "${list(docker_network.media.id, data.docker_network.bridge.id)}"
web {
web = {
expose = true
port = 7878
host = "radarr.${var.domain}"
}
resource {
resource = {
memory = 512
memory_swap = 1024
}
@@ -37,3 +38,4 @@
"TZ=Asia/Kolkata",
]
}
@@ -1,15 +1,15 @@
module "requestrr" {
name = "requestrr"
source = "../modules/container"
image = "darkalfx/requestrr:latest"
web {
web = {
expose = true
port = 4545
host = "requestrr.${var.domain}"
}
resource {
resource = {
memory = 256
memory_swap = 256
}
@@ -18,8 +18,10 @@
{
host_path = "/mnt/xwing/config/requestrr"
container_path = "/root/config"
}
},
]
networks = "${list(docker_network.media.id, data.docker_network.bridge.id)}"
}
@@ -1,15 +1,15 @@
module "sonarr-container" {
name = "sonarr"
source = "../modules/container"
image = "linuxserver/sonarr:latest"
web {
web = {
expose = true
port = 8989
host = "sonarr.${var.domain}"
}
resource {
resource = {
memory = 512
memory_swap = 1024
}
@@ -35,5 +35,6 @@
"TZ=Asia/Kolkata",
]
networks = "${list(docker_network.media.id, data.docker_network.bridge.id)}"
networks = [docker_network.media.id, data.docker_network.bridge.id]
}
@@ -1,18 +1,26 @@
locals {
transmission_labels = merge(var.traefik-labels, {
"traefik.frontend.auth.basic" = var.basic_auth
"traefik.port" = 9091
})
}
resource "docker_container" "transmission" {
name = "transmission"
image = "${docker_image.transmission.latest}"
labels = "${merge(
var.traefik-labels,
map(
"traefik.frontend.auth.basic", "${var.basic_auth}",
"traefik.port", 9091,
))}"
image = docker_image.transmission.latest
dynamic "labels" {
for_each = local.transmission_labels
content {
label = labels.key
value = labels.value
}
}
ports {
internal = 51413
external = 51413
ip = "${var.ips["eth0"]}"
ip = var.ips["eth0"]
protocol = "udp"
}
@@ -27,12 +35,17 @@
}
volumes {
host_path = "/mnt/xwing/media/Music/Audiobooks"
container_path = "/audiobooks"
}
volumes {
host_path = "/mnt/xwing/data/watch/transmission"
container_path = "/watch"
}
upload {
content = "${file("${path.module}/conf/transmission.json")}"
content = file("${path.module}/conf/transmission.json")
file = "/config/settings.json"
}
@@ -42,7 +55,7 @@
"TZ=Asia/Kolkata",
]
networks = ["${docker_network.media.id}", "${var.traefik-network-id}"]
networks = [docker_network.media.id, var.traefik-network-id]
memory = 1024
restart = "unless-stopped"
@@ -51,10 +64,11 @@
}
resource "docker_image" "transmission" {
name = "${data.docker_registry_image.transmission.name}"
pull_triggers = ["${data.docker_registry_image.transmission.sha256_digest}"]
name = data.docker_registry_image.transmission.name
pull_triggers = [data.docker_registry_image.transmission.sha256_digest]
}
data "docker_registry_image" "transmission" {
name = "linuxserver/transmission:latest"
}
@@ -1,11 +1,11 @@
variable "domain" {
type = "string"
type = string
}
variable "traefik-labels" {
type = "map"
type = map(string)
}
@@ -14,23 +14,29 @@
}
variable "ips" {
type = "map"
type = map(string)
}
variable "traefik-network-id" {}
variable "traefik-network-id" {
}
variable "lastfm_api_key" {
description = "Navidrome Configuration for lastfm_api_key"
type = "string"
type = string
}
variable "lastfm_secret" {
description = "Navidrome Configuration for lastfm_secret"
type = "string"
type = string
}
variable "spotify_id" {
description = "Navidrome Configuration for spotify_id"
type = "string"
type = string
}
variable "spotify_secret" {
description = "Navidrome Configuration for spotify_secret"
type = "string"
type = string
}
@@ -1,10 +1,10 @@
data "docker_registry_image" "act-exporter" {
name = "captn3m0/prometheus-act-exporter:latest"
}
resource "docker_container" "act-exporter" {
name = "act-exporter"
image = "${docker_image.act-exporter.latest}"
image = docker_image.act-exporter.latest
entrypoint = ["/usr/local/bin/node", "server.js"]
@@ -14,11 +14,10 @@
}
networks_advanced {
name = "bridge"
}
networks = ["bridge"]
restart = "unless-stopped"
destroy_grace_seconds = 10
must_run = true
}
@@ -1,9 +1,9 @@
module "cadvisor" {
source = "../modules/container"
name = "cadvisor"
image = "google/cadvisor:latest"
resource {
resource = {
memory = 512
memory_swap = 512
}
@@ -39,18 +39,12 @@
},
]
networks_advanced = [
{
name = "traefik"
},
{
name = "monitoring"
},
]
networks = ["monitoring"]
web {
web = {
expose = true
port = 8080
auth = true
}
}
@@ -1,3 +1,4 @@
data "docker_registry_image" "prometheus" {
name = "prom/prometheus:latest"
}
@@ -7,32 +7,25 @@
user = "984:982"
web {
web = {
port = 3000
host = "grafana.${var.domain}"
expose = true
}
volumes = [{
host_path = "/mnt/xwing/data/grafana"
container_path = "/var/lib/grafana"
}]
networks_advanced = [
{
name = "traefik"
},
volumes = [
{
name = "monitoring"
host_path = "/mnt/xwing/data/grafana"
container_path = "/var/lib/grafana"
},
]
networks = ["monitoring"]
env = [
"GF_SERVER_ROOT_URL=https://grafana.${var.domain}",
"GF_AUTH_ANONYMOUS_ENABLED=true",
"GF_AUTH_ANONYMOUS_ORG_NAME=Tatooine",
"GF_SECURITY_ADMIN_PASSWORD=${var.gf-security-admin-password}",
]
@@ -40,3 +33,4 @@
destroy_grace_seconds = 10
must_run = true
}
@@ -1,10 +1,11 @@
resource "docker_image" "prometheus" {
name = "${data.docker_registry_image.prometheus.name}"
pull_triggers = ["${data.docker_registry_image.prometheus.sha256_digest}"]
name = data.docker_registry_image.prometheus.name
pull_triggers = [data.docker_registry_image.prometheus.sha256_digest]
}
resource "docker_image" "act-exporter" {
name = "${data.docker_registry_image.act-exporter.name}"
pull_triggers = ["${data.docker_registry_image.act-exporter.sha256_digest}"]
name = data.docker_registry_image.act-exporter.name
pull_triggers = [data.docker_registry_image.act-exporter.sha256_digest]
keep_locally = true
}
@@ -1,5 +1,6 @@
resource "docker_network" "monitoring" {
name = "monitoring"
driver = "bridge"
internal = true
}
@@ -27,14 +27,17 @@
command = [
"--path.procfs=/host/proc",
"--path.sysfs=/host/sys",
"--collector.filesystem.ignored-mount-points=\"^/(sys|proc|dev|host|etc)($$|/)\"",
"--collector.filesystem.ignored-mount-points=\"^/(sys|proc|dev|host|etc)($|/)\"",
]
networks = [
"${docker_network.monitoring.id}",
]
restart = "unless-stopped"
destroy_grace_seconds = 10
must_run = true
}
@@ -1,6 +1,6 @@
resource "docker_container" "prometheus" {
name = "prometheus"
image = "${docker_image.prometheus.latest}"
image = docker_image.prometheus.latest
user = "985:983"
@@ -8,13 +8,13 @@
ports {
internal = 9090
external = 8811
ip = "${var.ips["eth0"]}"
ip = var.ips["eth0"]
}
ports {
internal = 9090
external = 8811
ip = "${var.ips["tun0"]}"
ip = var.ips["tun0"]
}
command = ["--config.file=/etc/prometheus/prometheus.yml"]
@@ -25,23 +25,12 @@
}
upload {
content = "${file("${path.module}/config/prometheus.yml")}"
content = file("${path.module}/config/prometheus.yml")
file = "/etc/prometheus/prometheus.yml"
}
networks_advanced {
name = "monitoring"
}
networks_advanced {
name = "bridge"
}
networks = ["monitoring", "bridge"]
networks = [
"${data.docker_network.bridge.id}",
"${docker_network.monitoring.id}",
]
restart = "unless-stopped"
destroy_grace_seconds = 10
must_run = true
@@ -50,3 +39,4 @@
data "docker_network" "bridge" {
name = "bridge"
}
@@ -1,0 +1,19 @@
terraform {
required_providers {
pass = {
source = "camptocamp/pass"
}
digitalocean = {
source = "digitalocean/digitalocean"
}
postgresql = {
source = "cyrilgdn/postgresql"
}
cloudflare = {
source = "cloudflare/cloudflare"
}
docker = {
source = "kreuzwerker/docker"
}
}
}
@@ -7,17 +7,9 @@
image = "captn3m0/speedtest-exporter:alpine"
source = "../modules/container"
networks_advanced = [
{
name = "monitoring"
aliases = ["speedtest", "speedtest.docker"]
},
{
name = "bridge"
},
]
networks = ["monitoring"]
resource {
resource = {
memory = 256
memory_swap = 256
}
@@ -26,3 +18,4 @@
destroy_grace_seconds = 10
must_run = true
}
@@ -1,17 +1,17 @@
variable "gf-security-admin-password" {
type = "string"
type = string
}
variable "domain" {
type = "string"
type = string
}
variable "transmission" {
type = "string"
type = string
}
variable "links-traefik" {
type = "string"
type = string
}
variable "alert-slack-username" {
@@ -31,11 +31,13 @@
}
variable "traefik-labels" {
type = "map"
type = map(string)
}
variable "ips" {
type = "map"
type = map(string)
}
variable "traefik-network-id" {}
variable "traefik-network-id" {
}
@@ -1,12 +1,13 @@
module "opml" {
name = "opml"
source = "../modules/container"
image = "captn3m0/opml-gen:latest"
networks = ["${docker_network.opml.id}", "${var.traefik-network-id}"]
web {
name = "opml"
source = "../modules/container"
image = "captn3m0/opml-gen:latest"
web = {
expose = true
host = "${var.domain}"
host = var.domain
}
env = [
@@ -15,8 +16,9 @@
"REDIS_URL=redis://opml-redis:6379/1",
]
resource {
resource = {
memory = 256
memory_swap = 256
}
}
@@ -1,4 +1,5 @@
resource "docker_network" "opml" {
name = "opml"
driver = "bridge"
}
@@ -1,0 +1,19 @@
terraform {
required_providers {
pass = {
source = "camptocamp/pass"
}
digitalocean = {
source = "digitalocean/digitalocean"
}
postgresql = {
source = "cyrilgdn/postgresql"
}
cloudflare = {
source = "cloudflare/cloudflare"
}
docker = {
source = "kreuzwerker/docker"
}
}
}
@@ -1,17 +1,19 @@
module "redis" {
name = "opml-redis"
source = "../modules/container"
image = "redis:alpine"
networks = ["${docker_network.opml.id}"]
name = "opml-redis"
source = "../modules/container"
image = "redis:alpine"
keep_image = true
web {
web = {
expose = "false"
}
resource {
resource = {
memory = 256
memory_swap = 256
}
}
@@ -1,5 +1,12 @@
variable "domain" {}
variable "client-id" {}
variable "client-secret" {}
variable "traefik-network-id" {}
variable "domain" {
}
variable "client-id" {
}
variable "client-secret" {
}
variable "traefik-network-id" {
}
@@ -11,6 +11,10 @@
# Value: none | htpasswd | remote_user | http_x_remote_user
type = htpasswd
htpasswd_filename = /config/users
htpasswd_encryption = bcrypt
# Message displayed in the client when a password is needed
realm = Authentication required
[storage]
filesystem_folder = /data/collections
@@ -1,17 +1,20 @@
module "container" {
name = "radicale"
source = "../modules/container"
image = "tomsquest/docker-radicale:amd64"
resource {
resource = {
memory = 2000
memory_swap = 2000
}
web {
web = {
expose = true
port = 5232
host = "${var.domain}"
host = var.domain
}
volumes = [
@@ -27,39 +30,15 @@
uploads = [
{
content = <<EOT
[server]
hosts = 0.0.0.0:5232
max_connections = 10
[auth]
type = htpasswd
htpasswd_filename = /config/users
htpasswd_encryption = bcrypt
[storage]
filesystem_folder = /data/collections
[logging]
level=warning
[headers]
X-Powered-By: Allomancy
Server: Blackbox
EOT
content = file("${path.module}/config")
file = "/config/config"
},
{
content = file("${path.module}/logging.conf")
file = "/config/logging"
},
{
content = <<EOT
nemo:$2y$05$vC1WTAuKn2xuDYZ6I3ucxuPnCrtZrVKzdDHSYhqCegi97RM/pdzXW
axy:$2b$10$iqCLs3F1IRDBoSGxGlsOFO9C3peh8QH14hMnHN4o6oqu21PWL9vu2
EOT
content = file("${path.module}/users")
file = "/config/users"
},
]
@@ -1,0 +1,19 @@
terraform {
required_providers {
pass = {
source = "camptocamp/pass"
}
digitalocean = {
source = "digitalocean/digitalocean"
}
postgresql = {
source = "cyrilgdn/postgresql"
}
cloudflare = {
source = "cloudflare/cloudflare"
}
docker = {
source = "kreuzwerker/docker"
}
}
}
@@ -1,3 +1,4 @@
variable "domain" {
type = "string"
type = string
}
@@ -1,15 +1,15 @@
data "docker_registry_image" "timemachine" {
name = "odarriba/timemachine:latest"
}
resource "docker_image" "timemachine" {
name = "${data.docker_registry_image.timemachine.name}"
pull_triggers = ["${data.docker_registry_image.timemachine.sha256_digest}"]
name = data.docker_registry_image.timemachine.name
pull_triggers = [data.docker_registry_image.timemachine.sha256_digest]
}
resource "docker_container" "timemachine" {
name = "timemachine"
image = "${docker_image.timemachine.latest}"
image = docker_image.timemachine.latest
volumes {
host_path = "/mnt/xwing/data/timemachine"
@@ -19,17 +19,17 @@
ports {
internal = 548
external = 548
ip = "${var.ips["eth0"]}"
ip = var.ips["eth0"]
}
ports {
internal = 636
external = 636
ip = "${var.ips["eth0"]}"
ip = var.ips["eth0"]
}
upload {
content = "${data.template_file.timemachine-entrypoint.rendered}"
content = data.template_file.timemachine-entrypoint.rendered
file = "/entrypoint-custom.sh"
}
@@ -44,13 +44,13 @@
}
data "template_file" "timemachine-entrypoint" {
template = "${file("${path.module}/entrypoint.sh.tpl")}"
vars {
username-1 = "${var.username-1}"
password-1 = "${var.password-1}"
username-2 = "${var.username-2}"
password-2 = "${var.password-2}"
template = file("${path.module}/entrypoint.sh.tpl")
vars = {
username-1 = var.username-1
password-1 = var.password-1
username-2 = var.username-2
password-2 = var.password-2
}
}
@@ -1,0 +1,19 @@
terraform {
required_providers {
pass = {
source = "camptocamp/pass"
}
digitalocean = {
source = "digitalocean/digitalocean"
}
postgresql = {
source = "cyrilgdn/postgresql"
}
cloudflare = {
source = "cloudflare/cloudflare"
}
docker = {
source = "kreuzwerker/docker"
}
}
}
@@ -1,8 +1,16 @@
variable "ips" {
type = "map"
type = map(string)
}
variable "username-1" {}
variable "username-2" {}
variable "password-2" {}
variable "password-1" {}
variable "username-1" {
}
variable "username-2" {
}
variable "password-2" {
}
variable "password-1" {
}
@@ -38,33 +38,6 @@
[backends.elibsrv]
[backends.elibsrv.servers.default]
url = "http://elibsrv.captnemo.in:90"
[backends.scan]
[backends.scan.servers.default]
url = "http://scan.in.bb8.fun:90"
[frontends]
[frontends.scan]
backend = "scan"
[frontends.scan.headers]
SSLRedirect = true
SSLTemporaryRedirect = true
STSSeconds = 2592000
FrameDeny = true
ContentTypeNosniff = true
BrowserXssFilter = true
ReferrerPolicy = "no-referrer"
[frontends.scan.headers.customresponseheaders]
X-Powered-By = "Allomancy"
Server = "BlackBox"
X-Clacks-Overhead = "GNU Terry Pratchett"
[frontends.scan.routes.domain]
rule = "Host:scan.bb8.fun"
[web]
address = ":1111"
readOnly = true
@@ -137,7 +137,7 @@
RESET_PASSWD_CODE_LIVE_MINUTES = 30
REGISTER_EMAIL_CONFIRM = true
ENABLE_NOTIFY_MAIL = true
DISABLE_REGISTRATION = false
DISABLE_REGISTRATION = true
; ; Enable captcha validation for registration
ENABLE_CAPTCHA = true
REQUIRE_EXTERNAL_REGISTRATION_CAPTCHA = true
@@ -146,7 +146,7 @@
REQUIRE_SIGNIN_VIEW = false
; ; Default value for KeepEmailPrivate
; ; New user will get the value of this setting copied into their profile
DEFAULT_KEEP_EMAIL_PRIVATE = false
DEFAULT_KEEP_EMAIL_PRIVATE = true
; ; Default value for AllowCreateOrganization
; ; New user will have rights set to create organizations depending on this setting
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
@@ -249,7 +249,7 @@
[openid]
ENABLE_OPENID_SIGNIN = true
ENABLE_OPENID_SIGNUP = true
ENABLE_OPENID_SIGNUP = false
[metrics]
; Enables metrics endpoint. True or false; default is false.
@@ -11,7 +11,7 @@
"blocklist-enabled": true,
"blocklist-url": "http://john.bitsurge.net/public/biglist.p2p.gz",
"cache-size-mb": 16,
"dht-enabled": true,
"dht-enabled": false,
"download-dir": "/downloads",
"download-queue-enabled": true,
"download-queue-size": 5,
@@ -31,14 +31,14 @@
"peer-port-random-low": 49152,
"peer-port-random-on-start": false,
"peer-socket-tos": "default",
"pex-enabled": true,
"pex-enabled": false,
"port-forwarding-enabled": true,
"preallocation": 1,
"prefetch-enabled": true,
"queue-stalled-enabled": true,
"queue-stalled-minutes": 30,
"ratio-limit": 0.2,
"ratio-limit-enabled": true,
"ratio-limit-enabled": false,
"rename-partial-files": true,
"rpc-host-whitelist": "transmission.bb8.fun,transmission",
"rpc-host-whitelist-enabled": true,
@@ -1,0 +1,9 @@
data "docker_registry_image" "image" {
name = var.image
}
resource "docker_image" "image" {
name = var.image
pull_triggers = [data.docker_registry_image.image.sha256_digest]
keep_locally = var.keep_image
}
@@ -1,36 +1,47 @@
locals {
default_labels {
default_labels = {
"managed.by" = "nebula"
}
web {
"traefik.port" = "${lookup(var.web, "port", "80")}"
"traefik.frontend.rule" = "Host:${lookup(var.web, "host", "example.invalid")}"
"traefik.protocol" = "${lookup(var.web, "protocol", "http")}"
web = {
"traefik.port" = var.web.port != null ? var.web.port : 80
"traefik.frontend.rule" = var.web.host != null ? "Host:${var.web.host}" : "Host:example.invalid"
"traefik.protocol" = var.web.protocol != null ? var.web.protocol : "http"
}
resource {
memory = "${lookup(var.resource, "memory", 64)}"
memory_swap = "${lookup(var.resource, "memory_swap", 128)}"
}
traefik_common_labels {
traefik_common_labels = {
"traefik.enable" = "true"
"traefik.frontend.headers.SSLTemporaryRedirect" = "true"
"traefik.frontend.headers.STSSeconds" = "2592000"
"traefik.frontend.headers.STSIncludeSubdomains" = "false"
"traefik.frontend.headers.customResponseHeaders" = "${var.xpoweredby}"
"traefik.frontend.headers.customResponseHeaders" = var.xpoweredby
"traefik.frontend.headers.contentTypeNosniff" = "true"
"traefik.frontend.headers.browserXSSFilter" = "true"
"traefik.docker.network" = "traefik"
}
"traefik.docker.network" = "traefik"
traefik_auth_labels = {
"traefik.frontend.auth.basic" = var.auth_header
}
traefik_auth_labels {
"traefik.frontend.auth.basic" = "${var.auth_header}"
resource = {
memory = lookup(var.resource, "memory", 64)
memory_swap = lookup(var.resource, "memory_swap", 128)
}
labels = merge(
local.default_labels,
var.web.expose ? local.traefik_common_labels : null,
var.web.expose ? local.web : null,
var.web.auth != null ? (var.web.auth ? local.traefik_auth_labels : null) : null,
)
networks = concat(var.networks, var.web.expose ? ["traefik"] : [])
}
@@ -1,125 +1,82 @@
data "docker_registry_image" "image" {
name = "${var.image}"
}
resource "docker_image" "image" {
name = "${var.image}"
pull_triggers = ["${data.docker_registry_image.image.sha256_digest}"]
keep_locally = "${var.keep_image}"
}
data "docker_network" "traefik" {
name = "traefik"
}
resource "docker_container" "container" {
name = "${var.name}"
image = "${docker_image.image.latest}"
ports = "${var.ports}"
restart = "${var.restart}"
env = ["${var.env}"]
command = "${var.command}"
entrypoint = "${var.entrypoint}"
user = "${var.user}"
network_mode = "${var.network_mode}"
capabilities = ["${var.capabilities}"]
networks = ["${concat(var.networks,compact(split(",",lookup(var.web, "expose", "false") == "false" ? "" :"${data.docker_network.traefik.id}")))}"]
networks_advanced = ["${var.networks_advanced}"]
memory = "${local.resource["memory"]}"
memory_swap = "${local.resource["memory_swap"]}"
volumes = ["${var.volumes}"]
devices = ["${var.devices}"]
upload = ["${var.uploads}"]
labels = "${merge(local.default_labels,
zipmap(
concat(
keys(local.default_labels),
split("~",
lookup(var.web, "expose", "false") == "false" ?
"" :
join("~", keys(local.traefik_common_labels))
)
),
concat(
values(local.default_labels),
split("~",
lookup(var.web, "expose", "false") == "false" ?
"" :
join("~", values(local.traefik_common_labels))
)
)
),
zipmap(
concat(
keys(local.default_labels),
split("~",
lookup(var.web, "expose", "false") == "false" ?
"" :
join("~", keys(local.web))
)
),
concat(
values(local.default_labels),
split("~",
lookup(var.web, "expose", "false") == "false" ?
"" :
join("~", values(local.web))
)
)
),
zipmap(
concat(
keys(local.default_labels),
split("~",
lookup(var.web, "expose", "false") == "false" ?
"" :
join("~", keys(local.traefik_common_labels))
)
),
concat(
values(local.default_labels),
split("~",
lookup(var.web, "expose", "false") == "false" ?
"" :
join("~", values(local.traefik_common_labels))
)
)
),
zipmap(
concat(
keys(local.default_labels),
split("~",
lookup(var.web, "auth", "false") == "false" ?
"" :
join("~", keys(local.traefik_auth_labels))
)
),
concat(
values(local.default_labels),
split("~",
lookup(var.web, "auth", "false") == "false" ?
"" :
join("~", values(local.traefik_auth_labels))
)
)
)
)}"
destroy_grace_seconds = "${var.destroy_grace_seconds}"
must_run = "${var.must_run}"
name = var.name
image = docker_image.image.latest
dynamic "ports" {
for_each = var.ports
content {
external = ports.value.external
internal = ports.value.internal
ip = ports.value.ip
protocol = lookup(ports.value, "protocol", "tcp")
}
}
restart = var.restart
env = var.env
command = var.command
entrypoint = var.entrypoint
user = var.user
network_mode = var.network_mode
dynamic "capabilities" {
for_each = [var.capabilities]
content {
add = lookup(capabilities.value, "add", [])
drop = lookup(capabilities.value, "drop", [])
}
}
dynamic "networks_advanced" {
for_each = local.networks
content {
name = networks_advanced.value
}
}
memory = local.resource["memory"]
memory_swap = local.resource["memory_swap"]
dynamic "volumes" {
for_each = var.volumes
content {
container_path = lookup(volumes.value, "container_path", null)
from_container = lookup(volumes.value, "from_container", null)
host_path = lookup(volumes.value, "host_path", null)
read_only = lookup(volumes.value, "read_only", null)
volume_name = lookup(volumes.value, "volume_name", null)
}
}
dynamic "devices" {
for_each = var.devices
content {
host_path = devices.value["host_path"]
container_path = devices.value["container_path"]
permissions = devices.value["permissions"]
}
}
dynamic "upload" {
for_each = var.uploads
content {
file = lookup(upload.value, "file", null)
content = lookup(upload.value, "content", null)
content_base64 = lookup(upload.value, "content_base64", null)
executable = lookup(upload.value, "executable", null)
source = lookup(upload.value, "source", null)
source_hash = lookup(upload.value, "source_hash", null)
}
}
dynamic "labels" {
for_each = local.labels
content {
label = labels.key
value = labels.value
}
}
destroy_grace_seconds = var.destroy_grace_seconds
must_run = var.must_run
}
@@ -1,0 +1,9 @@
terraform {
experiments = [module_variable_optional_attrs]
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "2.15.0"
}
}
}
@@ -8,19 +8,13 @@
variable "ports" {
description = "list of port mappings"
type = "list"
type = list(map(string))
default = []
}
variable "networks_advanced" {
description = "list of networks_advanced"
type = "list"
default = []
}
variable "networks" {
description = "list of networks"
type = "list"
description = "list of names of networks to attach to"
type = list(string)
default = []
}
@@ -32,7 +26,7 @@
variable "must_run" {
description = "If true, then the Docker container will be kept running. "
default = "true"
type = "string"
type = string
}
variable "user" {
@@ -43,7 +37,7 @@
variable "destroy_grace_seconds" {
description = "Container will be destroyed after n seconds or on successful stop."
default = 10
type = "string"
type = string
}
variable "command" {
@@ -61,10 +55,9 @@
default = []
}
variable "labels" {
description = "labels"
default = {}
}
variable "xpoweredby" {
default = "X-Powered-By:Allomancy||X-Server:Blackbox"
@@ -72,10 +65,20 @@
variable "web" {
description = "Web Configuration"
type = object({
expose = bool
auth = optional(bool)
port = optional(number)
host = optional(string)
protocol = optional(string)
})
default = {
expose = "false"
auth = "false"
expose = false
auth = false
port = 80
host = ""
protocol = "http"
}
}
@@ -95,20 +98,23 @@
variable "volumes" {
description = "volumes"
type = "list"
default = []
default = {}
}
variable "capabilities" {
description = "capabilities"
type = "list"
default = []
default = {
add = []
drop = []
}
}
variable "devices" {
description = "devices"
type = "list"
default = []
description = "list of devices"
type = list(map(string))
default = []
}
variable "keep_image" {
@@ -117,5 +123,15 @@
}
variable "uploads" {
description = "Files to Upload"
type = list(object({
file = string
content = optional(string)
content_base64 = optional(string)
executable = optional(bool)
source = optional(string)
source_hash = optional(string)
}))
default = []
}
@@ -1,16 +1,17 @@
variable "image" {
description = "image to use"
}
data "docker_registry_image" "image" {
name = "${var.image}"
name = var.image
}
resource "docker_image" "image" {
name = "${data.docker_registry_image.image.name}"
pull_triggers = ["${data.docker_registry_image.image.sha256_digest}"]
name = data.docker_registry_image.image.name
pull_triggers = [data.docker_registry_image.image.sha256_digest]
}
output "image" {
value = "${docker_image.image.latest}"
value = docker_image.image.latest
}
@@ -1,10 +1,11 @@
resource "postgresql_database" "db" {
name = "${var.name}"
owner = "${var.name}"
name = var.name
owner = var.name
}
resource "postgresql_role" "role" {
name = "${var.name}"
name = var.name
login = true
password = "${var.password}"
password = var.password
}
@@ -1,0 +1,19 @@
terraform {
required_providers {
pass = {
source = "camptocamp/pass"
}
digitalocean = {
source = "digitalocean/digitalocean"
}
postgresql = {
source = "cyrilgdn/postgresql"
}
cloudflare = {
source = "cloudflare/cloudflare"
}
docker = {
source = "kreuzwerker/docker"
}
}
}
@@ -1,9 +1,10 @@
variable "name" {
description = "database/role name"
type = "string"
type = string
}
variable "password" {
description = "role password"
type = "string"
type = string
}