-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathk8s.tf
140 lines (137 loc) · 3.81 KB
/
k8s.tf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# lets create a namespace for our ctf challenges
resource "kubernetes_namespace" "challenge_ns" {
metadata {
name = "ctf-chals"
}
}
resource "kubernetes_deployment" "challenge_deployment" {
depends_on = [
docker_registry_image.challenge_published, docker_image.chal, docker_registry_image.healthcheck_published
]
metadata {
name = "${var.name}-deploy"
namespace = kubernetes_namespace.challenge_ns.metadata[0].name
labels = {
app = var.name
}
}
spec {
replicas = 1
selector {
match_labels = {
app = var.name
}
}
template {
metadata {
labels = {
app = var.name
}
# required to mount things in most clouds
annotations = {
"container.apparmor.security.beta.kubernetes.io/challenge" : "unconfined"
}
}
spec {
container {
name = "challenge"
image = local.published_image_name
port {
container_port = 1337
}
# this is the most restrictive context that still allows nsjail to run
security_context {
read_only_root_filesystem = true
capabilities {
drop = ["ALL"]
add = local.k8s_capabilities
}
}
// both the liveness probe and the readiness probe are part of the healthcheck
dynamic liveness_probe {
// we use dynamic to include the healthcheck conditionally
for_each = var.healthcheck ? [1] : []
content {
http_get {
path = "/"
port = 21337
}
failure_threshold = 2
initial_delay_seconds = 45
timeout_seconds = 3
period_seconds = 30
}
}
dynamic readiness_probe {
// we use dynamic to include the healthcheck conditionally
for_each = var.healthcheck ? [1] : []
content {
http_get {
path = "/"
port = 21337
}
initial_delay_seconds = 5
timeout_seconds = 3
period_seconds = 5
}
}
}
dynamic container {
// we use dynamic to include the healthcheck conditionally
for_each = var.healthcheck ? [1] : []
content {
name = "healthcheck"
image = local.published_healthcheck_image_name
resources {
limits = {
cpu = "1000m"
}
requests = {
cpu = "50m"
}
}
}
}
}
}
}
}
resource "kubernetes_horizontal_pod_autoscaler" "challenge_autoscaler" {
# only create the autoscaler if necessary
count = var.max_replicas > var.min_replicas ? 1 : 0
depends_on = [kubernetes_deployment.challenge_deployment]
metadata {
name = "${var.name}-autoscaler"
namespace = kubernetes_namespace.challenge_ns.metadata[0].name
}
spec {
target_cpu_utilization_percentage = var.target_utilization
min_replicas = var.min_replicas
max_replicas = var.max_replicas
scale_target_ref {
kind = "Deployment"
name = "${var.name}-deploy"
}
}
}
resource "kubernetes_service" "challenge_service" {
depends_on = [kubernetes_deployment.challenge_deployment, docker_image.chal]
metadata {
name = "${var.name}-service"
namespace = kubernetes_namespace.challenge_ns.metadata[0].name
labels = {
app = var.name
}
}
spec {
type = "LoadBalancer"
port {
port = local.k8s_port
protocol = "TCP"
target_port = 1337
}
selector = {
app = var.name
}
}
}