Project: KICS (Provisioning / Security & Compliance)
File: 7249e3b0-9231-4af3-bc5f-5daf4988ecbf.md

title: StatefulSet Without PodDisruptionBudget hide: toc: true navigation: true <style> .highlight .hll { background-color: #ff171742; } .md-content { max-width: 1100px; margin: 0 auto; } </style> Query id: 7249e3b0-9231-4af3-bc5f-5daf4988ecbf Query name: StatefulSet Without PodDisruptionBudget Platform: Terraform Severity: <span style="color:#edd57e">Low</span> Category: Availability URL: StatefulSets should be assigned with a PodDisruptionBudget to ensure high availability<br> ```tf title="Positive test num. 1 - tf file" hl_lines="23" resource "kubernetesstatefulset" "prometheus" { metadata { annotations = { SomeAnnotation = "foobar" } labels = { k8s-app = "prometheus" "kubernetes.io/cluster-service" = "true" "addonmanager.kubernetes.io/mode" = "Reconcile" version = "v2.2.1" } name = "prometheus" } spec { podmanagementpolicy = "Parallel" replicas = 2 revisionhistorylimit = 5 selector { match_labels = { k8s-app2 = "prometheus2" } } service_name = "prometheus" template { metadata { labels = { k8s-app = "prometheus" } annotations = {} } spec { serviceaccountname = "prometheus" init_container { name = "init-chown-data" image = "busybox:latest" imagepullpolicy = "IfNotPresent" command = ["chown", "-R", "65534:65534", "/data"] volume_mount { name = "prometheus-data" mount_path = "/data" sub_path = "" } } container { name = "prometheus-server-configmap-reload" image = "jimmidyson/configmap-reload:v0.1" imagepullpolicy = "IfNotPresent" args = [ "--volume-dir=/etc/config", "--webhook-url=http://localhost:9090/-/reload", ] volume_mount { name = "config-volume" mount_path = "/etc/config" read_only = true } resources { limits = { cpu = "10m" memory = "10Mi" } requests = { cpu = "10m" memory = "10Mi" } } } container { name = "prometheus-server" image = "prom/prometheus:v2.2.1" imagepullpolicy = "IfNotPresent" args = [ "--config.file=/etc/config/prometheus.yml", "--storage.tsdb.path=/data", "--web.console.libraries=/etc/prometheus/console_libraries", "--web.console.templates=/etc/prometheus/consoles", "--web.enable-lifecycle", ] port { container_port = 9090 } resources { limits = { cpu = "200m" memory = "1000Mi" } requests = { cpu = "200m" memory = "1000Mi" } } volume_mount { name = "config-volume" mount_path = "/etc/config" } volume_mount { name = "prometheus-data" mount_path = "/data" sub_path = "" } readiness_probe { http_get { path = "/-/ready" port = 9090 } initialdelayseconds = 30 timeout_seconds = 30 } liveness_probe { http_get { path = "/-/healthy" port = 9090 scheme = "HTTPS" } initialdelayseconds = 30 timeout_seconds = 30 } } terminationgraceperiod_seconds = 300 volume { name = "config-volume" config_map { name = "prometheus-config" } } } } update_strategy { type = "RollingUpdate" rolling_update { partition = 1 } } volumeclaimtemplate { metadata { name = "prometheus-data" } spec { access_modes = ["ReadWriteOnce"] storageclassname = "standard" resources { requests = { storage = "16Gi" } } } } } } resource "kubernetespoddisruption_budget" "demo" { metadata { name = "demo" } spec { max_unavailable = "20%" selector { match_labels = { test = "MyExampleApp" } } } } ``` ```tf title="Negative test num. 1 - tf file" resource "kubernetesstatefulset" "prometheus2" { metadata { annotations = { SomeAnnotation = "foobar" } labels = { k8s-app = "prometheus" "kubernetes.io/cluster-service" = "true" "addonmanager.kubernetes.io/mode" = "Reconcile" version = "v2.2.1" } name = "prometheus" } spec { podmanagementpolicy = "Parallel" replicas = 2 revisionhistorylimit = 5 selector { match_labels = { k8s-app = "prometheus" } } service_name = "prometheus" template { metadata { labels = { k8s-app = "prometheus" } annotations = {} } spec { serviceaccountname = "prometheus" init_container { name = "init-chown-data" image = "busybox:latest" imagepullpolicy = "IfNotPresent" command = ["chown", "-R", "65534:65534", "/data"] volume_mount { name = "prometheus-data" mount_path = "/data" sub_path = "" } } container { name = "prometheus-server-configmap-reload" image =

imagepullpolicy = "IfNotPresent" args = [ "--volume-dir=/etc/config", "--webhook-url=http://localhost:9090/-/reload", ] volume_mount { name = "config-volume" mount_path = "/etc/config" read_only = true } resources { limits = { cpu = "10m" memory = "10Mi" } requests = { cpu = "10m" memory = "10Mi" } } } container { name = "prometheus-server" image = "prom/prometheus:v2.2.1" imagepullpolicy = "IfNotPresent" args = [ "--config.file=/etc/config/prometheus.yml", "--storage.tsdb.path=/data", "--web.console.libraries=/etc/prometheus/console_libraries", "--web.console.templates=/etc/prometheus/consoles", "--web.enable-lifecycle", ] port { container_port = 9090 } resources { limits = { cpu = "200m" memory = "1000Mi" } requests = { cpu = "200m" memory = "1000Mi" } } volume_mount { name = "config-volume" mount_path = "/etc/config" } volume_mount { name = "prometheus-data" mount_path = "/data" sub_path = "" } readiness_probe { http_get { path = "/-/ready" port = 9090 } initialdelayseconds = 30 timeout_seconds = 30 } liveness_probe { http_get { path = "/-/healthy" port = 9090 scheme = "HTTPS" } initialdelayseconds = 30 timeout_seconds = 30 } } terminationgraceperiod_seconds = 300 volume { name = "config-volume" config_map { name = "prometheus-config" } } } } update_strategy { type = "RollingUpdate" rolling_update { partition = 1 } } volumeclaimtemplate { metadata { name = "prometheus-data" } spec { access_modes = ["ReadWriteOnce"] storageclassname = "standard" resources { requests = { storage = "16Gi" } } } } } } resource "kubernetespoddisruption_budget" "demo2" { metadata { name = "demo" } spec { max_unavailable = "20%" selector { match_labels = { k8s-app = "prometheus" } } } } resource "kubernetesstatefulset" "prometheus3" { metadata { annotations = { SomeAnnotation = "foobar" } labels = { k8s-app = "prometheus" "kubernetes.io/cluster-service" = "true" "addonmanager.kubernetes.io/mode" = "Reconcile" version = "v2.2.1" } name = "prometheus" } spec { podmanagementpolicy = "Parallel" replicas = 2 revisionhistorylimit = 5 selector { match_labels = { k8s-app = "kubernetespoddisruptionbudget.demo2.spec.selector.0.matchlabels.k8s-app2" } } service_name = "prometheus" template { metadata { labels = { k8s-app = "prometheus" } annotations = {} } spec { serviceaccountname = "prometheus" init_container { name = "init-chown-data" image = "busybox:latest" imagepullpolicy = "IfNotPresent" command = ["chown", "-R", "65534:65534", "/data"] volume_mount { name = "prometheus-data" mount_path = "/data" sub_path = "" } } container { name = "prometheus-server-configmap-reload" image = "jimmidyson/configmap-reload:v0.1" imagepullpolicy = "IfNotPresent" args = [ "--volume-dir=/etc/config", "--webhook-url=http://localhost:9090/-/reload", ] volume_mount { name = "config-volume" mount_path = "/etc/config" read_only = true } resources { limits = { cpu = "10m" memory = "10Mi" } requests = { cpu = "10m" memory = "10Mi" } } } container { name = "prometheus-server" image = "prom/prometheus:v2.2.1" imagepullpolicy = "IfNotPresent" args = [ "--config.file=/etc/config/prometheus.yml", "--storage.tsdb.path=/data", "--web.console.libraries=/etc/prometheus/console_libraries", "--web.console.templates=/etc/prometheus/consoles", "--web.enable-lifecycle", ] port { container_port = 9090 } resources { limits = { cpu = "200m" memory = "1000Mi" } requests = { cpu = "200m" memory = "1000Mi" } } volume_mount { name = "config-volume" mount_path = "/etc/config" } volume_mount { name = "prometheus-data" mount_path = "/data" sub_path = "" } readiness_probe { http_get { path = "/-/ready" port = 9090 } initialdelayseconds = 30 timeout_seconds = 30 } liveness_probe { http_get { path = "/-/healthy" port = 9090 scheme = "HTTPS" } initialdelayseconds = 30 timeout_seconds = 30 } } terminationgraceperiod_seconds = 300 volume { name = "config-volume" config_map { name = "prometheus-config" } } } } update_strategy { type = "RollingUpdate" rolling_update { partition = 1 } } volumeclaimtemplate { metadata { name = "prometheus-data" } spec { access_modes = ["ReadWriteOnce"] storageclassname = "standard" resources { requests = { storage = "16Gi" } } } } } } ```