Missed some changes lmao.

This commit is contained in:
Greyscale 2024-06-04 17:36:15 +02:00
parent 203dba7db8
commit 2cad55b5e4
No known key found for this signature in database
GPG key ID: 74BAFF55434DA4B2
16 changed files with 325 additions and 16 deletions

View file

@ -0,0 +1,99 @@
//resource "random_uuid" "edge_id" {}
data "docker_registry_image" "portainer_agent" {
name = "portainer/agent:${var.portainer.version}"
}
resource "docker_network" "portainer_edge_network" {
name = "portainer_edge_network"
driver = "overlay"
labels {
label = "com.docker.stack.namespace"
value = var.docker.stack_name
}
lifecycle {
ignore_changes = [
ipam_config,
]
}
}
resource "docker_service" "portainer_edge_agent" {
name = var.docker.name_agent
mode {
global = true
}
task_spec {
container_spec {
image = "${data.docker_registry_image.portainer_agent.name}@${data.docker_registry_image.portainer_agent.sha256_digest}"
command = concat(["./agent"], var.debug ? ["--log-level", "DEBUG"] : [])
env = {
AGENT_CLUSTER_ADDR = "tasks.${var.docker.name_agent}"
EDGE = 1
EDGE_ID = var.edge_id
#EDGE_KEY = local.edge_key
EDGE_KEY = var.edge_key
EDGE_INSECURE_POLL = 1
}
mounts {
target = "/var/run/docker.sock"
source = "/var/run/docker.sock"
read_only = false
type = "bind"
}
mounts {
target = "/var/lib/docker/volumes"
source = "/var/lib/docker/volumes"
read_only = false
type = "bind"
}
mounts {
target = "/host"
source = "/"
read_only = false
type = "bind"
}
// MB:Might need to add a portainer_agent_data volume (not bind) here mounting int /data
labels {
label = "com.docker.stack.namespace"
value = var.docker.stack_name
}
}
networks_advanced {
name = docker_network.portainer_edge_network.id
}
restart_policy {
condition = "on-failure"
delay = "0s"
#max_attempts = -1
window = "10s"
}
placement {
constraints = [
"node.platform.os == linux"
]
platforms {
architecture = "amd64"
os = "linux"
}
}
resources {
limits {
nano_cpus = 30 * 10000000
memory_bytes = 256 * 1000000
}
reservation {
nano_cpus = 5 * 10000000
memory_bytes = 64 * 1000000
}
}
}
update_config {
order = "stop-first"
}
labels {
label = "com.docker.stack.namespace"
value = var.docker.stack_name
}
labels {
label = "com.docker.stack.image"
value = replace(data.docker_registry_image.portainer_agent.name, "/:.*/", "")
}
}

View file

@ -0,0 +1,26 @@
variable "docker" {
type = object({
name_agent = string
stack_name = optional(string)
})
}
variable "portainer" {
type = object({
version = string
})
}
variable "edge_id" {
type = string
description = "The ID of the edge agent"
default = null
}
variable "edge_key" {
type = string
description = "The key of the edge agent"
default = null
}
variable "debug" {
type = bool
description = "Enable debug mode"
default = false
}

View file

@ -0,0 +1,18 @@
terraform {
required_version = "~> 1.6"
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "~> 3.0"
}
random = {
source = "hashicorp/random"
version = "~> 3.5"
}
scratch = {
source = "BrendanThompson/scratch"
version = "~> 0.4"
}
}
}

View file

@ -0,0 +1,16 @@
variable "docker" {
type = object({
name = string
stack_name = optional(string)
networks = list(object({
name = string
id = string
}))
})
}
variable "portainer" {
type = object({
version = string
logo = optional(string)
})
}

View file

@ -0,0 +1,9 @@
output "portainer" {
value = {
credentials = {
username = "admin" # Sorry, this is hardcoded in the portainer image
password = nonsensitive(random_password.password.result)
}
service_name = docker_service.portainer.name
}
}

View file

@ -0,0 +1,18 @@
terraform {
required_version = "~> 1.6"
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "~> 3.0"
}
random = {
source = "hashicorp/random"
version = "~> 3.5"
}
htpasswd = {
source = "loafoe/htpasswd"
version = "~> 1.0"
}
}
}

View file

