diff --git a/README.md b/README.md index c07eedf..d5d8943 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # Kubernetes logging by Loki stack (Loki+Promtail) -Terraform module for logging your kubernetes cluster resources. +Terraform module for deploy Loki logging to your kubernetes cluster, with multi cloud storage support. ## Wokrflow Module creates all necessary resources for logging important containers inside your kubernetes cluster. Previously you need to have Grafana to see your logs. Loki is only separate Data Source for Grafana. -Module supports logging to AWS s3 bucket, GCP storage, Azure blob storage and Kubernetes Persistent Volume. +Module supports different storages for logs: AWS S3 bucket, GCP GCS Bucket, Azure Blob storage and Kubernetes Persistent Volume. ## Software Requirements @@ -16,92 +16,71 @@ Helm provider | >= 2.1.0 Kubernetes provider | >= v2.0.1 ## Usage +#### AWS with S3 as storage ``` -# AWS s3 Loki Logging module "aws_s3_loki_stack" { source = "terraform-iaac/loki-stack/kubernetes" - loki_node_selector = { - (local.node_spot_label_key) = false - (local.node_multi_az_label_key) = true - } - - # In case if IRSA is enabled + # In case if IRSA is enabled. IRSA must have S3 RW Policy access. + # Otherwise, your instance must have S3 RW Policy attached. loki_service_account_annotations = { "eks.amazonaws.com/role-arn" = "arn:aws:iam::123456789:role/loki-logging" } - - loki_resources = { - request_cpu = "50m" - request_memory = "100Mi" - } provider_type = "aws" s3_name = "s3-bucket-loki-logs" s3_region = "us-east-1" } - -# Google Cloud Storage Loki Logging +``` +#### GCP with GCS as storage +``` module "gcs_loki_stack" { source = "terraform-iaac/loki-stack/kubernetes" - - loki_node_selector = { - (local.node_spot_label_key) = false - (local.node_multi_az_label_key) = true - } # In case if Workload Identity is enabled. + # Otherwise, your node must have RW permissions to GCS. loki_service_account_annotations = { "iam.gke.io/gcp-service-account" = "loki-sa@projectid.iam.gserviceaccount.com" } - - promtail_resources = { - request_cpu = "20m" - request_memory = "50Mi" - } provider_type = "gcp" - gcs_bucket_name = "k8s-logging" + gcs_bucket_name = "gcs-bucket-loki-logs" } - -# Azure Loki Logging +``` +#### Azure with Blob as storage +``` module "azure_loki_stack" { source = "terraform-iaac/loki-stack/kubernetes" - loki_node_selector = { - (local.node_spot_label_key) = false - (local.node_multi_az_label_key) = true - } - provider_type = "azure" storage_account_name = "kuberneteslogging" storage_account_access_key = "super-secret-key" + container_name = "logs" } +``` -# Local Loki Logging -module "local_loki_stack" { - source = "terraform-iaac/loki-stack/kubernetes" - - loki_node_selector = { - (local.node_spot_label_key) = false - (local.node_multi_az_label_key) = true - } +#### PV local as storage +``` +module "pv_local_loki_stack" { + source = "terraform-iaac/loki-stack/kubernetes" provider_type = "local" - persistent_volume_name = kubernetes_persistent_volume.test.metadata.0.name - persistent_volume_size = "4Gi" // We recommend to use a bit smaller value than Persistent Volume have (example: current_PV*0.9) + pvc_storage_class_name = "default" + pvc_access_modes = ["ReadWriteOnce"] + persistent_volume_name = kubernetes_persistent_volume.pv_loki.metadata.0.name + persistent_volume_size = "4Gi" } ``` -### Note: ***provider_type*** support only ***aws, azure, gcp or local*** value. Every value require own variables (see ***locals*** section in varaibles.tf file) +### Note: ***provider_type*** supports only ***aws, azure, gcp or local*** value. Every value require own variables (see ***locals*** section in varaibles.tf file or check examples.) ## Inputs -Name | Description | Type | Default | Example | Required ---- | --- |----------| --- |--- |--- -namespace | Name of namespace where you want to deploy loki-stack | `string` | `monitoring` | n/a | no -create_namespace | Create namespace by module? true or false | `bool` | true | n/a | no -loki_resources | Compute Resources required by loki container. CPU/RAM requests | `map` | `{}` |
{| no -promtail_resources | Compute Resources required by promtail container. CPU/RAM requests | `map` | `{}` |
request_cpu = "20m"
request_memory = "50Mi"
}
{| no +Name | Description | Type | Default | Example | Required +--- | --- |----------|-------------------------------------------------------------------------------|--- |--- +namespace | Name of namespace where you want to deploy loki-stack | `string` | `monitoring` | n/a | no +create_namespace | Create namespace by module? true or false | `bool` | true | n/a | no +loki_resources | Compute Resources required by loki container. CPU/RAM requests | `map` |
request_cpu = "20m"
request_memory = "50Mi"
}
{|
request_cpu = "50m"
request_memory = "100Mi"
}
{| no +promtail_resources | Compute Resources required by promtail container. CPU/RAM requests | `map` |
request_cpu = "20m"
request_memory = "50Mi"
}
{|
request_cpu = "20m"
request_memory = "50Mi"
}
{| no ### Loki variables Name | Description | Type | Default | Example | Required @@ -125,7 +104,7 @@ Name | Description | Type | Default | Example | Required --- | --- | --- | --- |--- |--- provider_type | Choose what type of provider you want (aws, azure, gcp and local) | `string` | n/a | `azure` | yes -### ***AWS s3*** +### ***AWS S3*** Name | Description | Type | Default | Example | Required --- | --- | --- | --- |--- |--- s3_region | AWS region where s3 locate | `string` | `null` | `us-east-1` | no diff --git a/example/aws.tf b/example/aws.tf new file mode 100644 index 0000000..38b23f0 --- /dev/null +++ b/example/aws.tf @@ -0,0 +1,14 @@ +# AWS S3 Loki Logging +module "aws_s3_loki_stack" { + source = "terraform-iaac/loki-stack/kubernetes" + + # In case if IRSA is enabled. IRSA must have S3 RW Policy access. + # Otherwise, your instance must have S3 RW Policy attached. + loki_service_account_annotations = { + "eks.amazonaws.com/role-arn" = "arn:aws:iam::123456789:role/loki-logging" + } + + provider_type = "aws" + s3_name = "s3-bucket-loki-logs" + s3_region = "us-east-1" +} \ No newline at end of file diff --git a/example/azure.tf b/example/azure.tf new file mode 100644 index 0000000..4c21cda --- /dev/null +++ b/example/azure.tf @@ -0,0 +1,8 @@ +module "azure_loki_stack" { + source = "terraform-iaac/loki-stack/kubernetes" + + provider_type = "azure" + storage_account_name = "kuberneteslogging" + storage_account_access_key = "super-secret-key" + container_name = "logs" +} \ No newline at end of file diff --git a/example/example.tf b/example/example.tf deleted file mode 100644 index 9a6916e..0000000 --- a/example/example.tf +++ /dev/null @@ -1,95 +0,0 @@ -locals { - node_spot_label_key = "spot" - node_multi_az_label_key = "multi_az" -} - -# AWS s3 Loki Logging -module "aws_s3_loki_stack" { - source = "terraform-iaac/loki-stack/kubernetes" - - loki_node_selector = { - (local.node_spot_label_key) = false - (local.node_multi_az_label_key) = true - } - - loki_service_account_annotations = { - "eks.amazonaws.com/role-arn" = "arn:aws:iam::123456789:role/loki-logging" - } - - provider_type = "aws" - s3_name = "loki-logs" - s3_region = "us-east-1" -} - -# Google Cloud Storage Loki Logging -# Create GCP Service Account for LOKI -resource "google_service_account" "loki" { - account_id = "loki" - display_name = "Loki logs bucket" - description = "SA for loki to access logs bucket" -} - -# Assign permission to service account -resource "google_storage_bucket_access_control" "loki" { - bucket = "loki-bucket-name" - role = "WRITER" - entity = "user-${google_service_account.loki.email}" -} -resource "google_storage_bucket_iam_member" "loki" { - bucket = "loki-bucket-name" - role = "roles/storage.objectAdmin" - member = "serviceAccount:${google_service_account.loki.email}" -} -resource "google_service_account_iam_binding" "loki_workload_identity" { - service_account_id = google_service_account.loki.name - - role = "roles/iam.workloadIdentityUser" - - members = [ - "serviceAccount:${local.gke_workload_identity_pool}[${module.gcs_loki_stack.namespace}/${module.gcs_loki_stack.loki_service_account_name}]", - ] -} -module "gcs_loki_stack" { - source = "terraform-iaac/loki-stack/kubernetes" - - loki_service_account_annotations = { - "iam.gke.io/gcp-service-account" = google_service_account.loki.email - } - - loki_node_selector = { - (local.node_spot_label_key) = false - (local.node_multi_az_label_key) = true - } - - provider_type = "gcp" - gcs_bucket_name = "k8s-logging" -} - -# Azure Loki Logging -module "azure_loki_stack" { - source = "terraform-iaac/loki-stack/kubernetes" - - loki_node_selector = { - (local.node_spot_label_key) = false - (local.node_multi_az_label_key) = true - } - - provider_type = "azure" - storage_account_name = "kuberneteslogging" - storage_account_access_key = "super-secret-key" - container_name = "logs" -} - -# Local Loki Logging -module "local_loki_stack" { - source = "git::https://github.com/terraform-iaac/terraform-kubernetes-loki-stack.git" - - loki_node_selector = { - (local.node_spot_label_key) = false - (local.node_multi_az_label_key) = true - } - - provider_type = "local" - persistent_volume_name = kubernetes_persistent_volume.test.metadata.0.name - persistent_volume_size = "4Gi" // We recommend to use a bit smaller value than Persistent Volume have (example: current_PV*0.9) -} diff --git a/example/gcp.tf b/example/gcp.tf new file mode 100644 index 0000000..797b3ea --- /dev/null +++ b/example/gcp.tf @@ -0,0 +1,41 @@ +# Google Cloud Storage Loki Logging +# Create GCP Service Account for LOKI +resource "google_service_account" "loki" { + account_id = "loki" + display_name = "Loki Logging" + description = "SA for Loki Logging with GCS Access" +} + +# Assign permission to service account +resource "google_storage_bucket_access_control" "loki" { + bucket = "gcs-bucket-loki-logs" + role = "WRITER" + entity = "user-${google_service_account.loki.email}" +} +resource "google_storage_bucket_iam_member" "loki" { + bucket = "gcs-bucket-loki-logs" + role = "roles/storage.objectAdmin" + member = "serviceAccount:${google_service_account.loki.email}" +} +resource "google_service_account_iam_binding" "loki_workload_identity" { + service_account_id = google_service_account.loki.name + + role = "roles/iam.workloadIdentityUser" + + members = [ + "serviceAccount:${var.gke_workload_identity_pool}[${module.gcs_loki_stack.namespace}/${module.gcs_loki_stack.loki_service_account_name}]", + ] +} + +module "gcs_loki_stack" { + source = "terraform-iaac/loki-stack/kubernetes" + + # In case if Workload Identity is enabled. + # Otherwise, your node must have RW permissions to GCS. + loki_service_account_annotations = { + "iam.gke.io/gcp-service-account" = google_service_account.loki.email + } + + provider_type = "gcp" + gcs_bucket_name = "gcs-bucket-loki-logs" +} \ No newline at end of file diff --git a/example/pv_local.tf b/example/pv_local.tf new file mode 100644 index 0000000..cfb4b8f --- /dev/null +++ b/example/pv_local.tf @@ -0,0 +1,27 @@ +resource "kubernetes_persistent_volume" "pv_loki" { + metadata { + name = "loki-pv" + } + spec { + access_modes = ["ReadWriteOnce"] + capacity = { + storage = "4Gi" + } + storage_class_name = "default" + persistent_volume_reclaim_policy = "Retain" + persistent_volume_source { + # ... + } + } +} + +# PV Local Loki Logging +module "pv_local_loki_stack" { + source = "terraform-iaac/loki-stack/kubernetes" + + provider_type = "local" + pvc_storage_class_name = "default" + pvc_access_modes = ["ReadWriteOnce"] + persistent_volume_name = kubernetes_persistent_volume.pv_loki.metadata.0.name + persistent_volume_size = "4Gi" +} diff --git a/promtail.tf b/promtail.tf index c1138c5..ca242dc 100644 --- a/promtail.tf +++ b/promtail.tf @@ -31,8 +31,8 @@ module "promtail_daemonset" { resources = var.promtail_resources env_field = { - "HOSTNAME" = "spec.nodeName" - } + "HOSTNAME" = "spec.nodeName" + } internal_port = var.promtail_internal_port security_context = [ diff --git a/variables.tf b/variables.tf index 22c034c..955bca9 100644 --- a/variables.tf +++ b/variables.tf @@ -1,11 +1,33 @@ # Resources for services variable "loki_resources" { description = "(Optional) Compute Resources required by loki container. CPU/RAM requests" - default = {} + type = object( + { + request_cpu = optional(string) + request_memory = optional(string) + limit_cpu = optional(string) + limit_memory = optional(string) + } + ) + default = { + request_cpu = "50m" + request_memory = "100Mi" + } } variable "promtail_resources" { description = "(Optional) Compute Resources required by promtail container. CPU/RAM requests" - default = {} + type = object( + { + request_cpu = optional(string) + request_memory = optional(string) + limit_cpu = optional(string) + limit_memory = optional(string) + } + ) + default = { + request_cpu = "20m" + request_memory = "50Mi" + } } # Namespace @@ -22,12 +44,15 @@ variable "create_namespace" { # Loki variable "loki_name" { + type = string default = "loki" } variable "loki_docker_image" { - default = "grafana/loki:2.7.1" + type = string + default = "grafana/loki:2.7.4" } variable "loki_termination_grace_period_seconds" { + type = number default = 4800 } variable "loki_port" { @@ -48,10 +73,12 @@ variable "loki_service_account_annotations" { # Promtail variable "promtail_name" { + type = string default = "promtail" } variable "promtail_docker_image" { - default = "grafana/promtail:2.7.1" + type = string + default = "grafana/promtail:2.7.4" } variable "promtail_internal_port" { @@ -71,49 +98,60 @@ variable "provider_type" { # Storage variables ## AWS variable "s3_region" { + type = string description = "AWS region where s3 locate" default = null } variable "s3_name" { + type = string description = "Name of s3 bucket" default = null } ## GCP variable "gcs_bucket_name" { + type = string description = "Google Cloud Storage bucket name" default = null } ## Azure variable "storage_account_name" { + type = string description = "The Microsoft Azure storage account name to be used" default = null } variable "storage_account_access_key" { + type = string description = "The Microsoft Azure storage account access key to use" default = null } variable "container_name" { + type = string description = "Name of the blob container used to store chunks. This container must be created before running cortex." default = null } ## Local storage variable "persistent_volume_name" { + type = string description = "Name of persistant volume" default = null } variable "persistent_volume_size" { + type = string description = "Name of persistant disk size" default = null } variable "pvc_access_modes" { + type = list(string) description = "Mode for access to data" default = null } variable "pvc_storage_class_name" { + type = string description = "Type of storage class name" default = null } variable "local_storage_retention_period" { + type = string description = "How far back tables will be kept before they are deleted. 0s disables deletion" default = "336h" } \ No newline at end of file
request_cpu = "20m"
request_memory = "50Mi"
}