Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions terraform/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,17 @@ variable "tavern_container_image" {
default = "spellshift/tavern:latest"
}

variable "tavern_request_timeout_seconds" {
type = number
description = "How many seconds before a request is dropped, defaults to 3600 (the maximum) to accomodate reverse shells (which are killed when this timeout is reached)"
default = 3600

validation {
condition = var.tavern_request_timeout_seconds >= 1 && var.tavern_request_timeout_seconds <= 3600
error_message = "tavern_request_timeout_seconds must be a value between 1 and 3600 seconds"
}
}

variable "gcp_project" {
type = string
description = "GCP Project ID for deployment"
Expand All @@ -36,6 +47,25 @@ variable "gcp_region" {
description = "GCP Region for deployment"
default = "us-east4"
}

variable "disable_gcp_pubsub" {
type = bool
description = "Disables GCP pubsub setup and instead defaults to inmem pubsub, suitable for use-cases where only one tavern instance will exist and distributed orchestration is unnecessary"
default = false
}

variable "gcp_pubsub_topic_shell_input" {
type = string
description = "Name of the GCP pubsub topic to create for shell input"
default = "shell_input"
}

variable "gcp_pubsub_topic_shell_output" {
type = string
description = "Name of the GCP pubsub topic to create for shell output"
default = "shell_output"
}

variable "mysql_user" {
type = string
description = "Username to set for the configured MySQL instance"
Expand Down Expand Up @@ -146,6 +176,25 @@ locals {
prometheus_container_name = "prometheus-sidecar"
}

resource "google_pubsub_topic" "shell_input" {
count = var.disable_gcp_pubsub ? 0 : 1
name = var.gcp_pubsub_topic_shell_input
}
resource "google_pubsub_subscription" "shell_input-sub" {
count = var.disable_gcp_pubsub ? 0 : 1
name = format("%s-sub", var.gcp_pubsub_topic_shell_input)
topic = google_pubsub_topic.shell_input[0].id
}
resource "google_pubsub_topic" "shell_output" {
count = var.disable_gcp_pubsub ? 0 : 1
name = var.gcp_pubsub_topic_shell_output
}
resource "google_pubsub_subscription" "shell_output-sub" {
count = var.disable_gcp_pubsub ? 0 : 1
name = format("%s-sub", var.gcp_pubsub_topic_shell_output)
topic = google_pubsub_topic.shell_output[0].id
}

resource "google_cloud_run_service" "tavern" {
name = "tavern"
location = var.gcp_region
Expand All @@ -157,9 +206,13 @@ resource "google_cloud_run_service" "tavern" {

template {
spec {
// Controls request timeout, must be long-lived to enable reverse shell support
timeout_seconds = var.tavern_request_timeout_seconds

containers {
name = local.tavern_container_name
image = var.tavern_container_image

ports {
container_port = 80
}
Expand Down Expand Up @@ -195,6 +248,33 @@ resource "google_cloud_run_service" "tavern" {
name = "OAUTH_DOMAIN"
value = format("https://%s", var.oauth_domain)
}

// Only configure GCP pubsub if it is not disabled
dynamic "env" {
for_each = var.disable_gcp_pubsub ? [] : [
{
name = "PUBSUB_TOPIC_SHELL_INPUT"
value = format("gcppubsub://%s", google_pubsub_topic.shell_input[0].id)
},
{
name = "PUBSUB_SUBSCRIPTION_SHELL_INPUT"
value = format("gcppubsub://%s", google_pubsub_subscription.shell_input-sub[0].id)
},
{
name = "PUBSUB_TOPIC_SHELL_OUTPUT"
value = format("gcppubsub://%s", google_pubsub_topic.shell_output[0].id)
},
{
name = "PUBSUB_SUBSCRIPTION_SHELL_OUTPUT"
value = format("gcppubsub://%s", google_pubsub_subscription.shell_output-sub[0].id)
}
]
content {
name = env.value.name
value = env.value.value
}
}

env {
name = "ENABLE_METRICS"
value = var.enable_metrics ? "1" : ""
Expand Down