@ -0,0 +1,106 @@
resource "random_password" "password" {
length = 32
}
resource "random_password" "salt" {
length = 8
}
resource "htpasswd_password" "hash" {
password = random_password.password.result
salt = random_password.salt.result
}
data "docker_registry_image" "portainer_app" {
name = "portainer/portainer-ce:${var.portainer.version}"
}
resource "docker_volume" "portainer" {
name = var.docker.name
}
resource "docker_service" "portainer" {
name = var.docker.name
mode {
replicated {
replicas = 1
}
}
task_spec {
container_spec {
image = "${data.docker_registry_image.portainer_app.name}@${data.docker_registry_image.portainer_app.sha256_digest}"
command = [
"/portainer",
//"--edge-compute",
"--logo", coalesce(var.portainer.logo),
"--admin-password", htpasswd_password.hash.bcrypt,
]
#mounts {
# target = "/data"
# source = "/portainer"
# read_only = false
# type = "bind"
#}
mounts {
target = "/data"
source = docker_volume.portainer.name
type = "volume"
read_only = false
}
#mounts {
# target = "/var/run/docker.sock"
# source = "/var/run/docker.sock"
# read_only = false
# type = "bind"
#}
labels {
label = "com.docker.stack.namespace"
value = var.docker.stack_name
}
}
dynamic "networks_advanced" {
for_each = var.docker.networks
content {
name = networks_advanced.value.id
}
}
restart_policy {
condition = "on-failure"
delay = "3s"
max_attempts = 4
window = "10s"
}
placement {
constraints = [
"node.role == manager",
"node.platform.os == linux",
]
}
}
#endpoint_spec {
# ports {
# target_port = 9000
# publish_mode = "ingress"
# published_port = 9000
# }
# ports {
# target_port = 8000
# publish_mode = "ingress"
# published_port = 8000
# }
#}
update_config {
# Portainer gets super fuckin' upset if you start a second instance while the first is holding the db lock
order = "stop-first"
}
labels {
label = "com.docker.stack.namespace"
value = var.docker.stack_name
}
labels {
label = "com.docker.stack.image"
value = replace(data.docker_registry_image.portainer_app.name, "/:.*/", "")
}
lifecycle {
ignore_changes = [
# MB: This is a hack because terraform keeps detecting a "change" in the placement->platform constraint that doesn't exist.
task_spec[0].placement[0].platforms
]
}
}

View file

@ -1,4 +0,0 @@
resource "local_file" "configs" {
content = yamlencode(var.configs)
filename = "${path.module}/debug/config.yaml"
}

View file

@ -1,3 +1,5 @@
resolver 127.0.0.11 ipv6=off valid=1s;
server {
listen 80;
listen [::]:80;

View file

@ -1,16 +1,19 @@
locals {
default_page = "<h1>Hello, World!</h1>"
}
resource "docker_config" "default_page" {
name = "${var.service_name}.index.html"
data = base64encode("<h1>Hello, World!</h1>")
name = "${var.service_name}.index.html-${substr(sha1(local.default_page), 0, 4)}"
data = base64encode(local.default_page)
}
resource "local_file" "default_page" {
content = base64decode(docker_config.default_page.data)
filename = "${path.module}/debug/index.html"
filename = "${path.root}/.debug/nginx/index.html"
}
resource "docker_config" "default_conf" {
name = "${var.service_name}.default.conf"
name = "${var.service_name}.default.conf-${substr(sha1(file("${path.module}/default.conf")), 0, 4)}"
data = base64encode(file("${path.module}/default.conf"))
}
resource "local_file" "default_conf" {
content = base64decode(docker_config.default_conf.data)
filename = "${path.module}/debug/default.conf"
filename = "${path.root}/.debug/nginx/default.conf"
}

View file

@ -7,5 +7,5 @@ resource "docker_config" "auth" {
resource "local_file" "auth" {
count = var.basic_auth != null ? 1 : 0
content = local.auth
filename = "${path.module}/../debug/${local.filenames.auth}"
filename = "${path.root}/.debug/nginx/${local.filenames.auth}"
}

View file

@ -6,7 +6,7 @@ resource "docker_config" "certificate" {
resource "local_file" "certificate" {
count = var.certificate != null ? 1 : 0
content = local.cert_public
filename = "${path.module}/../debug/${local.filenames.certificate}"
filename = "${path.root}/.debug/nginx/${local.filenames.certificate}"
}
resource "docker_config" "certificate_key" {
count = var.certificate != null ? 1 : 0
@ -16,5 +16,5 @@ resource "docker_config" "certificate_key" {
resource "local_file" "certificate_key" {
count = var.certificate != null ? 1 : 0
content = var.certificate.private_key_pem
filename = "${path.module}/../debug/${local.filenames.certificate_key}"
filename = "${path.root}/.debug/nginx/${local.filenames.certificate_key}"
}

View file

@ -63,3 +63,8 @@ resource "docker_config" "nginx_site_available" {
name = join(".", [var.config_prefix, "conf", var.hostname, random_id.config_instance.id])
data = base64encode(local.config)
}
resource "local_file" "nginx_site_available" {
filename = "${path.root}/.debug/nginx/${local.filenames.nginx}"
content = local.config
}

View file

@ -78,6 +78,6 @@ server {
proxy_send_timeout ${timeout_seconds};
}
${extra_locations~}
${extra_locations}
}

View file

@ -1,3 +1,6 @@
output "files" {
value = local.files
}
output "hostname" {
value = var.hostname
}

View file

@ -35,6 +35,17 @@ resource "docker_service" "nginx" {
file_name = "/etc/nginx/conf.d/${configs.value.file}"
}
}
# Healthcheck that checks that the nginx process is running
#healthcheck {
# test = ["CMD", "pgrep", "nginx"]
# interval = "10s"
# timeout = "5s"
# retries = 3
# start_period = "10s"
#}
healthcheck {
test = ["CMD", "true"]
}
labels {
label = "com.nginx.iteration-id"
value = random_id.iteration.hex
@ -46,7 +57,6 @@ resource "docker_service" "nginx" {
name = networks_advanced.value.id
}
}
# @todo MB: Healthcheck.
}
endpoint_spec {
ports {
@ -60,11 +70,9 @@ resource "docker_service" "nginx" {
published_port = 443
}
}
update_config {
parallelism = ceil(var.replicas / 3)
delay = "10s"
order = "start-first"
}
}