diff --git a/.gitignore b/.gitignore index b64fba28..907256d5 100644 --- a/.gitignore +++ b/.gitignore @@ -135,6 +135,7 @@ terraform.tfstate terraform.tfstate.backup .terraform.lock.hcl .test-data +*.tfvars aws-observability-terraform/test/*/test_output aws-observability-terraform/test/*/test_output.log aws-observability-terraform/**/.terraform diff --git a/aws-observability-v2-terraform/app-modules/outputs.tf b/aws-observability-v2-terraform/app-modules/outputs.tf new file mode 100644 index 00000000..5697c404 --- /dev/null +++ b/aws-observability-v2-terraform/app-modules/outputs.tf @@ -0,0 +1,8 @@ +output "installed_apps" { + value = { for k, v in sumologic_app.apps : k => { + uuid = v.uuid + name = k + id = v.id + } } + description = "Information about installed Sumo Logic apps" +} diff --git a/aws-observability-v2-terraform/app-modules/providers.tf b/aws-observability-v2-terraform/app-modules/providers.tf new file mode 100644 index 00000000..86924900 --- /dev/null +++ b/aws-observability-v2-terraform/app-modules/providers.tf @@ -0,0 +1,6 @@ +provider "sumologic" { + access_id = var.sumologic_access_id + access_key = var.sumologic_access_key + base_url = var.sumologic_environment_base_url + environment = var.sumologic_environment_base_url == null ? var.sumologic_environment : null +} \ No newline at end of file diff --git a/aws-observability-v2-terraform/app-modules/sumologic_resources.tf b/aws-observability-v2-terraform/app-modules/sumologic_resources.tf new file mode 100644 index 00000000..00d2ff0a --- /dev/null +++ b/aws-observability-v2-terraform/app-modules/sumologic_resources.tf @@ -0,0 +1,10 @@ +resource "sumologic_app" "apps" { + for_each = { + for app in var.installation_apps_list : app.name => app + } + + uuid = each.value.uuid + version = each.value.version + + parameters = each.value.parameters +} \ No newline at end of file diff --git a/aws-observability-v2-terraform/app-modules/terraform.tfvars.example b/aws-observability-v2-terraform/app-modules/terraform.tfvars.example new file mode 100644 index 00000000..66780b71 --- /dev/null +++ b/aws-observability-v2-terraform/app-modules/terraform.tfvars.example @@ -0,0 +1,13 @@ +sumologic_access_id = "" +sumologic_access_key = "" +sumologic_environment = "stag" +sumologic_environment_base_url = "" # e.g., "https://api.sumologic.com/api/" + +installation_apps_list = [ + { + uuid = "" + name = "Example AWS App" + version = "latest" + parameters = {} + } +] diff --git a/aws-observability-v2-terraform/app-modules/variables.tf b/aws-observability-v2-terraform/app-modules/variables.tf new file mode 100644 index 00000000..f164075b --- /dev/null +++ b/aws-observability-v2-terraform/app-modules/variables.tf @@ -0,0 +1,100 @@ +variable "sumologic_environment" { + type = string + description = "Enter au, ca, de, eu, jp, us2, kr, fed ch or us1. For more information on Sumo Logic deployments visit https://help.sumologic.com/APIs/General-API-Information/Sumo-Logic-Endpoints-and-Firewall-Security" + + validation { + condition = contains([ + "stag", + "long", + "au", + "ca", + "de", + "eu", + "jp", + "us1", + "us2", + "kr", + "fed", + "ch" + ], var.sumologic_environment) + error_message = "The value must be one of au, ca, de, eu, jp, us1, us2, kr, ch or fed." + } +} + +variable "sumologic_environment_base_url" { + type = string + description = "Base URL for custom Sumo Logic environments (e.g., 'https://api.ch.sumologic.com/api/' for Switzerland). If provided, this takes precedence over the sumologic_environment parameter. Leave empty for standard deployments." + default = null + + validation { + condition = var.sumologic_environment_base_url == null || can(regex("^https://[a-zA-Z0-9.-]+\\.sumologic\\.(com|net)/api/?$", var.sumologic_environment_base_url)) + error_message = "The base URL must be null or a valid Sumo Logic API endpoint URL (e.g., 'https://api.ch.sumologic.com/api/' or 'https://stag-api.sumologic.net/api/')." + } +} + +variable "sumologic_access_id" { + type = string + description = "Sumo Logic Access ID. Visit https://help.sumologic.com/Manage/Security/Access-Keys#Create_an_access_key" + + validation { + condition = can(regex("\\w+", var.sumologic_access_id)) + error_message = "The SumoLogic access ID must contain valid characters." + } +} + +variable "sumologic_access_key" { + type = string + description = "Sumo Logic Access Key. Visit https://help.sumologic.com/Manage/Security/Access-Keys#Create_an_access_key" + sensitive = true + + validation { + condition = can(regex("\\w+", var.sumologic_access_key)) + error_message = "The SumoLogic access key must contain valid characters." + } +} + +variable "installation_apps_list" { + description = "List of Sumo Logic apps to be installed. Each app can have custom parameters specific to that app." + type = list(object({ + uuid = string + name = string + version = string + parameters = optional(map(string), {}) + })) + default = [] + + validation { + condition = length(var.installation_apps_list) == 0 || alltrue([ + for app in var.installation_apps_list : + can(regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", app.uuid)) + ]) + error_message = "All UUIDs must be in valid UUID format (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)." + } + + validation { + condition = length(var.installation_apps_list) == 0 || alltrue([ + for app in var.installation_apps_list : + length(app.name) > 0 && length(app.name) <= 100 + ]) + error_message = "App names must not be empty and must be 100 characters or less." + } + + validation { + condition = length(var.installation_apps_list) == 0 || alltrue([ + for app in var.installation_apps_list : + app.version == "latest" || can(regex("^[0-9]+\\.[0-9]+\\.[0-9]+$", app.version)) + ]) + error_message = "App versions must be either 'latest' or in semantic version format (x.y.z)." + } + + validation { + condition = length(var.installation_apps_list) == 0 || alltrue([ + for app in var.installation_apps_list : + alltrue([ + for key, value in app.parameters : + length(key) > 0 && length(key) <= 128 && length(value) <= 1024 + ]) + ]) + error_message = "Parameter keys must be between 1-128 characters and values must be 1024 characters or less." + } +} diff --git a/aws-observability-v2-terraform/app-modules/versions.tf b/aws-observability-v2-terraform/app-modules/versions.tf new file mode 100644 index 00000000..4caedef6 --- /dev/null +++ b/aws-observability-v2-terraform/app-modules/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.5.7" + + required_providers { + sumologic = { + version = ">= 3.1.5" + source = "SumoLogic/sumologic" + } + } +}