diff --git a/icons/grafana-loki.svg b/icons/grafana-loki.svg new file mode 100644 index 00000000..c6fb2653 --- /dev/null +++ b/icons/grafana-loki.svg @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Layer 1 + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/modules/loki/s3_standard/1.0/README.md b/modules/loki/s3_standard/1.0/README.md new file mode 100644 index 00000000..e69de29b diff --git a/modules/loki/s3_standard/1.0/facets.yaml b/modules/loki/s3_standard/1.0/facets.yaml new file mode 100644 index 00000000..723b67b7 --- /dev/null +++ b/modules/loki/s3_standard/1.0/facets.yaml @@ -0,0 +1,409 @@ +clouds: + - aws +intentDetails: + type: Monitoring & Observability + description: Deploys Loki distributed log aggregation system with S3 backend and Promtail for log collection + displayName: Loki S3 + iconUrl: https://raw.githubusercontent.com/Facets-cloud/facets-modules-redesign/main/icons/loki_s3.svg +description: | + Deploys Loki (distributed mode) with S3 storage backend and Promtail for log scraping. + Loki is a horizontally scalable, highly available log aggregation system. + Promtail is deployed as a DaemonSet to collect and forward logs from all pods. + S3 bucket is created separately and linked via inputs. +flavor: s3_standard +inputs: + cloud_account: + description: AWS Cloud Account for IAM provisioning + displayName: Cloud Account + optional: false + providers: + - aws + type: '@facets/aws_cloud_account' + eks_details: + description: EKS cluster details for OIDC/IRSA configuration + displayName: EKS Cluster + optional: false + providers: + - helm + - kubernetes + - kubernetes-alpha + type: '@facets/eks' + s3_details: + description: S3 bucket for Loki log storage + displayName: S3 Bucket + optional: false + type: '@facets/s3' +intent: loki +outputs: + default: + title: Loki S3 Log Collector + type: '@facets/loki_s3' +sample: + disabled: false + flavor: s3_standard + kind: loki + spec: + loki_chart_version: "0.80.0" + promtail_chart_version: "6.16.6" + namespace: loki + retention_period: "744h" + version: "1.0" +spec: + description: Configure Loki distributed log aggregation with S3 backend + properties: + loki_chart_version: + default: "0.80.0" + description: Helm chart version for loki-distributed + title: Loki Chart Version + type: string + promtail_chart_version: + default: "6.16.6" + description: Helm chart version for Promtail + title: Promtail Chart Version + type: string + namespace: + default: loki + description: Kubernetes namespace for Loki and Promtail deployment + title: Namespace + type: string + retention_period: + default: "744h" + description: Log retention period (e.g., 744h for 31 days) + title: Retention Period + type: string + loki_size: + description: Resource sizing for Loki components + properties: + distributor: + description: Distributor component resources + properties: + replicas: + default: 1 + description: Number of distributor replicas + minimum: 1 + title: Replicas + type: integer + requests: + description: Resource requests + properties: + cpu: + default: "250m" + description: CPU request + title: CPU + type: string + memory: + default: "256Mi" + description: Memory request + title: Memory + type: string + title: Requests + type: object + x-ui-order: + - cpu + - memory + limits: + description: Resource limits + properties: + cpu: + default: "500m" + description: CPU limit + title: CPU + type: string + memory: + default: "512Mi" + description: Memory limit + title: Memory + type: string + title: Limits + type: object + x-ui-order: + - cpu + - memory + title: Distributor + type: object + x-ui-order: + - replicas + - requests + - limits + ingester: + description: Ingester component resources + properties: + replicas: + default: 1 + description: Number of ingester replicas + minimum: 1 + title: Replicas + type: integer + requests: + description: Resource requests + properties: + cpu: + default: "250m" + description: CPU request + title: CPU + type: string + memory: + default: "512Mi" + description: Memory request + title: Memory + type: string + title: Requests + type: object + x-ui-order: + - cpu + - memory + limits: + description: Resource limits + properties: + cpu: + default: "500m" + description: CPU limit + title: CPU + type: string + memory: + default: "1Gi" + description: Memory limit + title: Memory + type: string + title: Limits + type: object + x-ui-order: + - cpu + - memory + title: Ingester + type: object + x-ui-order: + - replicas + - requests + - limits + querier: + description: Querier component resources + properties: + replicas: + default: 1 + description: Number of querier replicas + minimum: 1 + title: Replicas + type: integer + requests: + description: Resource requests + properties: + cpu: + default: "250m" + description: CPU request + title: CPU + type: string + memory: + default: "256Mi" + description: Memory request + title: Memory + type: string + title: Requests + type: object + x-ui-order: + - cpu + - memory + limits: + description: Resource limits + properties: + cpu: + default: "500m" + description: CPU limit + title: CPU + type: string + memory: + default: "512Mi" + description: Memory limit + title: Memory + type: string + title: Limits + type: object + x-ui-order: + - cpu + - memory + title: Querier + type: object + x-ui-order: + - replicas + - requests + - limits + query_frontend: + description: Query frontend component resources + properties: + replicas: + default: 1 + description: Number of query frontend replicas + minimum: 1 + title: Replicas + type: integer + requests: + description: Resource requests + properties: + cpu: + default: "125m" + description: CPU request + title: CPU + type: string + memory: + default: "128Mi" + description: Memory request + title: Memory + type: string + title: Requests + type: object + x-ui-order: + - cpu + - memory + limits: + description: Resource limits + properties: + cpu: + default: "250m" + description: CPU limit + title: CPU + type: string + memory: + default: "256Mi" + description: Memory limit + title: Memory + type: string + title: Limits + type: object + x-ui-order: + - cpu + - memory + title: Query Frontend + type: object + x-ui-order: + - replicas + - requests + - limits + compactor: + description: Compactor component resources + properties: + requests: + description: Resource requests + properties: + cpu: + default: "100m" + description: CPU request + title: CPU + type: string + memory: + default: "256Mi" + description: Memory request + title: Memory + type: string + title: Requests + type: object + x-ui-order: + - cpu + - memory + limits: + description: Resource limits + properties: + cpu: + default: "250m" + description: CPU limit + title: CPU + type: string + memory: + default: "512Mi" + description: Memory limit + title: Memory + type: string + title: Limits + type: object + x-ui-order: + - cpu + - memory + title: Compactor + type: object + x-ui-order: + - requests + - limits + title: Loki Component Sizing + type: object + x-ui-order: + - distributor + - ingester + - querier + - query_frontend + - compactor + x-ui-toggle: true + promtail_size: + description: Resource sizing for Promtail DaemonSet + properties: + requests: + description: Resource requests for Promtail pods + properties: + cpu: + default: "100m" + description: CPU request + title: CPU + type: string + memory: + default: "128Mi" + description: Memory request + title: Memory + type: string + title: Requests + type: object + x-ui-order: + - cpu + - memory + limits: + description: Resource limits for Promtail pods + properties: + cpu: + default: "200m" + description: CPU limit + title: CPU + type: string + memory: + default: "256Mi" + description: Memory limit + title: Memory + type: string + title: Limits + type: object + x-ui-order: + - cpu + - memory + title: Promtail Sizing + type: object + x-ui-order: + - requests + - limits + x-ui-toggle: true + query_timeout: + default: 60 + description: Query timeout in seconds + minimum: 10 + title: Query Timeout + type: integer + loki_custom_values: + default: {} + description: Additional Helm values for loki-distributed chart (merged last, highest priority) + title: Loki Custom Values + type: object + x-ui-yaml-editor: true + promtail_custom_values: + default: {} + description: Additional Helm values for Promtail chart (merged last, highest priority) + title: Promtail Custom Values + type: object + x-ui-yaml-editor: true + title: Loki S3 Configuration + type: object + x-ui-order: + - loki_chart_version + - promtail_chart_version + - namespace + - retention_period + - query_timeout + - loki_size + - promtail_size + - loki_custom_values + - promtail_custom_values +version: "1.0" diff --git a/modules/loki/s3_standard/1.0/locals.tf b/modules/loki/s3_standard/1.0/locals.tf new file mode 100644 index 00000000..e8aad6ae --- /dev/null +++ b/modules/loki/s3_standard/1.0/locals.tf @@ -0,0 +1,55 @@ +locals { + # Naming + sa_name = "${var.environment.unique_name}-${lower(var.instance_name)}-loki" + namespace = lookup(var.instance.spec, "namespace", "loki") + + # S3 details from input + bucket_name = var.inputs.s3_details.attributes.bucket_name + bucket_arn = var.inputs.s3_details.attributes.bucket_arn + aws_region = var.inputs.cloud_account.attributes.aws_region + + # EKS OIDC for IRSA + oidc_provider_arn = var.inputs.eks_details.attributes.oidc_provider_arn + oidc_provider = var.inputs.eks_details.attributes.oidc_provider + + # Spec extraction + retention_period = lookup(var.instance.spec, "retention_period", "744h") + query_timeout = lookup(var.instance.spec, "query_timeout", 60) + + # Loki component sizing + loki_size = lookup(var.instance.spec, "loki_size", {}) + distributor = lookup(local.loki_size, "distributor", {}) + distributor_requests = lookup(local.distributor, "requests", {}) + distributor_limits = lookup(local.distributor, "limits", {}) + ingester = lookup(local.loki_size, "ingester", {}) + ingester_requests = lookup(local.ingester, "requests", {}) + ingester_limits = lookup(local.ingester, "limits", {}) + querier = lookup(local.loki_size, "querier", {}) + querier_requests = lookup(local.querier, "requests", {}) + querier_limits = lookup(local.querier, "limits", {}) + compactor = lookup(local.loki_size, "compactor", {}) + compactor_requests = lookup(local.compactor, "requests", {}) + compactor_limits = lookup(local.compactor, "limits", {}) + query_frontend = lookup(local.loki_size, "query_frontend", {}) + query_frontend_requests = lookup(local.query_frontend, "requests", {}) + query_frontend_limits = lookup(local.query_frontend, "limits", {}) + + # Promtail sizing + promtail_size = lookup(var.instance.spec, "promtail_size", {}) + promtail_requests = lookup(local.promtail_size, "requests", {}) + promtail_limits = lookup(local.promtail_size, "limits", {}) + + # Custom values + loki_custom_values = lookup(var.instance.spec, "loki_custom_values", {}) + promtail_custom_values = lookup(var.instance.spec, "promtail_custom_values", {}) + + # Tags + instance_tags = merge( + var.environment.cloud_tags, + { + "facets:instance_name" = var.instance_name + "facets:environment" = var.environment.name + "facets:component" = "loki-s3" + } + ) +} diff --git a/modules/loki/s3_standard/1.0/main.tf b/modules/loki/s3_standard/1.0/main.tf new file mode 100644 index 00000000..84c628d9 --- /dev/null +++ b/modules/loki/s3_standard/1.0/main.tf @@ -0,0 +1,404 @@ +module "name" { + source = "github.com/Facets-cloud/facets-utility-modules//name" + environment = var.environment + limit = 48 + resource_name = var.instance_name + resource_type = "loki_s3" + globally_unique = true +} + +# ----------------------------------------------------------------------------- +# IRSA: IAM Role for Loki Service Account to access S3 +# ----------------------------------------------------------------------------- + +resource "aws_iam_role" "loki" { + name = "${module.name.name}-loki" + + assume_role_policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Effect = "Allow" + Principal = { + Federated = local.oidc_provider_arn + } + Action = "sts:AssumeRoleWithWebIdentity" + Condition = { + StringEquals = { + "${local.oidc_provider}:aud" = "sts.amazonaws.com" + "${local.oidc_provider}:sub" = "system:serviceaccount:${local.namespace}:${local.sa_name}" + } + } + } + ] + }) + + tags = local.instance_tags +} + +resource "aws_iam_policy" "loki_s3" { + name = "${module.name.name}-loki-s3" + description = "S3 read-write access for Loki log storage" + + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Effect = "Allow" + Action = [ + "s3:PutObject", + "s3:GetObject", + "s3:DeleteObject", + "s3:ListBucket", + "s3:GetBucketLocation", + "s3:ListBucketMultipartUploads", + "s3:ListMultipartUploadParts", + "s3:AbortMultipartUpload" + ] + Resource = [ + local.bucket_arn, + "${local.bucket_arn}/*" + ] + } + ] + }) + + tags = local.instance_tags +} + +resource "aws_iam_role_policy_attachment" "loki_s3" { + role = aws_iam_role.loki.name + policy_arn = aws_iam_policy.loki_s3.arn +} + +# ----------------------------------------------------------------------------- +# Kubernetes Namespace +# ----------------------------------------------------------------------------- + +resource "kubernetes_namespace_v1" "loki" { + count = local.namespace != "default" && local.namespace != "kube-system" ? 1 : 0 + + metadata { + name = local.namespace + labels = { + "app.kubernetes.io/managed-by" = "facets" + "facets.cloud/instance" = var.instance_name + } + } +} + +# ----------------------------------------------------------------------------- +# Loki Distributed Helm Release +# ----------------------------------------------------------------------------- + +resource "helm_release" "loki" { + name = "${var.instance_name}-loki" + repository = "https://grafana.github.io/helm-charts" + chart = "loki-distributed" + version = lookup(var.instance.spec, "loki_chart_version", "0.80.0") + namespace = local.namespace + create_namespace = false + cleanup_on_fail = true + wait = true + timeout = 600 + + values = [ + yamlencode({ + loki = { + structuredConfig = { + auth_enabled = false + + server = { + http_listen_port = 3100 + } + + ingester = { + chunk_idle_period = "1h" + max_chunk_age = "1h" + chunk_target_size = 1048576 + chunk_retain_period = "30s" + + lifecycler = { + ring = { + replication_factor = 1 + } + } + } + + schema_config = { + configs = [ + { + from = "2024-01-01" + store = "boltdb-shipper" + object_store = "s3" + schema = "v11" + index = { + prefix = "loki_index_" + period = "24h" + } + } + ] + } + + storage_config = { + aws = { + s3 = "s3://${local.aws_region}/${local.bucket_name}" + s3forcepathstyle = false + } + boltdb_shipper = { + shared_store = "s3" + cache_ttl = "48h" + } + } + + compactor = { + shared_store = "s3" + working_directory = "/var/loki/compactor" + compaction_interval = "5m" + retention_enabled = true + retention_delete_delay = "2h" + } + + limits_config = { + retention_period = local.retention_period + enforce_metric_name = false + reject_old_samples = true + reject_old_samples_max_age = "168h" + max_query_length = local.retention_period + volume_enabled = true + } + + query_range = { + align_queries_with_step = true + } + + frontend = { + max_outstanding_per_tenant = 2048 + compress_responses = true + } + } + } + + serviceAccount = { + create = true + name = local.sa_name + annotations = { + "eks.amazonaws.com/role-arn" = aws_iam_role.loki.arn + } + } + + distributor = { + replicas = lookup(local.distributor, "replicas", 1) + resources = { + requests = { + cpu = lookup(local.distributor_requests, "cpu", "250m") + memory = lookup(local.distributor_requests, "memory", "256Mi") + } + limits = { + cpu = lookup(local.distributor_limits, "cpu", "500m") + memory = lookup(local.distributor_limits, "memory", "512Mi") + } + } + } + + ingester = { + replicas = lookup(local.ingester, "replicas", 1) + resources = { + requests = { + cpu = lookup(local.ingester_requests, "cpu", "250m") + memory = lookup(local.ingester_requests, "memory", "512Mi") + } + limits = { + cpu = lookup(local.ingester_limits, "cpu", "500m") + memory = lookup(local.ingester_limits, "memory", "1Gi") + } + } + persistence = { + enabled = true + size = "10Gi" + } + } + + querier = { + replicas = lookup(local.querier, "replicas", 1) + resources = { + requests = { + cpu = lookup(local.querier_requests, "cpu", "250m") + memory = lookup(local.querier_requests, "memory", "256Mi") + } + limits = { + cpu = lookup(local.querier_limits, "cpu", "500m") + memory = lookup(local.querier_limits, "memory", "512Mi") + } + } + } + + queryFrontend = { + replicas = lookup(local.query_frontend, "replicas", 1) + resources = { + requests = { + cpu = lookup(local.query_frontend_requests, "cpu", "125m") + memory = lookup(local.query_frontend_requests, "memory", "128Mi") + } + limits = { + cpu = lookup(local.query_frontend_limits, "cpu", "250m") + memory = lookup(local.query_frontend_limits, "memory", "256Mi") + } + } + } + + compactor = { + enabled = true + resources = { + requests = { + cpu = lookup(local.compactor_requests, "cpu", "100m") + memory = lookup(local.compactor_requests, "memory", "256Mi") + } + limits = { + cpu = lookup(local.compactor_limits, "cpu", "250m") + memory = lookup(local.compactor_limits, "memory", "512Mi") + } + } + persistence = { + enabled = true + size = "10Gi" + } + } + + gateway = { + enabled = true + replicas = 1 + } + }) + , yamlencode(local.loki_custom_values) + ] + + depends_on = [ + kubernetes_namespace_v1.loki, + aws_iam_role_policy_attachment.loki_s3 + ] +} + +# ----------------------------------------------------------------------------- +# Promtail Helm Release +# ----------------------------------------------------------------------------- + +resource "helm_release" "promtail" { + name = "${var.instance_name}-promtail" + repository = "https://grafana.github.io/helm-charts" + chart = "promtail" + version = lookup(var.instance.spec, "promtail_chart_version", "6.16.6") + namespace = local.namespace + create_namespace = false + cleanup_on_fail = true + wait = true + timeout = 600 + + values = [ + yamlencode({ + config = { + clients = [ + { + url = "http://${var.instance_name}-loki-loki-distributed-gateway.${local.namespace}.svc.cluster.local/loki/api/v1/push" + } + ] + + snippets = { + scrapeConfigs = <<-SCRAPECONFIG + - job_name: kubernetes-pods + pipeline_stages: + - cri: {} + kubernetes_sd_configs: + - role: pod + relabel_configs: + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] + action: drop + regex: 'false' + - source_labels: [__meta_kubernetes_pod_label_name] + target_label: __service__ + - source_labels: [__meta_kubernetes_pod_node_name] + target_label: __host__ + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - action: replace + replacement: $1 + separator: / + source_labels: + - __meta_kubernetes_namespace + - __service__ + target_label: job + - action: replace + source_labels: + - __meta_kubernetes_namespace + target_label: namespace + - action: replace + source_labels: + - __meta_kubernetes_pod_name + target_label: pod + - action: replace + source_labels: + - __meta_kubernetes_pod_container_name + target_label: container + - replacement: /var/log/pods/*$1/*.log + separator: / + source_labels: + - __meta_kubernetes_pod_uid + - __meta_kubernetes_pod_container_name + target_label: __path__ + SCRAPECONFIG + } + } + + resources = { + requests = { + cpu = lookup(local.promtail_requests, "cpu", "100m") + memory = lookup(local.promtail_requests, "memory", "128Mi") + } + limits = { + cpu = lookup(local.promtail_limits, "cpu", "200m") + memory = lookup(local.promtail_limits, "memory", "256Mi") + } + } + }) + , yamlencode(local.promtail_custom_values) + ] + + depends_on = [ + helm_release.loki + ] +} + +# ----------------------------------------------------------------------------- +# Grafana Datasource ConfigMap (auto-discovered by Grafana sidecar) +# ----------------------------------------------------------------------------- + +resource "kubernetes_config_map_v1" "grafana_datasource" { + metadata { + name = "${var.instance_name}-loki-datasource" + namespace = "default" + labels = { + grafana_datasource = "1" + } + } + + data = { + "loki-datasource.yaml" = yamlencode({ + apiVersion = 1 + datasources = [ + { + name = "Loki" + type = "loki" + access = "proxy" + url = "http://${var.instance_name}-loki-loki-distributed-gateway.${local.namespace}.svc.cluster.local" + jsonData = { + maxLines = 1000 + } + } + ] + }) + } + + depends_on = [ + helm_release.loki + ] +} diff --git a/modules/loki/s3_standard/1.0/outputs.tf b/modules/loki/s3_standard/1.0/outputs.tf new file mode 100644 index 00000000..1b4b882f --- /dev/null +++ b/modules/loki/s3_standard/1.0/outputs.tf @@ -0,0 +1,17 @@ +locals { + output_attributes = { + loki_release_name = helm_release.loki.name + loki_namespace = helm_release.loki.namespace + loki_chart_version = helm_release.loki.version + loki_release_status = helm_release.loki.status + promtail_release_name = helm_release.promtail.name + promtail_chart_version = helm_release.promtail.version + promtail_release_status = helm_release.promtail.status + loki_gateway_url = "http://${var.instance_name}-loki-loki-distributed-gateway.${local.namespace}.svc.cluster.local" + loki_push_url = "http://${var.instance_name}-loki-loki-distributed-gateway.${local.namespace}.svc.cluster.local/loki/api/v1/push" + s3_bucket_name = local.bucket_name + iam_role_arn = aws_iam_role.loki.arn + } + + output_interfaces = {} +} diff --git a/modules/loki/s3_standard/1.0/variables.tf b/modules/loki/s3_standard/1.0/variables.tf new file mode 100644 index 00000000..8b26118c --- /dev/null +++ b/modules/loki/s3_standard/1.0/variables.tf @@ -0,0 +1,147 @@ +variable "instance" { + description = "Facets instance object containing spec and metadata" + type = object({ + kind = string + flavor = string + version = string + spec = object({ + loki_chart_version = optional(string, "0.80.0") + promtail_chart_version = optional(string, "6.16.6") + namespace = optional(string, "loki") + retention_period = optional(string, "744h") + loki_size = optional(object({ + distributor = optional(object({ + replicas = optional(number, 1) + requests = optional(object({ + cpu = optional(string, "250m") + memory = optional(string, "256Mi") + }), {}) + limits = optional(object({ + cpu = optional(string, "500m") + memory = optional(string, "512Mi") + }), {}) + }), {}) + ingester = optional(object({ + replicas = optional(number, 1) + requests = optional(object({ + cpu = optional(string, "250m") + memory = optional(string, "512Mi") + }), {}) + limits = optional(object({ + cpu = optional(string, "500m") + memory = optional(string, "1Gi") + }), {}) + }), {}) + querier = optional(object({ + replicas = optional(number, 1) + requests = optional(object({ + cpu = optional(string, "250m") + memory = optional(string, "256Mi") + }), {}) + limits = optional(object({ + cpu = optional(string, "500m") + memory = optional(string, "512Mi") + }), {}) + }), {}) + query_frontend = optional(object({ + replicas = optional(number, 1) + requests = optional(object({ + cpu = optional(string, "125m") + memory = optional(string, "128Mi") + }), {}) + limits = optional(object({ + cpu = optional(string, "250m") + memory = optional(string, "256Mi") + }), {}) + }), {}) + compactor = optional(object({ + requests = optional(object({ + cpu = optional(string, "100m") + memory = optional(string, "256Mi") + }), {}) + limits = optional(object({ + cpu = optional(string, "250m") + memory = optional(string, "512Mi") + }), {}) + }), {}) + }), {}) + promtail_size = optional(object({ + requests = optional(object({ + cpu = optional(string, "100m") + memory = optional(string, "128Mi") + }), {}) + limits = optional(object({ + cpu = optional(string, "200m") + memory = optional(string, "256Mi") + }), {}) + }), {}) + query_timeout = optional(number, 60) + loki_custom_values = optional(any, {}) + promtail_custom_values = optional(any, {}) + }) + }) +} + +variable "instance_name" { + description = "Unique architectural name from blueprint" + type = string +} + +variable "environment" { + description = "An object containing details about the environment" + type = object({ + name = string + unique_name = string + namespace = optional(string) + cloud_tags = optional(map(string), {}) + }) +} + +variable "inputs" { + description = "Input variables from dependencies" + type = object({ + cloud_account = object({ + attributes = object({ + aws_region = string + aws_iam_role = string + external_id = optional(string) + session_name = optional(string) + }) + }) + eks_details = object({ + attributes = object({ + cluster_endpoint = string + cluster_ca_certificate = string + cluster_name = string + cluster_version = optional(string) + cluster_arn = optional(string) + cluster_id = optional(string) + cluster_location = optional(string) + cluster_primary_security_group_id = optional(string) + cluster_security_group_id = optional(string) + oidc_issuer_url = string + oidc_provider = string + oidc_provider_arn = string + node_iam_role_arn = optional(string) + node_iam_role_name = optional(string) + node_security_group_id = optional(string) + kubernetes_provider_exec = optional(object({ + api_version = string + command = string + args = list(string) + })) + }) + }) + s3_details = object({ + attributes = object({ + bucket_name = string + bucket_arn = string + region = string + bucket_domain_name = optional(string) + bucket_regional_domain_name = optional(string) + read_only_iam_policy_arn = optional(string) + read_write_iam_policy_arn = optional(string) + }) + }) + }) +} diff --git a/outputs/loki_s3/outputs.yaml b/outputs/loki_s3/outputs.yaml new file mode 100644 index 00000000..7808ef7b --- /dev/null +++ b/outputs/loki_s3/outputs.yaml @@ -0,0 +1,44 @@ +name: '@facets/loki_s3' +properties: + type: object + properties: + attributes: + type: object + properties: + loki_release_name: + description: Loki Helm release name + type: string + loki_namespace: + description: Kubernetes namespace where Loki is deployed + type: string + loki_chart_version: + description: Loki Helm chart version + type: string + loki_release_status: + description: Loki Helm release status + type: string + promtail_release_name: + description: Promtail Helm release name + type: string + promtail_chart_version: + description: Promtail Helm chart version + type: string + promtail_release_status: + description: Promtail Helm release status + type: string + loki_gateway_url: + description: Loki gateway URL for internal access + type: string + loki_push_url: + description: Loki push API endpoint for log ingestion + type: string + s3_bucket_name: + description: S3 bucket name used for log storage + type: string + iam_role_arn: + description: IAM role ARN used by Loki for S3 access + type: string + interfaces: + type: object + properties: {} +providers: [] diff --git a/project-type/aws/project-type.yml b/project-type/aws/project-type.yml index a9f35545..0ec1f13e 100644 --- a/project-type/aws/project-type.yml +++ b/project-type/aws/project-type.yml @@ -40,6 +40,8 @@ modules: flavor: standard - intent: aws_secret_manager flavor: standard + - intent: loki + flavor: s3_standard # === AWS Messaging & Storage Modules === - intent: s3