Skip to content

Terraform + k8s

Deploy DeepIntShield on Kubernetes using Terraform. This guide breaks down the deployment into individual components for better understanding.

Create an EBS volume, persistent volume, and persistent volume claim for DeepIntShield data storage.

locals {
service_name = "deepintshield-service"
}
resource "aws_ebs_volume" "bifrost_disk" {
availability_zone = "${var.region}${var.main_zone}"
size = var.volume_size_gb
type = "gp3"
encrypted = true
tags = {
Name = "deepintshield-disk"
}
lifecycle {
ignore_changes = [tags]
}
}
resource "kubernetes_persistent_volume" "bifrost_volume" {
metadata {
name = "deepintshield-volume"
}
spec {
capacity = {
storage = "${var.volume_size_gb}Gi"
}
access_modes = ["ReadWriteOnce"]
persistent_volume_reclaim_policy = "Retain"
storage_class_name = "gp3"
persistent_volume_source {
aws_elastic_block_store {
volume_id = aws_ebs_volume.bifrost_disk.id
fs_type = "ext4"
}
}
}
depends_on = [aws_ebs_volume.bifrost_disk]
lifecycle {
prevent_destroy = false
}
}
resource "kubernetes_persistent_volume_claim" "bifrost_volume_claim" {
metadata {
name = "deepintshield-volume-claim"
namespace = var.namespace
}
spec {
access_modes = ["ReadWriteOnce"]
resources {
requests = {
storage = "${var.volume_size_gb}Gi"
}
}
storage_class_name = "gp3"
volume_name = "deepintshield-volume"
}
depends_on = [kubernetes_persistent_volume.bifrost_volume]
}

Create a Kubernetes secret to store DeepIntShield configuration with Postgres backend.

resource "kubernetes_secret" "bifrost_config" {
metadata {
name = "deepintshield-config"
namespace = kubernetes_namespace.bifrost_namespace.metadata[0].name
}
data = {
"config.json" = jsonencode({
"config_store" : {
"enabled" : true,
"type" : "postgres",
"config" : {
"host" : "${var.pg_host}",
"port" : "${var.pg_port}",
"user" : "${var.pg_user}",
"password" : "${var.pg_password}",
"db_name" : "${var.pg_database}",
"ssl_mode": "disable"
}
},
"logs_store" : {
"enabled" : true,
"type" : "postgres",
"config" : {
"host" : "${var.pg_host}",
"port" : "${var.pg_port}",
"user" : "${var.pg_user}",
"password" : "${var.pg_password}",
"db_name" : "${var.pg_database}",
"ssl_mode": "disable"
}
}
})
}
type = "Opaque"
depends_on = [kubernetes_namespace.bifrost_namespace]
}

Create the DeepIntShield deployment with proper security contexts and volume mounts.

resource "kubernetes_deployment" "bifrost_deployment" {
metadata {
name = local.service_name
namespace = kubernetes_namespace.bifrost_namespace.metadata[0].name
labels = {
app = local.service_name
env = var.env
}
}
spec {
replicas = var.replica_count
selector {
match_labels = {
app = local.service_name
}
}
template {
metadata {
labels = {
app = local.service_name
env = var.env
}
}
spec {
security_context {
fs_group = 1000
fs_group_change_policy = "OnRootMismatch"
}
init_container {
name = "fix-permissions"
image = "busybox:latest"
command = ["sh", "-c", "chown -R 1000:1000 /app/data && chmod -R 755 /app/data"]
security_context {
run_as_user = 0
}
volume_mount {
name = "deepintshield-volume"
mount_path = "/app/data"
}
}
container {
name = "deepintshield-service"
image = "maximhq/deepintshield:${var.image_tag}"
port {
container_port = 8080
name = "http"
}
security_context {
run_as_user = 1000
run_as_group = 1000
run_as_non_root = true
allow_privilege_escalation = false
}
resources {
requests = {
cpu = "250m"
memory = "512Mi"
}
limits = {
cpu = "500m"
memory = "1Gi"
}
}
volume_mount {
name = "deepintshield-volume"
mount_path = "/app/data"
}
volume_mount {
name = "config-volume"
mount_path = "/app/data/config.json"
sub_path = "config.json"
}
liveness_probe {
http_get {
path = "/health"
port = 8080
}
initial_delay_seconds = 30
period_seconds = 10
timeout_seconds = 5
failure_threshold = 3
}
readiness_probe {
http_get {
path = "/health"
port = 8080
}
initial_delay_seconds = 10
period_seconds = 5
timeout_seconds = 3
failure_threshold = 3
}
}
volume {
name = "deepintshield-volume"
persistent_volume_claim {
claim_name = "deepintshield-volume-claim"
}
}
volume {
name = "config-volume"
secret {
secret_name = kubernetes_secret.bifrost_config.metadata[0].name
}
}
}
}
}
depends_on = [kubernetes_secret.bifrost_config, kubernetes_persistent_volume_claim.bifrost_volume_claim]
}

Create a Kubernetes service to expose the DeepIntShield deployment.

resource "kubernetes_service" "bifrost_service" {
metadata {
name = local.service_name
namespace = kubernetes_namespace.bifrost_namespace.metadata[0].name
labels = {
app = local.service_name
}
}
spec {
selector = {
app = local.service_name
}
port {
name = "http"
port = 80
target_port = 8080
protocol = "TCP"
}
type = "ClusterIP"
}
}

