Initial commit

This commit is contained in:
Patrick de Ruiter 2024-05-25 05:32:38 +02:00
commit 89a3f6e47b
11 changed files with 432 additions and 0 deletions

34
.gitignore vendored Normal file
View File

@ -0,0 +1,34 @@
# Local .terraform directories
**/.terraform/*
# .tfstate files
*.tfstate
*.tfstate.*
# Crash log files
crash.log
crash.*.log
# Exclude all .tfvars files, which are likely to contain sensitive data, such as
# password, private keys, and other secrets. These should not be part of version
# control as they are data points which are potentially sensitive and subject
# to change depending on the environment.
*.tfvars
*.tfvars.json
# Ignore override files as they are usually used to override resources locally and so
# are not checked in
override.tf
override.tf.json
*_override.tf
*_override.tf.json
# Include override files you do wish to add to version control using negated pattern
# !example_override.tf
# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
# example: *tfplan*
# Ignore CLI configuration files
.terraformrc
terraform.rc

44
.terraform.lock.hcl generated Normal file
View File

@ -0,0 +1,44 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/abh80/docker" {
version = "1.0.1"
constraints = "1.0.1"
hashes = [
"h1:cmotTmVc4w+Q5+pqjxx/HqHoDmhWcqIzCGPmPmyYUgs=",
"zh:111e17287b583f0ea4f9348e43d6451bec62178d99399c1273ce9c6b0e73b20e",
"zh:35e09001d2dbdd27519bd9d0987f8350fde9ffb78cfac83ae01a6c2e5e5120f6",
"zh:418c0930c8a2719184686ae27091dcaac0b05c554062dad87691772e257afd19",
"zh:5ea943d639daf72f5fe9a26a5ae9541527ea093f96ef261a130eecf14313ef0a",
"zh:7bd5bfca33ef7449313645b52f044ee970b0b929fed5b8d5bea3f0c971d85002",
"zh:7ea67b58146270acaea2f3d61ba72c5d4c28083208ac3a77f5be81f7910e0ceb",
"zh:830b24cc5328931c2796128647bbfcc44e7238461399f78b7f8e6376c431477b",
"zh:c51bd68a6c56f734baea5352d98c41815ac98916ad5c7760938af0c9d930414a",
"zh:d4b92841056fbcfdafc8d42d186a7e2e7bb3e1e8e2248012f92653b232ad8156",
"zh:e542b3e076da9d4d8325ff5bbd7bf2d58ef0b95ee9607b23fc4b2e26890313b2",
"zh:e803b0ef43d44b9a510b360663df9f2bc7bbc4f3a3b9e61ab5a98832367f5e29",
"zh:eaf409305294569b696c33d3778b73c41f8fe4dfbb812a6b87ddce9154d64af0",
"zh:f2555a9a387064a54b28123026f8d938e55266e944fbd4c3ca1e805b5b3009f7",
"zh:f747ca9d07c45711c94ac30dac2bc71cfe53d4c53b9a3b5a813bcf8b0fb3e7f2",
]
}
provider "registry.terraform.io/hashicorp/vault" {
version = "3.25.0"
constraints = "3.25.0"
hashes = [
"h1:3GN5k6zxDAI5gfcKENb/jnJyFGWA/0JoumnD6eyVZjs=",
"zh:430308f5dbd322a2e5afafd2be810f44eb35e28afa0aa0ac30b270cd6f413da8",
"zh:6c36da504c4af84ea9fbaf1e6c2560f691dc3d2d7f0b382a937bfae78830fa17",
"zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
"zh:7bc39cb2a7d91631cb8be54b0b06de29fb47910923e54f779e74d8b218b1ab70",
"zh:7e4a5bebcfa19b9f1e3a6bbda5c6771b6dd28b3dfa19fdf3d4fced419cfa416f",
"zh:7ea473203b37d006a0d2b1cdc8bff55c96b3c5819dbb62862cdabff6f2f0e2f2",
"zh:9ad136feece62f0c545fefa4592b2cdaa896a39acb697fb129233dce880a69aa",
"zh:ad0c9980295c902804af23da0250830b912eb13089349bf5c7be0649fac2689c",
"zh:b305835cc13dcd9ec996d49d23163c6311f30786296f86ca5657b93aea4f3591",
"zh:d8fe6ab7da12efbb5b122ae9b6856375c5a3759add9df577a8fb448898ceffe3",
"zh:ef59ef2c06a55571e64fdd5888a074ed9556436738e9737e32bacab93ca133ff",
"zh:f59c2605d916e1806dc494241467dd430194f5e7bdbf331c5aca904873347ad8",
]
}

8
README.md Normal file
View File

@ -0,0 +1,8 @@
# Terraform Docker SearXNG Module
This Terraform module deploys a SearXNG private search engine instance using Docker.
## Usage
```hcl
```

16
backend.tf Normal file
View File

@ -0,0 +1,16 @@
terraform {
backend "s3" {
bucket = "terraformstate-vsphere"
endpoint = "https://wbyc-srv-minio01.bsdserver.lan:9000"
key = "home/docker/searxng/servers.tfstate"
access_key = "terraform"
secret_key = "Drj3nD!!"
region = "main"
skip_credentials_validation = true
skip_metadata_api_check = true
skip_region_validation = true
force_path_style = true
}
}

3
data.tf Normal file
View File

@ -0,0 +1,3 @@
#data "vault_generic_secret" "searxng" {
# path = "secret/searxng"
#}

6
files/limiter.toml Normal file
View File

@ -0,0 +1,6 @@
# This configuration file updates the default configuration file
# See https://github.com/searxng/searxng/blob/master/searx/botdetection/limiter.toml
[botdetection.ip_limit]
# activate link_token method in the ip_limit method
link_token = true

33
files/settings.yml Normal file
View File

@ -0,0 +1,33 @@
# see https://docs.searxng.org/admin/settings/settings.html#settings-use-default-settings
use_default_settings: true
server:
# base_url is defined in the SEARXNG_BASE_URL environment variable, see .env and docker-compose.yml
secret_key: "9fd0439f0fc5c38dc3d6c433d5ec98b98234aa93c30f4136a117574da7bdea13"
limiter: true # can be disabled for a private instance
image_proxy: true
ui:
static_use_hash: true
redis:
url: redis://redis:6379/0
proxies:
http: socks5h://searxng-tor:9050
https: socks5h://searxng-tor:9050
search:
engines:
duckduckgo_onion:
proxy: true
categories: general
base_url: "https://3g2upl4pq6kufc4m.onion"
name: DuckDuckGo (onion)
torch_onion:
name: Torch (onion)
base_url: "https://xmh57jrzrnw6insl.onion"
search_url: "https://xmh57jrzrnw6insl.onioni/search?q={query}"
method: GET
parsing_engine: xpath
xpath: "//h3/a[@href]"
proxy: true
categories: general

224
main.tf Normal file
View File

@ -0,0 +1,224 @@
# Description: This file contains the main Terraform configuration for the SonarQube Docker container configuration.
# Define the local variables
locals {
app_name = "searxng"
app_version = "latest"
app_src_port = "8080"
app_dst_port = "8080"
db_type = "redis"
db_version = "alpine"
db_src_port = "6379"
db_dst_port = "6379"
}
# Get the ID of the traefik_network
data "docker_network" "traefik_network" {
name = "traefik_network"
}
# Create Docker volumes dynamically based on service_volumes variable
resource "docker_volume" "service_volume" {
for_each = toset(flatten([
for svc, cfg in var.service_volumes : [
for vol_name, _ in cfg.volumes : vol_name
]
]))
name = each.value
}
# Create Docker images dynamically based on service_images variable
resource "docker_image" "database" {
name = "docker.io/library/${local.db_type}:${local.db_version}"
}
# Create Docker images dynamically based on service_images variable
resource "docker_image" "application" {
name = "docker.io/${local.app_name}/${local.app_name}:${local.app_version}"
}
# Create Docker images dynamically based on service_images variable
resource "docker_image" "tor" {
name = "docker.io/shinomineko/torproxy:latest"
}
resource "docker_container" "tor" {
image = docker_image.tor.image_id
name = "${local.app_name}-tor"
hostname = "${local.app_name}-tor"
command = [
"--Log", "notice stdout",
"--RunAsDaemon", "0",
"--SocksPort", "0.0.0.0:9050"
]
networks_advanced {
name = data.docker_network.traefik_network.name
}
#ports {
# internal = 9050
# external = 9050
#}
env = [
"ALLOW_UNKNOWN=true",
"SOCKS_PORT=9050"
]
}
# Create Docker containers dynamically based on service_volumes variable
resource "docker_container" "db" {
image = docker_image.database.image_id
name = "${local.app_name}-${local.db_type}-db"
hostname = "${local.app_name}-db"
command = ["--save", "30", "1", "--loglevel", "warning"]
networks_advanced {
name = data.docker_network.traefik_network.name
}
dynamic "volumes" {
for_each = var.service_volumes["database"].volumes
iterator = volume
content {
volume_name = docker_volume.service_volume[volume.key].name
container_path = volume.value
}
}
restart = "always"
capabilities {
drop = ["ALL"]
add = ["SETGID", "SETUID", "DAC_OVERRIDE"]
}
#logging {
# driver = "json-file"
# options = {
# "max-size" = "1m"
# "max-file" = "1"
# }
#}
}
# Create Docker containers dynamically based on service_volumes variable
resource "docker_container" "application" {
image = docker_image.application.image_id
name = local.app_name
hostname = local.app_name
networks_advanced {
name = data.docker_network.traefik_network.name
}
env = [
"SEARXNG_BASE_URL=https://search.bsdserver.nl/",
]
dynamic "volumes" {
for_each = var.service_volumes["application"].volumes
iterator = volume
content {
volume_name = docker_volume.service_volume[volume.key].name
container_path = volume.value
}
}
capabilities {
drop = ["ALL"]
add = ["CHOWN", "SETGID", "SETUID"]
}
#logging {
# driver = "json-file"
# options = {
# "max-size" = "1m"
# "max-file" = "1"
# }
#}
upload {
content = file("${path.module}/files/settings.yml")
file = "/etc/searxng/settings.yml"
}
upload {
content = file("${path.module}/files/limiter.toml")
file = "/etc/searxng/limiter.toml"
}
labels {
label = "traefik.enable"
value = "true"
}
labels {
label = "traefik.http.routers.searxng.entrypoints"
value = "websecure"
}
labels {
label = "traefik.http.routers.searxng.rule"
value = "Host(`search.bsdserver.nl`)"
}
labels {
label = "traefik.http.services.searxng.loadBalancer.server.port"
value = 8080
}
labels {
label = "traefik.http.routers.searxng.tls"
value = "true"
}
labels {
label = "traefik.http.routers.searxng.tls.certresolver"
value = "production"
}
labels {
label = "traefik.http.middlewares.searxng-headers.headers.customresponseheaders.Strict-Transport-Security"
value = "max-age=31536000; includeSubDomains; preload"
}
labels {
label = "traefik.http.middlewares.searxng-headers.headers.customresponseheaders.X-XSS-Protection"
value = "1; mode=block"
}
labels {
label = "traefik.http.middlewares.searxng-headers.headers.customresponseheaders.X-Content-Type-Options"
value = "nosniff"
}
labels {
label = "traefik.http.middlewares.searxng-headers.headers.customresponseheaders.Permissions-Policy"
value = "accelerometer=(),ambient-light-sensor=(),autoplay=(),camera=(),encrypted-media=(),focus-without-user-activation=(),geolocation=(),gyroscope=(),magnetometer=(),microphone=(),midi=(),payment=(),picture-in-picture=(),speaker=(),sync-xhr=(),usb=(),vr=()"
}
labels {
label = "traefik.http.middlewares.searxng-headers.headers.customresponseheaders.Referrer-Policy"
value = "no-referrer"
}
labels {
label = "traefik.http.middlewares.searxng-headers.headers.customresponseheaders.X-Robots-Tag"
value = "noindex, noarchive, nofollow"
}
labels {
label = "traefik.http.routers.searxng.middlewares"
value = "searxng-headers"
}
##labels {
## label = "traefik.http.routers.searxng.middlewares"
## value = "forward-auth"
##}
restart = "always"
depends_on = [
docker_container.db
]
}

7
outputs.tf Normal file
View File

@ -0,0 +1,7 @@
# Purpose: This file is used to output the values of the resources created in the main.tf file.
# The output "searxng" block outputs the value of the password from the SearXNG secret in Vault.
#output "searxng" {
# value = data.vault_generic_secret.searxng.data ["admin_password"]
# sensitive = true
#}

33
provider.tf Normal file
View File

@ -0,0 +1,33 @@
# Description: This file is used to configure the Docker and Vault providers.
terraform {
required_providers {
docker = {
source = "abh80/docker"
version = "1.0.1"
}
vault = {
source = "hashicorp/vault"
version = "3.25.0"
}
}
}
# Configure the Docker provider
provider "docker" {
host = "tcp://192.168.2.170:2376"
cert_path = pathexpand("~/.docker")
}
# Configure the Vault provider
provider "vault" {
address = "https://wbyc-srv-docker01.bsdserver.lan:8200"
auth_login {
path = "auth/approle/login"
parameters = {
role_id = var.role_id
secret_id = var.secret_id
}
}
}

24
variables.tf Normal file
View File

@ -0,0 +1,24 @@
variable "service_volumes" {
description = "Mapping of service names to their volume names and mount points"
type = map(object({
volumes = map(string)
}))
}
variable "domain" {
description = "Domain name for the application"
type = string
default = "bsdserver.lan"
}
variable "role_id" {
description = "Role ID for Vault AppRole authentication"
type = string
sensitive = true
}
variable "secret_id" {
description = "Secret ID for Vault AppRole authentication"
type = string
sensitive = true
}