initial commit

This commit is contained in:
Greyscale 2024-06-21 17:52:01 +02:00
parent 5d4f8448cb
commit 007c98d282
No known key found for this signature in database
GPG key ID: 74BAFF55434DA4B2
8 changed files with 293 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/.idea

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"
}
}
}

106
docker-portainer-ui/ui.tf Normal file
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
]
}
}