Here’s the complete Terraform configuration combining all components:

locals {
service_name = "deepintshield-service"
}
# Volume Configuration
resource "aws_ebs_volume" "bifrost_disk" {
availability_zone = "${var.region}${var.main_zone}"
size = var.volume_size_gb
type = "gp3"
encrypted = true
tags = {
Name = "deepintshield-disk"
}
lifecycle {
ignore_changes = [tags]
}
}
resource "kubernetes_persistent_volume" "bifrost_volume" {
metadata {
name = "deepintshield-volume"
}
spec {
capacity = {
storage = "${var.volume_size_gb}Gi"
}
access_modes = ["ReadWriteOnce"]
persistent_volume_reclaim_policy = "Retain"
storage_class_name = "gp3"
persistent_volume_source {
aws_elastic_block_store {
volume_id = aws_ebs_volume.bifrost_disk.id
fs_type = "ext4"
}
}
}
depends_on = [aws_ebs_volume.bifrost_disk]
lifecycle {
prevent_destroy = false
}
}
resource "kubernetes_persistent_volume_claim" "bifrost_volume_claim" {
metadata {
name = "deepintshield-volume-claim"
namespace = var.namespace
}
spec {
access_modes = ["ReadWriteOnce"]
resources {
requests = {
storage = "${var.volume_size_gb}Gi"
}
}
storage_class_name = "gp3"
volume_name = "deepintshield-volume"
}
depends_on = [kubernetes_persistent_volume.bifrost_volume]
}
# Configuration Secret
resource "kubernetes_secret" "bifrost_config" {
metadata {
name = "deepintshield-config"
namespace = kubernetes_namespace.bifrost_namespace.metadata[0].name
}
data = {
"config.json" = jsonencode({
"config_store" : {
"enabled" : true,
"type" : "postgres",
"config" : {
"host" : "${var.pg_host}",
"port" : "${var.pg_port}",
"user" : "${var.pg_user}",
"password" : "${var.pg_password}",
"db_name" : "${var.pg_database}",
"ssl_mode": "disable"
}
},
"logs_store" : {
"enabled" : true,
"type" : "postgres",
"config" : {
"host" : "${var.pg_host}",
"port" : "${var.pg_port}",
"user" : "${var.pg_user}",
"password" : "${var.pg_password}",
"db_name" : "${var.pg_database}",
"ssl_mode": "disable"
}
}
})
}
type = "Opaque"
depends_on = [kubernetes_namespace.bifrost_namespace]
}
# Deployment Configuration
resource "kubernetes_deployment" "bifrost_deployment" {
metadata {
name = local.service_name
namespace = kubernetes_namespace.bifrost_namespace.metadata[0].name
labels = {
app = local.service_name
env = var.env
}
}
spec {
replicas = var.replica_count
selector {
match_labels = {
app = local.service_name
}
}
template {
metadata {
labels = {
app = local.service_name
env = var.env
}
}
spec {
security_context {
fs_group = 1000
fs_group_change_policy = "OnRootMismatch"
}
init_container {
name = "fix-permissions"
image = "busybox:latest"
command = ["sh", "-c", "chown -R 1000:1000 /app/data && chmod -R 755 /app/data"]
security_context {
run_as_user = 0
}
volume_mount {
name = "deepintshield-volume"
mount_path = "/app/data"
}
}
container {
name = "deepintshield-service"
image = "maximhq/deepintshield:${var.image_tag}"
port {
container_port = 8080
name = "http"
}
security_context {
run_as_user = 1000
run_as_group = 1000
run_as_non_root = true
allow_privilege_escalation = false
}
resources {
requests = {
cpu = "250m"
memory = "512Mi"
}
limits = {
cpu = "500m"
memory = "1Gi"
}
}
volume_mount {
name = "deepintshield-volume"
mount_path = "/app/data"
}
volume_mount {
name = "config-volume"
mount_path = "/app/data/config.json"
sub_path = "config.json"
}
liveness_probe {
http_get {
path = "/health"
port = 8080
}
initial_delay_seconds = 30
period_seconds = 10
timeout_seconds = 5
failure_threshold = 3
}
readiness_probe {
http_get {
path = "/health"
port = 8080
}
initial_delay_seconds = 10
period_seconds = 5
timeout_seconds = 3
failure_threshold = 3
}
}
volume {
name = "deepintshield-volume"
persistent_volume_claim {
claim_name = "deepintshield-volume-claim"
}
}
volume {
name = "config-volume"
secret {
secret_name = kubernetes_secret.bifrost_config.metadata[0].name
}
}
}
}
}
depends_on = [kubernetes_secret.bifrost_config, kubernetes_persistent_volume_claim.bifrost_volume_claim]
}
# Service Configuration
resource "kubernetes_service" "bifrost_service" {
metadata {
name = local.service_name
namespace = kubernetes_namespace.bifrost_namespace.metadata[0].name
labels = {
app = local.service_name
}
}
spec {
selector = {
app = local.service_name
}
port {
name = "http"
port = 80
target_port = 8080
protocol = "TCP"
}
type = "ClusterIP"
}
}