{"id":1070,"date":"2025-04-06T01:36:20","date_gmt":"2025-04-06T01:36:20","guid":{"rendered":"https:\/\/techtrendfeed.com\/?p=1070"},"modified":"2025-04-06T01:36:20","modified_gmt":"2025-04-06T01:36:20","slug":"constructing-a-value-efficient-elk-stack-for-centralized-logging","status":"publish","type":"post","link":"https:\/\/techtrendfeed.com\/?p=1070","title":{"rendered":"Constructing a Value-Efficient ELK Stack for Centralized Logging"},"content":{"rendered":"<p> <br \/>\n<\/p>\n<div>\n<p data-end=\"27\" data-start=\"0\">If your organization has finances constraints, buying licensed merchandise like Splunk for logging infrastructure is probably not possible. Fortuitously, a robust open-source different exists: ELK (Elasticsearch, Logstash, and Kibana). ELK gives strong logging and visualization capabilities.<\/p>\n<p data-end=\"27\" data-start=\"0\">At a startup the place I labored, value minimization was a precedence, so I applied ELK for logging.<\/p>\n<p>\n On this article, I am going to information you thru organising and configuring the free model of the ELK stack on GCP utilizing Terraform and Ansible. Nevertheless, the identical directions might be adopted to deploy it on different cloud platforms like AWS and Azure.\n<\/p>\n<h2 data-en-clipboard=\"true\" data-pm-slice=\"1 1 []\" draggable=\"false\"><strong>Why Select ELK?<\/strong><\/h2>\n<p>After thorough analysis, I made a decision to implement the ELK stack on GCP utilizing digital machines (VMs) for logging as a result of its ease of use, wealthy dashboards, and easy setup course of. Whereas I might have deployed it on a GKE cluster, I opted for VMs on the time for numerous causes.<\/p>\n<p><a rel=\"nofollow\" target=\"_blank\" href=\"https:\/\/dzone.com\/articles\/introduction-to-elasticsearch-and-the-elk-stack\">Elasticsearch<\/a> is an open-source search and analytics engine that means that you can acquire and analyze logs from a number of sources, together with IoT gadgets, software servers, internet servers, and cloud providers. The ELK stack consists of the next parts:<\/p>\n<ul>\n<li draggable=\"false\">\n<p>\n   <strong>Elasticsearch<\/strong> \u2013 Shops and indexes log information\n  <\/p>\n<\/li>\n<li draggable=\"false\">\n<p>\n   <strong>Logstash<\/strong> \u2013 Filters and codecs logs earlier than ingestion\n  <\/p>\n<\/li>\n<li draggable=\"false\">\n<p>\n   <strong>Kibana<\/strong> \u2013 Gives a graphical person interface (GUI) for looking out and visualizing logs\n  <\/p>\n<\/li>\n<li draggable=\"false\">\n<div draggable=\"false\">\n   <strong>Filebeat<\/strong> \u2013 A light-weight log shipper put in as an agent on machines producing logs\n   <\/div>\n<\/li>\n<\/ul>\n<p><span class=\"fr-img-caption fr-fic fr-dib lazyloaded\" style=\"width: 618px;\"><span class=\"fr-img-wrap\"><img decoding=\"async\" data-image=\"true\" data-new=\"false\" data-sizeformatted=\"154.0 kB\" data-mimetype=\"image\/png\" data-creationdate=\"1742061968534\" data-creationdateformatted=\"03\/15\/2025 06:06 PM\" data-type=\"temp\" data-url=\"https:\/\/dz2cdn1.dzone.com\/storage\/temp\/18281867-elk-stack.png\" data-modificationdate=\"null\" data-size=\"153983\" data-name=\"elk-stack.png\" data-id=\"18281867\" src=\"https:\/\/dz2cdn1.dzone.com\/storage\/temp\/18281867-elk-stack.png\" alt=\"Figure 1\" class=\"lazyload\"\/><\/span><\/span><\/p><figcaption class=\"fr-inner\" contenteditable=\"true\">\n<p>\n  <em>Determine 1<\/em>\n <\/p>\n<\/figcaption><h2 data-en-clipboard=\"true\" data-pm-slice=\"1 1 []\" draggable=\"false\"><strong>Stipulations<\/strong><\/h2>\n<p data-en-clipboard=\"true\" data-pm-slice=\"1 1 []\" draggable=\"false\">Earlier than organising ELK, guarantee you will have the next:<\/p>\n<ul>\n<li draggable=\"false\">\n<p>\n   A cloud account (Google Cloud, AWS, or Azure). This information makes use of GCP.\n  <\/p>\n<\/li>\n<li draggable=\"false\">\n<p>\n   Terraform and Ansible put in in your native machine.\n  <\/p>\n<\/li>\n<li draggable=\"false\">\n<p>\n   Correct authentication configured between your native machine and the cloud supplier (Google Cloud or some other) with the required entry permissions for Terraform and Ansible.\n  <\/p>\n<\/li>\n<\/ul>\n<h2 data-en-clipboard=\"true\" data-pm-slice=\"1 1 []\" draggable=\"false\">Half 1: ELK Infrastructure Setup Utilizing Terraform on GCP<\/h2>\n<p>\n The ELK stack consists of varied nodes, every serving a selected operate to reinforce scalability and failover:\n<\/p>\n<ul>\n<li draggable=\"false\">\n<p>\n   <strong>Grasp nodes<\/strong> \u2013 Handle cluster operations and indexing.\n  <\/p>\n<\/li>\n<li draggable=\"false\">\n<p>\n   <strong>Information nodes<\/strong> \u2013 Retailer and index log information for search and evaluation.\n  <\/p>\n<\/li>\n<li draggable=\"false\">\n<p>\n   <strong>Kibana node<\/strong> \u2013 Gives a GUI for log visualization and analytics.\n  <\/p>\n<\/li>\n<li draggable=\"false\">\n<p>\n   <strong>Logstash node<\/strong> \u2013 Filters, transforms, and ingests logs from numerous sources.\n  <\/p>\n<\/li>\n<\/ul>\n<p>Whereas all functionalities might be mixed on a single node, separating them in a manufacturing atmosphere improves scalability and fault tolerance, relying on the workload.<\/p>\n<p>Create the next recordsdata in a folder the place you intend to run the Terraform code, or clone my Git repository, which comprises all of the code: <a rel=\"nofollow\" target=\"_blank\" data-end=\"212\" data-start=\"138\" href=\"https:\/\/github.com\/pradeep-gaddamidi\/ELK\" rel=\"noopener noreferrer\" target=\"_blank\">GitHub &#8211; pradeep-gaddamidi\/ELK<\/a>.<\/p>\n<h3 data-en-clipboard=\"true\" data-pm-slice=\"1 1 [&quot;ol&quot;,{&quot;style&quot;:null,&quot;start&quot;:null,&quot;backgroundColor&quot;:null,&quot;color&quot;:null,&quot;lineHeight&quot;:null,&quot;listStyleType&quot;:null},&quot;li&quot;,{&quot;style&quot;:null,&quot;checked&quot;:null,&quot;value&quot;:null,&quot;displayValue&quot;:1,&quot;backgroundColor&quot;:null,&quot;color&quot;:null,&quot;listStyleType&quot;:null,&quot;isCollapsed&quot;:null,&quot;draggable&quot;:false,&quot;alignmentReferenceFontSize&quot;:null}]\" draggable=\"false\"><strong>1. create_elk_instances.tf<\/strong><\/h3>\n<div class=\"codeMirror-wrapper\" contenteditable=\"false\">\n<div contenteditable=\"false\">\n<div class=\"codeMirror-code--wrapper\" data-code=\"locals {&#10;  config = var.environment_config[terraform.workspace]&#10;  instances = [for key, value in local.config.nodes : {&#10;    name = key&#10;    machine_type = (&#10;      can(regex(&quot;master_.*&quot;, value)) ? local.config.master_machine_type :&#10;      can(regex(&quot;kibana_.*&quot;, value)) ? local.config.kibana_machine_type :&#10;      can(regex(&quot;logstash_.*&quot;, value)) ? local.config.logstash_machine_type :&#10;      local.config.node_machine_type&#10;    )&#10;    zone = (&#10;      can(regex(&quot;.*_zoneb&quot;, value)) ? local.config.region_zones[1] :&#10;      can(regex(&quot;.*_zonec&quot;, value)) ? local.config.region_zones[2] :&#10;      local.config.region_zones[0]&#10;    )&#10;    network_tags         = local.config.network_tags&#10;    ssh_keys      = local.config.ssh_keys&#10;    static_ip_name       = key           # Modify or leave null as needed&#10;    service_account_name = &quot;elastic&quot;     # Modify or leave null as needed&#10;    disk_name            = key           # Modify or leave null as needed&#10;    disk_type            = &quot;pd-standard&quot; # Modify as needed&#10;    disk_size = (&#10;      can(regex(&quot;master_.*&quot;, value)) ? local.config.master_disk_size :&#10;      can(regex(&quot;kibana_.*&quot;, value)) ? local.config.kibana_disk_size :&#10;      can(regex(&quot;logstash_.*&quot;, value)) ? local.config.logstash_disk_size :&#10;      local.config.node_disk_size&#10;    )&#10;    disk_zone = (&#10;      can(regex(&quot;.*_zoneb&quot;, value)) ? local.config.region_zones[1] :&#10;      can(regex(&quot;.*_zonec&quot;, value)) ? local.config.region_zones[2] :&#10;      local.config.region_zones[0]&#10;    )&#10;    disk_project = local.config.project_name&#10;  }]&#10;}&#10;&#10;module &quot;gcp_instance&quot; {&#10;  source                = &quot;..\/..\/modules\/gcp_custom_instance&quot;&#10;  gce_image             = local.config.gce_image&#10;  subnet                = local.config.subnet&#10;  region                = local.config.region  # Provide only when creating static IPS&#10;  instances             = local.instances&#10;  use_common_service_account = local.config.use_common_service_account # Provide only when creating a common service account accross all the instances&#10;}\" data-lang=\"application\/json\">\n<pre><code lang=\"application\/json\">locals {\n  config = var.environment_config[terraform.workspace]\n  cases = [for key, value in local.config.nodes : {\n    name = key\n    machine_type = (\n      can(regex(\"master_.*\", value)) ? local.config.master_machine_type :\n      can(regex(\"kibana_.*\", value)) ? local.config.kibana_machine_type :\n      can(regex(\"logstash_.*\", value)) ? local.config.logstash_machine_type :\n      local.config.node_machine_type\n    )\n    zone = (\n      can(regex(\".*_zoneb\", value)) ? local.config.region_zones[1] :\n      can(regex(\".*_zonec\", worth)) ? native.config.region_zones[2] :\n      native.config.region_zones[0]\n    )\n    network_tags         = native.config.network_tags\n    ssh_keys      = native.config.ssh_keys\n    static_ip_name       = key           # Modify or depart null as wanted\n    service_account_name = \"elastic\"     # Modify or depart null as wanted\n    disk_name            = key           # Modify or depart null as wanted\n    disk_type            = \"pd-standard\" # Modify as wanted\n    disk_size = (\n      can(regex(\"master_.*\", worth)) ? native.config.master_disk_size :\n      can(regex(\"kibana_.*\", worth)) ? native.config.kibana_disk_size :\n      can(regex(\"logstash_.*\", worth)) ? native.config.logstash_disk_size :\n      native.config.node_disk_size\n    )\n    disk_zone = (\n      can(regex(\".*_zoneb\", worth)) ? native.config.region_zones[1] :\n      can(regex(\".*_zonec\", worth)) ? native.config.region_zones[2] :\n      native.config.region_zones[0]\n    )\n    disk_project = native.config.project_name\n  }]\n}\n\nmodule \"gcp_instance\" {\n  supply                = \"..\/..\/modules\/gcp_custom_instance\"\n  gce_image             = native.config.gce_image\n  subnet                = native.config.subnet\n  area                = native.config.area  # Present solely when creating static IPS\n  cases             = native.cases\n  use_common_service_account = native.config.use_common_service_account # Present solely when creating a typical service account accross all of the cases\n}<\/code><\/pre>\n<\/p><\/div><\/div>\n<\/div>\n<h3 data-en-clipboard=\"true\" data-pm-slice=\"1 1 [&quot;ol&quot;,{&quot;style&quot;:null,&quot;start&quot;:&quot;2&quot;,&quot;backgroundColor&quot;:null,&quot;color&quot;:null,&quot;lineHeight&quot;:null,&quot;listStyleType&quot;:null},&quot;li&quot;,{&quot;style&quot;:null,&quot;checked&quot;:null,&quot;value&quot;:null,&quot;displayValue&quot;:&quot;2&quot;,&quot;backgroundColor&quot;:null,&quot;color&quot;:null,&quot;listStyleType&quot;:null,&quot;isCollapsed&quot;:null,&quot;draggable&quot;:false,&quot;alignmentReferenceFontSize&quot;:null}]\" draggable=\"false\"><strong>2. variables.tf\u00a0<\/strong><\/h3>\n<div class=\"codeMirror-wrapper\" contenteditable=\"false\">\n<div contenteditable=\"false\">\n<div class=\"codeMirror-code--wrapper\" data-code=\"variable &quot;environment_config&quot; {&#10;  description = &quot;Configuration per environment&quot;&#10;  type = map(object({&#10;    project_name         = string&#10;    region               = string&#10;    region_zones         = list(string)&#10;    master_machine_type  = string&#10;    node_machine_type    = string&#10;    kibana_machine_type  = string&#10;    logstash_machine_type= string&#10;    network_tags         = list(string)&#10;    network              = string&#10;    subnet               = string&#10;    gce_image            = string&#10;    ca_bucket_location   = string&#10;    backup_bucket        = string&#10;    master_disk_size     = number&#10;    node_disk_size       = number&#10;    kibana_disk_size     = number&#10;    logstash_disk_size   = number&#10;    use_common_service_account = bool&#10;    machine_access_scopes= list(string)&#10;    nodes                = map(string)&#10;    ssh_keys             = list(string)&#10;  }))&#10;  default = {&#10;    nonprod = {&#10;      project_name         = &quot;nonprod-infra-monitoring&quot;&#10;      region               = &quot;us-central1&quot;&#10;      region_zones         = [&quot;us-central1-a&quot;, &quot;us-central1-b&quot;]&#10;      master_machine_type  = &quot;n1-standard-2&quot;&#10;      node_machine_type    = &quot;n1-standard-2&quot;&#10;      kibana_machine_type  = &quot;n1-standard-2&quot;&#10;      logstash_machine_type= &quot;n1-standard-2&quot;&#10;      network_tags         = [&quot;elastic&quot;, &quot;nonprod&quot;]&#10;      network              = &quot;projects\/nonprod-networking\/global\/networks\/nonprod-vpc&quot;&#10;      subnet               = &quot;projects\/nonprod-networking\/regions\/us-central1\/subnetworks\/nonprod-sub01&quot;&#10;      gce_image            = &quot;debian-cloud\/debian-12&quot;&#10;      ca_bucket_location   = &quot;nonprod-elastic-certificates&quot;&#10;      backup_bucket        = &quot;nonprod-elastic-backup&quot;&#10;      master_disk_size     = 100&#10;      node_disk_size       = 510&#10;      kibana_disk_size     = 100&#10;      logstash_disk_size   = 100&#10;      use_common_service_account = true&#10;      machine_access_scopes = [&quot;cloud-platform&quot;]&#10;      ssh_keys              = []&#10;      nodes = {&#10;        &quot;nonprod-elastic-master-node1&quot; = &quot;master_zonea&quot;&#10;        &quot;nonprod-elastic-data-node1&quot;   = &quot;data_zonea&quot;&#10;        &quot;nonprod-elastic-data-node2&quot;   = &quot;data_zoneb&quot;&#10;        &quot;nonprod-elastic-kibana&quot;       = &quot;kibana_zonea&quot;&#10;        &quot;nonprod-elastic-logstash&quot;     = &quot;logstash_zonea&quot;&#10;      }&#10;    }&#10;    prod = {&#10;      project_name         = &quot;prod-infra-monitoring&quot;&#10;      region               = &quot;us-central1&quot;&#10;      region_zones         = [&quot;us-central1-a&quot;, &quot;us-central1-b&quot;, &quot;us-central1-c&quot;]&#10;      master_machine_type  = &quot;n2-standard-2&quot;&#10;      node_machine_type    = &quot;n2-highmem-4&quot;&#10;      kibana_machine_type  = &quot;n2-standard-2&quot;&#10;      logstash_machine_type= &quot;n2-standard-2&quot;&#10;      network_tags         = [&quot;elastic&quot;, &quot;prod&quot;]&#10;      network              = &quot;projects\/prod-networking\/global\/networks\/prod-vpc&quot;&#10;      subnet               = &quot;projects\/prod-networking\/regions\/us-central1\/subnetworks\/prod-sub01&quot;&#10;      gce_image            = &quot;debian-cloud\/debian-12&quot;&#10;      ca_bucket_location   = &quot;prod-elastic-certificates&quot;&#10;      backup_bucket        = &quot;prod-elastic-backup&quot;&#10;      master_disk_size     = 100&#10;      node_disk_size       = 3000&#10;      kibana_disk_size     = 100&#10;      logstash_disk_size   = 100&#10;      use_common_service_account = true&#10;      machine_access_scopes = [&quot;cloud-platform&quot;]&#10;      ssh_keys              = []&#10;      nodes = {&#10;        &quot;elastic-master-node1&quot; = &quot;master_zonea&quot;&#10;        &quot;elastic-master-node2&quot; = &quot;master_zoneb&quot;&#10;        &quot;elastic-master-node3&quot; = &quot;master_zonec&quot;&#10;        &quot;elastic-data-node1&quot;   = &quot;data_zonea&quot;&#10;        &quot;elastic-data-node2&quot;   = &quot;data_zonea&quot;&#10;        &quot;elastic-data-node3&quot;   = &quot;data_zoneb&quot;&#10;        &quot;elastic-data-node4&quot;   = &quot;data_zoneb&quot;&#10;        &quot;elastic-data-node5&quot;   = &quot;data_zonea&quot;&#10;        &quot;elastic-data-node6&quot;   = &quot;data_zoneb&quot;&#10;        &quot;elastic-kibana&quot;       = &quot;kibana_zonea&quot;&#10;        &quot;elastic-logstash&quot;     = &quot;logstash_zonea&quot;&#10;        &quot;elastic-logstash2&quot;     = &quot;logstash_zoneb&quot;&#10;        &quot;elastic-logstash3&quot;    = &quot;logstash_zonec&quot;&#10;      }&#10;    }&#10;  }&#10;}\" data-lang=\"application\/json\">\n<pre><code lang=\"application\/json\">variable \"environment_config\" {\n  description = \"Configuration per atmosphere\"\n  kind = map(object({\n    project_name         = string\n    area               = string\n    region_zones         = record(string)\n    master_machine_type  = string\n    node_machine_type    = string\n    kibana_machine_type  = string\n    logstash_machine_type= string\n    network_tags         = record(string)\n    community              = string\n    subnet               = string\n    gce_image            = string\n    ca_bucket_location   = string\n    backup_bucket        = string\n    master_disk_size     = quantity\n    node_disk_size       = quantity\n    kibana_disk_size     = quantity\n    logstash_disk_size   = quantity\n    use_common_service_account = bool\n    machine_access_scopes= record(string)\n    nodes                = map(string)\n    ssh_keys             = record(string)\n  }))\n  default = {\n    nonprod = {\n      project_name         = \"nonprod-infra-monitoring\"\n      area               = \"us-central1\"\n      region_zones         = [\"us-central1-a\", \"us-central1-b\"]\n      master_machine_type  = \"n1-standard-2\"\n      node_machine_type    = \"n1-standard-2\"\n      kibana_machine_type  = \"n1-standard-2\"\n      logstash_machine_type= \"n1-standard-2\"\n      network_tags         = [\"elastic\", \"nonprod\"]\n      community              = \"tasks\/nonprod-networking\/world\/networks\/nonprod-vpc\"\n      subnet               = \"tasks\/nonprod-networking\/areas\/us-central1\/subnetworks\/nonprod-sub01\"\n      gce_image            = \"debian-cloud\/debian-12\"\n      ca_bucket_location   = \"nonprod-elastic-certificates\"\n      backup_bucket        = \"nonprod-elastic-backup\"\n      master_disk_size     = 100\n      node_disk_size       = 510\n      kibana_disk_size     = 100\n      logstash_disk_size   = 100\n      use_common_service_account = true\n      machine_access_scopes = [\"cloud-platform\"]\n      ssh_keys              = []\n      nodes = {\n        \"nonprod-elastic-master-node1\" = \"master_zonea\"\n        \"nonprod-elastic-data-node1\"   = \"data_zonea\"\n        \"nonprod-elastic-data-node2\"   = \"data_zoneb\"\n        \"nonprod-elastic-kibana\"       = \"kibana_zonea\"\n        \"nonprod-elastic-logstash\"     = \"logstash_zonea\"\n      }\n    }\n    prod = {\n      project_name         = \"prod-infra-monitoring\"\n      area               = \"us-central1\"\n      region_zones         = [\"us-central1-a\", \"us-central1-b\", \"us-central1-c\"]\n      master_machine_type  = \"n2-standard-2\"\n      node_machine_type    = \"n2-highmem-4\"\n      kibana_machine_type  = \"n2-standard-2\"\n      logstash_machine_type= \"n2-standard-2\"\n      network_tags         = [\"elastic\", \"prod\"]\n      community              = \"tasks\/prod-networking\/world\/networks\/prod-vpc\"\n      subnet               = \"tasks\/prod-networking\/areas\/us-central1\/subnetworks\/prod-sub01\"\n      gce_image            = \"debian-cloud\/debian-12\"\n      ca_bucket_location   = \"prod-elastic-certificates\"\n      backup_bucket        = \"prod-elastic-backup\"\n      master_disk_size     = 100\n      node_disk_size       = 3000\n      kibana_disk_size     = 100\n      logstash_disk_size   = 100\n      use_common_service_account = true\n      machine_access_scopes = [\"cloud-platform\"]\n      ssh_keys              = []\n      nodes = {\n        \"elastic-master-node1\" = \"master_zonea\"\n        \"elastic-master-node2\" = \"master_zoneb\"\n        \"elastic-master-node3\" = \"master_zonec\"\n        \"elastic-data-node1\"   = \"data_zonea\"\n        \"elastic-data-node2\"   = \"data_zonea\"\n        \"elastic-data-node3\"   = \"data_zoneb\"\n        \"elastic-data-node4\"   = \"data_zoneb\"\n        \"elastic-data-node5\"   = \"data_zonea\"\n        \"elastic-data-node6\"   = \"data_zoneb\"\n        \"elastic-kibana\"       = \"kibana_zonea\"\n        \"elastic-logstash\"     = \"logstash_zonea\"\n        \"elastic-logstash2\"     = \"logstash_zoneb\"\n        \"elastic-logstash3\"    = \"logstash_zonec\"\n      }\n    }\n  }\n}<\/code><\/pre>\n<\/p><\/div><\/div>\n<\/div>\n<p>\n <br \/>I&#8217;ve created a customized module to provision GCP cases and used it within the <code>create_elk_instances.tf<\/code> file. Nevertheless, you can too use GCP&#8217;s official Terraform module to create VM cases.\n<\/p>\n<div class=\"codeMirror-wrapper newest\" contenteditable=\"false\">\n<div contenteditable=\"false\">\n<div class=\"codeMirror-code--wrapper\" data-code=\"module &quot;gcp_instance&quot; {&#10;  source                = &quot;.\/modules\/gcp_custom_instance&quot;\" data-lang=\"application\/json\">\n<pre><code lang=\"application\/json\">module \"gcp_instance\" {\n \u00a0supply \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0= \".\/modules\/gcp_custom_instance\"<\/code><\/pre>\n<\/p><\/div><\/div>\n<\/div>\n<p>\n <br \/>The <code>.\/modules\/gcp_custom_instance<\/code> folder should have the recordsdata, <code>gcp_custom_vm.tf<\/code> and <code>variables_custom.tf<\/code>).\n<\/p>\n<p>\n <br \/>Under is the code for my customized module:\n<\/p>\n<h3 data-en-clipboard=\"true\" data-pm-slice=\"1 1 [&quot;ol&quot;,{&quot;style&quot;:null,&quot;start&quot;:&quot;3&quot;,&quot;backgroundColor&quot;:null,&quot;color&quot;:null,&quot;lineHeight&quot;:null,&quot;listStyleType&quot;:null},&quot;li&quot;,{&quot;style&quot;:null,&quot;checked&quot;:null,&quot;value&quot;:null,&quot;displayValue&quot;:&quot;3&quot;,&quot;backgroundColor&quot;:null,&quot;color&quot;:null,&quot;listStyleType&quot;:null,&quot;isCollapsed&quot;:null,&quot;draggable&quot;:false,&quot;alignmentReferenceFontSize&quot;:null}]\" draggable=\"false\"><strong>3. gcp_custom_vm.tf<\/strong><\/h3>\n<div class=\"codeMirror-wrapper newest\" contenteditable=\"false\">\n<div contenteditable=\"false\">\n<div class=\"codeMirror-code--wrapper\" data-code=\"locals {&#10;  common_service_account_email = var.use_common_service_account ? google_service_account.common_service_account[0].email : null&#10;}&#10;&#10;resource &quot;google_compute_instance&quot; &quot;google-compute-instance&quot; {&#10;  for_each = { for index, inst in var.instances : inst.name =&gt; inst }&#10;  name         = each.value.name&#10;  machine_type = each.value.machine_type&#10;  zone = each.value.zone&#10;#  allow_stopping_for_update = true&#10;  tags         = each.value.network_tags&#10;  metadata = {&#10;    ssh-keys = join(&quot;n&quot;, each.value.ssh_keys)&#10;  }&#10;&#10;  boot_disk {&#10;    initialize_params {&#10;      image = var.gce_image&#10;    }&#10;  }&#10;&#10;  network_interface {&#10;    subnetwork = var.subnet&#10;    network_ip = each.value.static_ip_name != null ? google_compute_address.static_ips[each.value.static_ip_name].address : null&#10;  }&#10;&#10;  dynamic &quot;service_account&quot; {&#10;    for_each = each.value.service_account_name != null ? [1] : []&#10;    content {&#10;      scopes = var.machine_access_scopes&#10;      email  = var.use_common_service_account ? google_service_account.common_service_account[0].email :               google_service_account.individual_service_account[each.value.name].email&#10;    }&#10;  }&#10;&#10;  dynamic &quot;attached_disk&quot; {&#10;    for_each = each.value.disk_name != null ? [1] : []&#10;    content {&#10;      source      = google_compute_disk.google-compute-disk[each.value.disk_name].self_link&#10;      device_name = &quot;${each.value.disk_name}-data&quot;&#10;      mode        = &quot;READ_WRITE&quot;&#10;    }&#10;  }&#10;&#10;}&#10;&#10;&#10;resource &quot;google_compute_disk&quot; &quot;google-compute-disk&quot; {&#10;  for_each = { for index, inst in var.instances : inst.disk_name =&gt; inst if inst.disk_name != null }&#10;&#10;  name = &quot;${each.value.disk_name}-data&quot;&#10;  type = each.value.disk_type&#10;  size = each.value.disk_size&#10;  zone = each.value.disk_zone&#10;  project = each.value.disk_project&#10;}&#10;&#10;resource &quot;google_service_account&quot; &quot;common_service_account&quot; {&#10;  count        = var.use_common_service_account ? 1 : 0&#10;  account_id   = var.use_common_service_account ? lookup(var.instances[0], &quot;service_account_name&quot;, null) : null&#10;  display_name = &quot;Service Account&quot;&#10;}&#10;&#10;resource &quot;google_service_account&quot; &quot;individual_service_account&quot; {&#10;  for_each     = { for index, inst in var.instances : inst.service_account_name =&gt; inst if inst.service_account_name != null &amp;&amp; !var.use_common_service_account }&#10;&#10;  account_id   = each.value.service_account_name&#10;  display_name = &quot;Service account for ${each.value.name}&quot;&#10;}&#10;&#10;resource &quot;google_compute_address&quot; &quot;static_ips&quot; {&#10;  # Only include instances that have static_ip_name defined&#10;  for_each = { for index, inst in var.instances : inst.static_ip_name =&gt; inst if inst.static_ip_name != null }&#10;&#10;  name         = each.value.static_ip_name&#10;  address_type = &quot;INTERNAL&quot;&#10;  region       = var.region&#10;  subnetwork   = var.subnet&#10;}&#10;&#10;output &quot;common_service_account_email&quot; {&#10;  value       = local.common_service_account_email&#10;  description = &quot;The email of the common service account&quot;&#10;}\" data-lang=\"application\/json\">\n<pre><code lang=\"application\/json\">locals {\n  common_service_account_email = var.use_common_service_account ? google_service_account.common_service_account[0].e mail : null\n}\n\nuseful resource \"google_compute_instance\" \"google-compute-instance\" {\n  for_each = { for index, inst in var.cases : inst.title =&gt; inst }\n  title         = every.worth.title\n  machine_type = every.worth.machine_type\n  zone = every.worth.zone\n#  allow_stopping_for_update = true\n  tags         = every.worth.network_tags\n  metadata = {\n    ssh-keys = be a part of(\"n\", every.worth.ssh_keys)\n  }\n\n  boot_disk {\n    initialize_params {\n      picture = var.gce_image\n    }\n  }\n\n  network_interface {\n    subnetwork = var.subnet\n    network_ip = every.worth.static_ip_name != null ? google_compute_address.static_ips[each.value.static_ip_name].handle : null\n  }\n\n  dynamic \"service_account\" {\n    for_each = every.worth.service_account_name != null ? [1] : []\n    content material {\n      scopes = var.machine_access_scopes\n      e mail  = var.use_common_service_account ? google_service_account.common_service_account[0].e mail :               google_service_account.individual_service_account[each.value.name].e mail\n    }\n  }\n\n  dynamic \"attached_disk\" {\n    for_each = every.worth.disk_name != null ? [1] : []\n    content material {\n      supply      = google_compute_disk.google-compute-disk[each.value.disk_name].self_link\n      device_name = \"${every.worth.disk_name}-data\"\n      mode        = \"READ_WRITE\"\n    }\n  }\n\n}\n\n\nuseful resource \"google_compute_disk\" \"google-compute-disk\" {\n  for_each = { for index, inst in var.cases : inst.disk_name =&gt; inst if inst.disk_name != null }\n\n  title = \"${every.worth.disk_name}-data\"\n  kind = every.worth.disk_type\n  measurement = every.worth.disk_size\n  zone = every.worth.disk_zone\n  undertaking = every.worth.disk_project\n}\n\nuseful resource \"google_service_account\" \"common_service_account\" {\n  depend        = var.use_common_service_account ? 1 : 0\n  account_id   = var.use_common_service_account ? lookup(var.cases[0], \"service_account_name\", null) : null\n  display_name = \"Service Account\"\n}\n\nuseful resource \"google_service_account\" \"individual_service_account\" {\n  for_each     = { for index, inst in var.cases : inst.service_account_name =&gt; inst if inst.service_account_name != null &amp;&amp; !var.use_common_service_account }\n\n  account_id   = every.worth.service_account_name\n  display_name = \"Service account for ${every.worth.title}\"\n}\n\nuseful resource \"google_compute_address\" \"static_ips\" {\n  # Solely embody cases which have static_ip_name outlined\n  for_each = { for index, inst in var.cases : inst.static_ip_name =&gt; inst if inst.static_ip_name != null }\n\n  title         = every.worth.static_ip_name\n  address_type = \"INTERNAL\"\n  area       = var.area\n  subnetwork   = var.subnet\n}\n\noutput \"common_service_account_email\" {\n  worth       = native.common_service_account_email\n  description = \"The e-mail of the widespread service account\"\n}<\/code><\/pre>\n<\/p><\/div><\/div>\n<\/div>\n<h3>4. <strong>variables_custom.tf<\/strong><\/h3>\n<div class=\"codeMirror-wrapper\" contenteditable=\"false\">\n<div contenteditable=\"false\">\n<div class=\"codeMirror-code--wrapper\" data-code=\"variable &quot;instances&quot; {&#10;  description = &quot;List of instance configurations&quot;&#10;  type = list(object({&#10;    name                = string&#10;    machine_type        = string&#10;    zone                = string&#10;    network_tags        = optional(list(string))&#10;    ssh_keys&#9;        = optional(list(string))&#10;    static_ip_name      = optional(string)&#10;    service_account_name = optional(string)&#10;    disk_name           = optional(string)&#10;    disk_type           = optional(string)&#10;    disk_size           = optional(number)&#10;    disk_zone           = optional(string)&#10;    disk_project        = optional(string)&#10;  }))&#10;}&#10;&#10;variable &quot;gce_image&quot; {&#10;  description = &quot;GCE image for the instances&quot;&#10;  type        = string&#10;  default     = &quot;debian-cloud\/debian-12&quot;&#10;}&#10;&#10;variable &quot;subnet&quot; {&#10;  description = &quot;Subnet for the network&quot;&#10;  type        = string&#10;}&#10;&#10;variable &quot;region&quot; {&#10;  description = &quot;GCP region&quot;&#10;  type        = string&#10;  default     = &quot;us-central1&quot;&#10;}&#10;&#10;variable &quot;use_common_service_account&quot; {&#10;  description = &quot;Flag to determine if a common service account should be used for all instances&quot;&#10;  type        = bool&#10;  default     = false&#10;}&#10;&#10;variable &quot;machine_access_scopes&quot; {&#10;  description = &quot;Scopes for machine access&quot;&#10;  type        = list(string)&#10;  default     = [&quot;cloud-platform&quot;]&#10;}\" data-lang=\"application\/json\">\n<pre><code lang=\"application\/json\">variable \"cases\" {\n  description = \"Listing of occasion configurations\"\n  kind = record(object({\n    title                = string\n    machine_type        = string\n    zone                = string\n    network_tags        = non-compulsory(record(string))\n    ssh_keys\t        = non-compulsory(record(string))\n    static_ip_name      = non-compulsory(string)\n    service_account_name = non-compulsory(string)\n    disk_name           = non-compulsory(string)\n    disk_type           = non-compulsory(string)\n    disk_size           = non-compulsory(quantity)\n    disk_zone           = non-compulsory(string)\n    disk_project        = non-compulsory(string)\n  }))\n}\n\nvariable \"gce_image\" {\n  description = \"GCE picture for the cases\"\n  kind        = string\n  default     = \"debian-cloud\/debian-12\"\n}\n\nvariable \"subnet\" {\n  description = \"Subnet for the community\"\n  kind        = string\n}\n\nvariable \"area\" {\n  description = \"GCP area\"\n  kind        = string\n  default     = \"us-central1\"\n}\n\nvariable \"use_common_service_account\" {\n  description = \"Flag to find out if a typical service account ought to be used for all cases\"\n  kind        = bool\n  default     = false\n}\n\nvariable \"machine_access_scopes\" {\n  description = \"Scopes for machine entry\"\n  kind        = record(string)\n  default     = [\"cloud-platform\"]\n}<\/code><\/pre>\n<\/p><\/div><\/div>\n<\/div>\n<p>\n <br \/>Assign permissions to the service accounts created earlier within the code:\n<\/p>\n<div class=\"codeMirror-wrapper\" contenteditable=\"false\">\n<div contenteditable=\"false\">\n<div class=\"codeMirror-code--wrapper\" data-code=\"locals {&#10;  bucket_config = var.environment_config[terraform.workspace]&#10;}&#10;&#10;resource &quot;google_storage_bucket_iam_binding&quot; &quot;elastic-backup&quot; {&#10;  bucket  = local.bucket_config.backup_bucket&#10;  role    = &quot;roles\/storage.objectAdmin&quot;&#10;  members = local.config.use_common_service_account ? [&quot;serviceAccount:${module.gcp_instance.common_service_account_email}&quot;] : []&#10;}&#10;&#10;resource &quot;google_storage_bucket_iam_binding&quot; &quot;elastic-certs&quot; {&#10;  bucket  = local.bucket_config.ca_bucket_location&#10;  role    = &quot;roles\/storage.objectViewer&quot;&#10;  members = local.config.use_common_service_account ? [&quot;serviceAccount:${module.gcp_instance.common_service_account_email}&quot;] : []&#10;}\" data-lang=\"application\/json\">\n<pre><code lang=\"application\/json\">locals {\n  bucket_config = var.environment_config[terraform.workspace]\n}\n\nuseful resource \"google_storage_bucket_iam_binding\" \"elastic-backup\" {\n  bucket  = native.bucket_config.backup_bucket\n  function    = \"roles\/storage.objectAdmin\"\n  members = native.config.use_common_service_account ? [\"serviceAccount:${module.gcp_instance.common_service_account_email}\"] : []\n}\n\nuseful resource \"google_storage_bucket_iam_binding\" \"elastic-certs\" {\n  bucket  = native.bucket_config.ca_bucket_location\n  function    = \"roles\/storage.objectViewer\"\n  members = native.config.use_common_service_account ? [\"serviceAccount:${module.gcp_instance.common_service_account_email}\"] : []\n}<\/code><\/pre>\n<\/p><\/div><\/div>\n<\/div>\n<p>\n <br \/>Create the GCP buckets used for certificates and elastic backups:\n<\/p>\n<div class=\"codeMirror-wrapper\" contenteditable=\"false\">\n<div contenteditable=\"false\">\n<div class=\"codeMirror-code--wrapper\" data-code=\"resource &quot;google_storage_bucket&quot; &quot;elastic-backup&quot; {&#10;  name          = local.bucket_config.backup_bucket&#10;  location      = &quot;US&quot;&#10;  storage_class = &quot;STANDARD&quot;&#10;&#10;  uniform_bucket_level_access = true&#10;}&#10;resource &quot;google_storage_bucket&quot; &quot;elastic-certs&quot; {&#10;  name          = local.bucket_config.ca_bucket_location&#10;  location      = &quot;US&quot;&#10;  storage_class = &quot;STANDARD&quot;&#10;&#10;  uniform_bucket_level_access = true&#10;}\" data-lang=\"application\/json\">\n<pre><code lang=\"application\/json\">useful resource \"google_storage_bucket\" \"elastic-backup\" {\n  title          = native.bucket_config.backup_bucket\n  location      = \"US\"\n  storage_class = \"STANDARD\"\n\n  uniform_bucket_level_access = true\n}\nuseful resource \"google_storage_bucket\" \"elastic-certs\" {\n  title          = native.bucket_config.ca_bucket_location\n  location      = \"US\"\n  storage_class = \"STANDARD\"\n\n  uniform_bucket_level_access = true\n}<\/code><\/pre>\n<\/p><\/div><\/div>\n<\/div>\n<p>\n \u00a0<br \/>\n <br \/>You should utilize the under Terraform instructions to create the above assets:\n<\/p>\n<div class=\"codeMirror-wrapper\" contenteditable=\"false\">\n<div contenteditable=\"false\">\n<div class=\"codeMirror-code--wrapper\" data-code=\"terraform workspace set nonprod (if you use workspaces)&#10;terraform init&#10;terraform plan&#10;terraform apply\" data-lang=\"application\/json\">\n<pre><code lang=\"application\/json\">terraform workspace set nonprod (in the event you use workspaces)\nterraform init\nterraform plan\nterraform apply<\/code><\/pre>\n<\/p><\/div><\/div>\n<\/div>\n<p>You possibly can add new nodes as wanted by updating variables, i.e., including new nodes to the nodes part of the file and re-running the Terraform code. It will provision the brand new information nodes robotically. Now that the ELK infrastructure is about up, the following step is to put in and configure the ELK software program.<\/p>\n<h2>Half 2: Configure the ELK Infrastructure Utilizing Ansible<\/h2>\n<h3><strong>Stipulations<\/strong><\/h3>\n<p>1. The certificates era required for safe communication between numerous Elastic nodes might be automated. Nevertheless, I selected to generate them manually by following the ELK guides.<\/p>\n<p>As soon as the certificates are generated, stage them on the GCP bucket <code>elastic-certificates<\/code>.<\/p>\n<p>2. Make certain your Ansible hosts recordsdata are organized as under:<\/p>\n<ul>\n<li draggable=\"false\">\n<p>\n   All information and grasp nodes are grouped beneath the <code>elastic<\/code> part\n  <\/p>\n<\/li>\n<li draggable=\"false\">\n<p>\n   Kibana nodes beneath <code>kibana<\/code> part\n  <\/p>\n<\/li>\n<li draggable=\"false\">\n<p>\n   Logstash nodes beneath <code>logstash<\/code>\n  <\/p>\n<\/li>\n<li draggable=\"false\">\n<p>\n   Information nodes beneath <code>information<\/code>\n  <\/p>\n<\/li>\n<li draggable=\"false\">\n<p>\n   Grasp nodes beneath <code>grasp<\/code>\n  <\/p>\n<\/li>\n<\/ul>\n<div data-message-author-role=\"assistant\" data-message-id=\"66f5ae86-3313-4e85-a610-573630a95509\" data-message-model-slug=\"gpt-4o\" dir=\"auto\">\n<p data-end=\"153\" data-is-last-node=\"\" data-is-only-node=\"\" data-start=\"0\">Create the next recordsdata in a folder the place you intend to run the Ansible playbook. Then, execute the Ansible playbook under to put in and configure ELK.<\/p>\n<\/div>\n<h4 data-en-clipboard=\"true\" data-pm-slice=\"1 1 []\" draggable=\"false\"><strong>ansible.yaml<\/strong><\/h4>\n<div class=\"codeMirror-wrapper newest\" contenteditable=\"false\">\n<div contenteditable=\"false\">\n<div class=\"codeMirror-code--wrapper\" data-code=\"---&#10;- name: Install Elasticsearch pre-reqs on Debian&#10;  hosts: all&#10;  become: yes&#10;  tasks:&#10;    - name: Update apt repository&#10;      apt:&#10;        update_cache: yes&#10;&#10;    - name: Install default-jre&#10;      apt:&#10;        name:&#10;          - default-jre&#10;        state: present&#10;&#10;    - name: Add Elasticsearch GPG key&#10;      apt_key:&#10;        url: https:\/\/artifacts.elastic.co\/GPG-KEY-elasticsearch&#10;        state: present&#10;&#10;    - name: Install apt-transport-https&#10;      apt:&#10;        name: apt-transport-https&#10;        state: present&#10;&#10;    - name: Add Elasticsearch repository&#10;      apt_repository:&#10;        repo: &quot;deb https:\/\/artifacts.elastic.co\/packages\/8.x\/apt stable main&quot;&#10;        state: present&#10;        filename: elastic-8.x&#10;&#10;    - name: Update apt repository&#10;      apt:&#10;        update_cache: yes&#10;&#10;- name: Install Elasticsearch on Debian&#10;  hosts: elastic&#10;  become: yes&#10;  tasks:&#10;    - name: Install Elasticsearch&#10;      apt:&#10;        name: elasticsearch=8.11.2&#10;        state: present&#10;    - name: Enable Elasticsearch service&#10;      ansible.builtin.systemd:&#10;        name: elasticsearch.service&#10;        enabled: yes&#10;&#10;- name: Install Kibana on Debian&#10;  hosts: kibana&#10;  become: yes&#10;  tasks:&#10;    - name: Install Kibana&#10;      apt:&#10;        name: kibana=8.11.2&#10;        state: present&#10;    - name: Enable kibana service&#10;      ansible.builtin.systemd:&#10;        name: kibana.service&#10;        enabled: yes&#10;&#10;- name: Install logstash on Debian&#10;  hosts: logstash&#10;  become: yes&#10;  tasks:&#10;    - name: Install logstash&#10;      apt:&#10;        name: logstash=1:8.11.2-1&#10;        state: present&#10;    - name: Enable logstash service&#10;      ansible.builtin.systemd:&#10;        name: logstash.service&#10;        enabled: yes&#10;&#10;- name: Copy the kibana.yml configuration file to the kibana nodes&#10;  hosts: kibana&#10;  become: yes&#10;  tasks:&#10;    - name: Copy a kibana.yml file&#10;      template:&#10;        src: &quot;{{ playbook_dir }}\/files\/kibana.j2&quot;&#10;        dest: \/etc\/kibana\/kibana.yml&#10;&#10;- name: Copy the pipelines.yml configuration file to the logstash nodes&#10;  hosts: logstash&#10;  become: yes&#10;  tasks:&#10;    - name: Copy a logstash pipelines.yml file&#10;      template:&#10;        src: &quot;{{ playbook_dir }}\/files\/logstash.j2&quot;&#10;        dest: \/etc\/logstash\/conf.d\/pipelines.conf&#10;&#10;- name: Copy the elasticsearch_node.yml configuration file to the nodes&#10;  hosts: data&#10;  gather_facts: yes&#10;  become: yes&#10;  tasks:&#10;    - name: Get zone info from metadata server&#10;      ansible.builtin.uri:&#10;        url: http:\/\/metadata.google.internal\/computeMetadata\/v1\/instance\/zone&#10;        method: GET&#10;        return_content: yes  # Ensures that the content is returned&#10;        headers:&#10;          Metadata-Flavor: &quot;Google&quot;&#10;      register: zone_info&#10;      check_mode: no&#10;    - name: Extract the zone name&#10;      set_fact:&#10;        zone_name: &quot;{{ zone_info.content.split(\" https:=\"\" name:=\"\" copy=\"\" a=\"\" elasticsearch_node.yml=\"\" file=\"\" template:=\"\" src:=\"\" playbook_dir=\"\" dest:=\"\" the=\"\" configuration=\"\" to=\"\" nodes=\"\" hosts:=\"\" master=\"\" gather_facts:=\"\" yes=\"\" become:=\"\" tasks:=\"\" elasticsearch_master.yml=\"\" download=\"\" certificates=\"\" from=\"\" gcs=\"\" bucket=\"\" elastic=\"\" command:=\"\" gsutil=\"\" cp=\"\" gs:=\"\" kibana=\"\" logstash=\"\" data-lang=\"text\/x-yaml\">\n<pre><code lang=\"text\/x-yaml\">---\n- title: Set up Elasticsearch pre-reqs on Debian\n  hosts: all\n  turn out to be: sure\n  duties:\n    - title: Replace apt repository\n      apt:\n        update_cache: sure\n\n    - title: Set up default-jre\n      apt:\n        title:\n          - default-jre\n        state: current\n\n    - title: Add Elasticsearch GPG key\n      apt_key:\n        url: https:\/\/artifacts.elastic.co\/GPG-KEY-elasticsearch\n        state: current\n\n    - title: Set up apt-transport-https\n      apt:\n        title: apt-transport-https\n        state: current\n\n    - title: Add Elasticsearch repository\n      apt_repository:\n        repo: \"deb https:\/\/artifacts.elastic.co\/packages\/8.x\/apt secure essential\"\n        state: current\n        filename: elastic-8.x\n\n    - title: Replace apt repository\n      apt:\n        update_cache: sure\n\n- title: Set up Elasticsearch on Debian\n  hosts: elastic\n  turn out to be: sure\n  duties:\n    - title: Set up Elasticsearch\n      apt:\n        title: elasticsearch=8.11.2\n        state: current\n    - title: Allow Elasticsearch service\n      ansible.builtin.systemd:\n        title: elasticsearch.service\n        enabled: sure\n\n- title: Set up Kibana on Debian\n  hosts: kibana\n  turn out to be: sure\n  duties:\n    - title: Set up Kibana\n      apt:\n        title: kibana=8.11.2\n        state: current\n    - title: Allow kibana service\n      ansible.builtin.systemd:\n        title: kibana.service\n        enabled: sure\n\n- title: Set up logstash on Debian\n  hosts: logstash\n  turn out to be: sure\n  duties:\n    - title: Set up logstash\n      apt:\n        title: logstash=1:8.11.2-1\n        state: current\n    - title: Allow logstash service\n      ansible.builtin.systemd:\n        title: logstash.service\n        enabled: sure\n\n- title: Copy the kibana.yml configuration file to the kibana nodes\n  hosts: kibana\n  turn out to be: sure\n  duties:\n    - title: Copy a kibana.yml file\n      template:\n        src: \"{{ playbook_dir }}\/recordsdata\/kibana.j2\"\n        dest: \/and so on\/kibana\/kibana.yml\n\n- title: Copy the pipelines.yml configuration file to the logstash nodes\n  hosts: logstash\n  turn out to be: sure\n  duties:\n    - title: Copy a logstash pipelines.yml file\n      template:\n        src: \"{{ playbook_dir }}\/recordsdata\/logstash.j2\"\n        dest: \/and so on\/logstash\/conf.d\/pipelines.conf\n\n- title: Copy the elasticsearch_node.yml configuration file to the nodes\n  hosts: information\n  gather_facts: sure\n  turn out to be: sure\n  duties:\n    - title: Get zone information from metadata server\n      ansible.builtin.uri:\n        url: http:\/\/metadata.google.inside\/computeMetadata\/v1\/occasion\/zone\n        technique: GET\n        return_content: sure  # Ensures that the content material is returned\n        headers:\n          Metadata-Taste: \"Google\"\n      register: zone_info\n      check_mode: no\n    - title: Extract the zone title\n      set_fact:\n        zone_name: \"{{ zone_info.content material.break up(\"https:\/\/dzone.com\/\")[-1] }}\"\n    - title: Copy a elasticsearch_node.yml file\n      template:\n        src: \"{{ playbook_dir }}\/recordsdata\/elasticsearch_node.j2\"\n        dest: \/and so on\/elasticsearch\/elasticsearch.yml\n\n- title: Copy the elasticsearch_node.yml configuration file to the nodes\n  hosts: grasp\n  gather_facts: sure\n  turn out to be: sure\n  duties:\n    - title: Copy a elasticsearch_master.yml file\n      template:\n        src: \"{{ playbook_dir }}\/recordsdata\/elasticsearch_master.j2\"\n        dest: \/and so on\/elasticsearch\/elasticsearch.yml\n- title: Obtain the certificates from the GCS bucket\n  hosts: elastic\n  turn out to be: sure\n  duties:\n    - title: certificates\n      command: gsutil cp gs:\/\/nonprod-elastic-certificates\/* \/and so on\/elasticsearch\/certs\n- title: Obtain the certificates from the GCS bucket\n  hosts: kibana\n  turn out to be: sure\n  duties:\n    - title: certificates\n      command: gsutil cp gs:\/\/nonprod-elastic-certificates\/elasticsearch-ca.pem \/and so on\/kibana\n\n- title: Obtain the certificates from the GCS bucket\n  hosts: logstash\n  turn out to be: sure\n  duties:\n    - title: certificates\n      command: gsutil cp gs:\/\/nonprod-elastic-certificates\/elasticsearch-ca.pem \/usr\/share\/logstash\/pipeline\/elasticsearch-ca.pem\n<\/code><\/pre>\n<\/p><\/div><\/div>\n<\/div>\n<div data-message-author-role=\"assistant\" data-message-id=\"677080d4-efb3-487b-9053-bc6e1a7703db\" data-message-model-slug=\"gpt-4o\" dir=\"auto\">\n<p data-end=\"140\" data-is-last-node=\"\" data-is-only-node=\"\" data-start=\"0\">The configuration recordsdata required by the Ansible playbook ought to be positioned within the <code>recordsdata<\/code> listing. The anticipated recordsdata are listed under:<\/p>\n<h3 data-end=\"140\" data-is-last-node=\"\" data-is-only-node=\"\" data-start=\"0\">1. <strong>elasticsearch_master.j2<\/strong><\/h3>\n<\/div>\n<div class=\"codeMirror-wrapper\" contenteditable=\"false\">\n<div contenteditable=\"false\">\n<div class=\"codeMirror-code--wrapper\" data-code=\"node.name: {{ ansible_default_ipv4.address }}&#10;node.roles: [ master ]&#10;discovery.seed_hosts:&#10; - 10.x.x.x&#10; - 10.x.x.x&#10; - 10.x.x.x&#10;#cluster.initial_master_nodes:&#10;# - 10.x.x.x&#10;# - 10.x.x.x&#10;# - 10.x.x.x&#10;network.host : {{ ansible_default_ipv4.address }}&#10;cluster.name: prod-monitoring&#10;path:&#10;  data: \/mnt\/disks\/elasticsearch&#10;  logs: \/var\/log\/elasticsearch&#10;cluster.routing.allocation.awareness.attributes: zone&#10;cluster.routing.allocation.awareness.force.zone.values: us-central1-a,us-central1-b&#10;xpack.security.http.ssl.enabled: true&#10;xpack.security.http.ssl.keystore.path: \/etc\/elasticsearch\/certs\/http.p12&#10;xpack.security.enabled: true&#10;xpack.security.transport.ssl.enabled: true&#10;xpack.security.audit.enabled: true&#10;xpack.security.transport.ssl.verification_mode: certificate&#10;xpack.security.transport.ssl.keystore.path: \/etc\/elasticsearch\/certs\/elastic-certificates.p12&#10;xpack.security.transport.ssl.client_authentication: required&#10;xpack.security.transport.ssl.truststore.path: \/etc\/elasticsearch\/certs\/elastic-certificates.p12&#10;xpack.license.self_generated.type: basic\" data-lang=\"null\">\n<pre><code lang=\"null\">node.title: {{ ansible_default_ipv4.handle }}\nnode.roles: [ master ]\ndiscovery.seed_hosts:\n - 10.x.x.x\n - 10.x.x.x\n - 10.x.x.x\n#cluster.initial_master_nodes:\n# - 10.x.x.x\n# - 10.x.x.x\n# - 10.x.x.x\ncommunity.host : {{ ansible_default_ipv4.handle }}\ncluster.title: prod-monitoring\npath:\n  information: \/mnt\/disks\/elasticsearch\n  logs: \/var\/log\/elasticsearch\ncluster.routing.allocation.consciousness.attributes: zone\ncluster.routing.allocation.consciousness.power.zone.values: us-central1-a,us-central1-b\nxpack.safety.http.ssl.enabled: true\nxpack.safety.http.ssl.keystore.path: \/and so on\/elasticsearch\/certs\/http.p12\nxpack.safety.enabled: true\nxpack.safety.transport.ssl.enabled: true\nxpack.safety.audit.enabled: true\nxpack.safety.transport.ssl.verification_mode: certificates\nxpack.safety.transport.ssl.keystore.path: \/and so on\/elasticsearch\/certs\/elastic-certificates.p12\nxpack.safety.transport.ssl.client_authentication: required\nxpack.safety.transport.ssl.truststore.path: \/and so on\/elasticsearch\/certs\/elastic-certificates.p12\nxpack.license.self_generated.kind: fundamental<\/code><\/pre>\n<\/p><\/div><\/div>\n<\/div>\n<div data-en-clipboard=\"true\" data-pm-slice=\"1 3 []\" draggable=\"false\">\n <br \/>\n A couple of factors to be famous in regards to the above elastic grasp nodes configuration:\n <\/div>\n<ol>\n<li draggable=\"false\">\n<p>\n   We&#8217;re utilizing a fundamental (free) license, not a premium one.\n  <\/p>\n<\/li>\n<li draggable=\"false\">\n<p>\n   When Ansible runs on the grasp node, it robotically fills within the IPv4 handle of the grasp node by default.\n  <\/p>\n<\/li>\n<li draggable=\"false\">\n<p>\n   Uncomment <code>cluster.initial_master_nodes<\/code> <strong>solely<\/strong> when creating the cluster for the primary time.\n  <\/p>\n<\/li>\n<li draggable=\"false\">\n<div draggable=\"false\">\n   Safety is enabled between:\u00a0<\/p>\n<ul>\n<li>Grasp nodes utilizing <code>xpack.safety.transport.ssl.enabled<\/code><\/li>\n<li>Information nodes and Kibana\/Logstash utilizing <code>xpack.safety.http.ssl.enabled<\/code><\/li>\n<\/ul><\/div>\n<\/li>\n<\/ol>\n<h3 data-en-clipboard=\"true\" data-pm-slice=\"1 1 [&quot;ol&quot;,{&quot;style&quot;:null,&quot;start&quot;:&quot;2&quot;,&quot;backgroundColor&quot;:null,&quot;color&quot;:null,&quot;lineHeight&quot;:null,&quot;listStyleType&quot;:null},&quot;li&quot;,{&quot;style&quot;:null,&quot;checked&quot;:null,&quot;value&quot;:null,&quot;displayValue&quot;:&quot;2&quot;,&quot;backgroundColor&quot;:null,&quot;color&quot;:null,&quot;listStyleType&quot;:null,&quot;isCollapsed&quot;:null,&quot;draggable&quot;:false,&quot;alignmentReferenceFontSize&quot;:null}]\" draggable=\"false\"><strong>2. elasticsearch_node.j2<\/strong><\/h3>\n<div class=\"codeMirror-wrapper\" contenteditable=\"false\">\n<div contenteditable=\"false\">\n<div class=\"codeMirror-code--wrapper\" data-code=\"node.name: {{ ansible_default_ipv4.address }}&#10;node.roles: [ data, transform, ingest ]&#10;discovery.seed_hosts:&#10; - 10.x.x.x&#10; - 10.x.x.x&#10; - 10.x.x.x&#10;#cluster.initial_master_nodes:&#10;# - 10.x.x.x&#10;# - 10.x.x.x&#10;# - 10.x.x.x&#10;network.host : {{ ansible_default_ipv4.address }}&#10;cluster.name: prod-monitoring&#10;path:&#10;  data: \/mnt\/disks\/elasticsearch&#10;  logs: \/var\/log\/elasticsearch&#10;node.attr.zone: {{ zone_name }}&#10;xpack.security.http.ssl.enabled: true&#10;xpack.security.http.ssl.keystore.path: \/etc\/elasticsearch\/certs\/http.p12&#10;xpack.security.enabled: true&#10;xpack.security.transport.ssl.enabled: true&#10;xpack.security.audit.enabled: true&#10;xpack.security.transport.ssl.verification_mode: certificate&#10;xpack.security.transport.ssl.keystore.path: \/etc\/elasticsearch\/certs\/elastic-certificates.p12&#10;xpack.security.transport.ssl.client_authentication: required&#10;xpack.security.transport.ssl.truststore.path: \/etc\/elasticsearch\/certs\/elastic-certificates.p12&#10;xpack.license.self_generated.type: basic\" data-lang=\"null\">\n<pre><code lang=\"null\">node.title: {{ ansible_default_ipv4.handle }}\nnode.roles: [ data, transform, ingest ]\ndiscovery.seed_hosts:\n - 10.x.x.x\n - 10.x.x.x\n - 10.x.x.x\n#cluster.initial_master_nodes:\n# - 10.x.x.x\n# - 10.x.x.x\n# - 10.x.x.x\ncommunity.host : {{ ansible_default_ipv4.handle }}\ncluster.title: prod-monitoring\npath:\n  information: \/mnt\/disks\/elasticsearch\n  logs: \/var\/log\/elasticsearch\nnode.attr.zone: {{ zone_name }}\nxpack.safety.http.ssl.enabled: true\nxpack.safety.http.ssl.keystore.path: \/and so on\/elasticsearch\/certs\/http.p12\nxpack.safety.enabled: true\nxpack.safety.transport.ssl.enabled: true\nxpack.safety.audit.enabled: true\nxpack.safety.transport.ssl.verification_mode: certificates\nxpack.safety.transport.ssl.keystore.path: \/and so on\/elasticsearch\/certs\/elastic-certificates.p12\nxpack.safety.transport.ssl.client_authentication: required\nxpack.safety.transport.ssl.truststore.path: \/and so on\/elasticsearch\/certs\/elastic-certificates.p12\nxpack.license.self_generated.kind: fundamental<\/code><\/pre>\n<\/p><\/div><\/div>\n<\/div>\n<h3>3. <strong>kibana.j2<\/strong><\/h3>\n<div class=\"codeMirror-wrapper newest\" contenteditable=\"false\">\n<div contenteditable=\"false\">\n<div class=\"codeMirror-code--wrapper\" data-code=\"elasticsearch.hosts: [&quot;https:\/\/10.x.x.x:9200&quot;,&quot;https:\/\/10.x.x.x:9200&quot;,&quot;https:\/\/10.x.x.x:9200&quot;,&quot;https:\/\/10.x.x.x:9200&quot;]&#10;server.name: kibana&#10;server.host: {{ ansible_default_ipv4.address }}&#10;server.port: 443&#10;elasticsearch.username: 'kibana_system'&#10;elasticsearch.password: 'somepassxxxxx'&#10;elasticsearch.ssl.certificateAuthorities: ['\/etc\/kibana\/elasticsearch-ca.pem']&#10;elasticsearch.ssl.verificationMode: 'certificate'&#10;server.ssl.enabled: true&#10;server.ssl.certificate: \/etc\/ssl\/kibana\/kibana-cert.crt&#10;server.ssl.key: \/etc\/ssl\/kibana\/kibana-key.key&#10;server.publicBaseUrl: https:\/\/elastic.company.xyz&#10;xpack.encryptedSavedObjects.encryptionKey: zxy123f1318d633817xyz1234&#10;xpack.reporting.encryptionKey: 1xfsyc4ad24176a902f2xyz123&#10;xpack.security.encryptionKey: cskcjsn60e148a70308d39dxyz123&#10;logging:&#10;  appenders:&#10;    file:&#10;      type: file&#10;      fileName: \/var\/log\/kibana\/kibana.log&#10;      layout:&#10;        type: json&#10;  root:&#10;    appenders:&#10;      - default&#10;      - file&#10;pid.file: \/run\/kibana\/kibana.pid\" data-lang=\"null\">\n<pre><code lang=\"null\">elasticsearch.hosts: [\"https:\/\/10.x.x.x:9200\",\"https:\/\/10.x.x.x:9200\",\"https:\/\/10.x.x.x:9200\",\"https:\/\/10.x.x.x:9200\"]\nserver.title: kibana\nserver.host: {{ ansible_default_ipv4.handle }}\nserver.port: 443\nelasticsearch.username: 'kibana_system'\nelasticsearch.password: 'somepassxxxxx'\nelasticsearch.ssl.certificateAuthorities: ['\/etc\/kibana\/elasticsearch-ca.pem']\nelasticsearch.ssl.verificationMode: 'certificates'\nserver.ssl.enabled: true\nserver.ssl.certificates: \/and so on\/ssl\/kibana\/kibana-cert.crt\nserver.ssl.key: \/and so on\/ssl\/kibana\/kibana-key.key\nserver.publicBaseUrl: https:\/\/elastic.firm.xyz\nxpack.encryptedSavedObjects.encryptionKey: zxy123f1318d633817xyz1234\nxpack.reporting.encryptionKey: 1xfsyc4ad24176a902f2xyz123\nxpack.safety.encryptionKey: cskcjsn60e148a70308d39dxyz123\nlogging:\n  appenders:\n    file:\n      kind: file\n      fileName: \/var\/log\/kibana\/kibana.log\n      format:\n        kind: json\n  root:\n    appenders:\n      - default\n      - file\npid.file: \/run\/kibana\/kibana.pid<\/code><\/pre>\n<\/p><\/div><\/div>\n<\/div>\n<h3>4.<strong>\u00a0l<\/strong><strong>ogstash.j2<\/strong><\/h3>\n<div class=\"codeMirror-wrapper\" contenteditable=\"false\">\n<div contenteditable=\"false\">\n<div class=\"codeMirror-code--wrapper\" data-code=\"input {&#10;        beats {&#10;                port =&gt; 5044&#10;        }&#10;&#10;        tcp {&#10;                port =&gt; 50000&#10;        }&#10;    tcp {&#10;        port =&gt; 5000&#10;        codec =&gt; &quot;line&quot;&#10;        type =&gt; &quot;syslog&quot;&#10;    }&#10;&#10;    http {&#10;        port =&gt; 5050&#10;    }&#10;        google_pubsub {&#10;        type =&gt; &quot;pubsub&quot;&#10;        project_id =&gt; &quot;my-project-123&quot;&#10;        topic =&gt; &quot;cloud_functions_logs&quot;&#10;        subscription =&gt; &quot;cloud_functions_logs-sub&quot;&#10;###        json_key_file =&gt; &quot;\/etc\/logstash\/keys\/logstash-sa.json&quot;&#10;        codec =&gt; &quot;json&quot;&#10;                      }&#10;        google_pubsub {&#10;        type =&gt; &quot;pubsub&quot;&#10;        project_id =&gt; &quot;my-project-123&quot;&#10;        topic =&gt; &quot;cloud_run_logs&quot;&#10;        subscription =&gt; &quot;cloud_run_logs-sub&quot;&#10;###        json_key_file =&gt; &quot;\/etc\/logstash\/keys\/logstash-sa.json&quot;&#10;        codec =&gt; &quot;json&quot;&#10;                      }&#10;}&#10;&#10;filter {&#10;    grok {&#10;        match =&gt; { &quot;message&quot; =&gt; &quot;^%{SYSLOGTIMESTAMP:timestamp} %{SYSLOGHOST:hostname} %{DATA:program}(?:[%{POSINT:pid}])?: %{GREEDYDATA:log_message}&quot; }&#10;    }&#10;    &#10;    date {&#10;        match =&gt; [ &quot;timestamp&quot;, &quot;MMM  d HH:mm:ss&quot;, &quot;MMM dd HH:mm:ss&quot; ]&#10;        target =&gt; &quot;@timestamp&quot;&#10;    }&#10;    &#10;    kv  &quot;&#10;        value_split =&gt; &quot;=&quot;&#10;    &#10;    &#10;    mutate {&#10;        remove_field =&gt; [ &quot;timestamp&quot; ]&#10;        convert =&gt; { &quot;pid&quot; =&gt; &quot;integer&quot; }&#10;    }&#10;}&#10;&#10;### Add your filters \/ logstash plugins configuration here&#10;&#10;output {&#10;        elasticsearch {&#10;                hosts =&gt; [&quot;https:\/\/10.x.x.x:9200&quot;,&quot;https:\/\/10.x.x.x:9200&quot;,&quot;https:\/\/10.x.x.x:9200&quot;,&quot;https:\/\/10.x.x.x:9200&quot;]&#10;                user =&gt; &quot;logstash_writer&quot;&#10;                password =&gt; &quot;mypassxyz&quot;&#10;                index =&gt; &quot;logs-my-index-%{+yyyy.MM.dd}&quot;&#10;                action =&gt; &quot;create&quot;&#10;                ssl =&gt; true&#10;                cacert =&gt; '\/usr\/share\/logstash\/pipeline\/elasticsearch-ca.pem'&#10;        }&#10;}\" data-lang=\"null\">\n<pre><code lang=\"null\">enter {\n        beats {\n                port =&gt; 5044\n        }\n\n        tcp {\n                port =&gt; 50000\n        }\n    tcp {\n        port =&gt; 5000\n        codec =&gt; \"line\"\n        kind =&gt; \"syslog\"\n    }\n\n    http {\n        port =&gt; 5050\n    }\n        google_pubsub {\n        kind =&gt; \"pubsub\"\n        project_id =&gt; \"my-project-123\"\n        subject =&gt; \"cloud_functions_logs\"\n        subscription =&gt; \"cloud_functions_logs-sub\"\n###        json_key_file =&gt; \"\/and so on\/logstash\/keys\/logstash-sa.json\"\n        codec =&gt; \"json\"\n                      }\n        google_pubsub {\n        kind =&gt; \"pubsub\"\n        project_id =&gt; \"my-project-123\"\n        subject =&gt; \"cloud_run_logs\"\n        subscription =&gt; \"cloud_run_logs-sub\"\n###        json_key_file =&gt; \"\/and so on\/logstash\/keys\/logstash-sa.json\"\n        codec =&gt; \"json\"\n                      }\n}\n\nfilter {\n    grok {\n        match =&gt; { \"message\" =&gt; \"^%{SYSLOGTIMESTAMP:timestamp} %{SYSLOGHOST:hostname} %{DATA:program}(?:[%{POSINT:pid}])?: %{GREEDYDATA:log_message}\" }\n    }\n    \n    date {\n        match =&gt; [ \"timestamp\", \"MMM  d HH:mm:ss\", \"MMM dd HH:mm:ss\" ]\n        goal =&gt; \"@timestamp\"\n    }\n    \n    kv  \"\n        value_split =&gt; \"=\"\n    \n    \n    mutate {\n        remove_field =&gt; [ \"timestamp\" ]\n        convert =&gt; { \"pid\" =&gt; \"integer\" }\n    }\n}\n\n### Add your filters \/ logstash plugins configuration right here\n\noutput {\n        elasticsearch {\n                hosts =&gt; [\"https:\/\/10.x.x.x:9200\",\"https:\/\/10.x.x.x:9200\",\"https:\/\/10.x.x.x:9200\",\"https:\/\/10.x.x.x:9200\"]\n                person =&gt; \"logstash_writer\"\n                password =&gt; \"mypassxyz\"\n                index =&gt; \"logs-my-index-%{+yyyy.MM.dd}\"\n                motion =&gt; \"create\"\n                ssl =&gt; true\n                cacert =&gt; '\/usr\/share\/logstash\/pipeline\/elasticsearch-ca.pem'\n        }\n}<\/code><\/pre>\n<\/p><\/div><\/div>\n<\/div>\n<p>A couple of factors to be famous in regards to the above logstash configuration:<\/p>\n<ul data-en-clipboard=\"true\" data-pm-slice=\"3 3 []\">\n<li draggable=\"false\">\n<p>\n   Within the Logstash configuration above, we use numerous filters corresponding to <code>grok<\/code>, <code>date<\/code>, <code>kv<\/code>, and <code>mutate<\/code> to match and modify incoming logs. Modify in response to your wants.\n  <\/p>\n<\/li>\n<li draggable=\"false\">\n<p>\n   In each <code>kibana.j2<\/code> and <code>logstash.j2<\/code>, for &#8220;elasticsearch.hosts&#8221;, you possibly can specify all information nodes as a listing, permitting requests to be round-robin distributed throughout them. Alternatively, configure an inside load balancer with information nodes because the backend and supply simply the load balancer&#8217;s IP.\n  <\/p>\n<\/li>\n<li draggable=\"false\">\n<p>\n   Be certain that the <code>index<\/code> and <code>logstash_writer<\/code> customers are created by way of the Kibana console. Moreover, configure the mandatory indices to ingest information from different sources like Filebeat and assign correct permissions to the respective customers.\n  <\/p>\n<\/li>\n<li draggable=\"false\">\n<p>\n   Information might be ingested into Elasticsearch by way of Logstash, permitting for mandatory filtering, or it may be despatched on to information nodes utilizing brokers like Filebeat.\n  <\/p>\n<\/li>\n<li draggable=\"false\">\n<div data-message-author-role=\"assistant\" data-message-id=\"0a894ade-b274-402c-b28d-aef2ee5fdc5b\" data-message-model-slug=\"gpt-4o\" dir=\"auto\">\n<div data-message-author-role=\"assistant\" data-message-id=\"f35106c3-5b62-4c5f-a9e5-c45bae6bdae1\" data-message-model-slug=\"gpt-4o\" dir=\"auto\">\n<p data-end=\"304\" data-is-last-node=\"\" data-is-only-node=\"\" data-start=\"0\">If you&#8217;re storing any of the above <code>.j2<\/code> Jinja recordsdata in a Git repository, they usually comprise delicate data, encrypt them utilizing <code>ansible-vault<\/code>. Discuss with the <a rel=\"nofollow\" target=\"_blank\" data-end=\"257\" data-start=\"171\" href=\"https:\/\/docs.ansible.com\/ansible\/2.8\/user_guide\/vault.html\" rel=\"noopener\" target=\"_new\">Ansible documentation<\/a> to study extra about utilizing <code>ansible-vault<\/code>.<\/p>\n<\/p><\/div><\/div>\n<\/li>\n<\/ul>\n<p>\n Right here is the Filebeat configuration if you wish to ship logs immediately from Docker functions. It&#8217;s also possible to use it to ship logs from some other functions.\n<\/p>\n<h4 data-en-clipboard=\"true\" data-pm-slice=\"1 1 []\" draggable=\"false\"><strong>filebeat.conf<\/strong><\/h4>\n<div class=\"codeMirror-wrapper\" contenteditable=\"false\">\n<div contenteditable=\"false\">\n<div class=\"codeMirror-code--wrapper\" data-code=\"logging.json: true&#10;logging.level: info&#10;logging.metrics.enabled: false&#10;&#10;setup.kibana.host: ${KIBANA_HOST}&#10;setup.ilm.enabled: true&#10;&#10;output.elasticsearch:&#10;  hosts: ${ELASTIC_HOST}&#10;  indices:&#10;    - index: &quot;audit-%{+yyyy.MM.dd}&quot;&#10;      when.has_fields: [&quot;_audit&quot;]&#10;    - index: &quot;logs-%{+yyyy.MM.dd}&quot;&#10;      when.has_fields: [&quot;app&quot;, &quot;env&quot;]&#10;    - index: &quot;invalid-stream-%{+yyyy.MM.dd}&quot;&#10;      when.has_fields: [&quot;error.data&quot;, &quot;error.message&quot;]&#10;&#10;filebeat.autodiscover:&#10;  providers:&#10;    - type: docker&#10;      templates:&#10;        - config:&#10;            - type: container&#10;              paths:&#10;                - \/var\/lib\/docker\/containers\/${data.docker.container.id}\/*.log&#10;&#10;processors:&#10;  - decode_json_fields:&#10;      fields: [&quot;message&quot;]&#10;      process_array: false&#10;      max_depth: 1&#10;      target: &quot;&quot;&#10;      overwrite_keys: false&#10;      add_error_key: true\" data-lang=\"text\/x-yaml\">\n<pre><code lang=\"text\/x-yaml\">logging.json: true\nlogging.stage: information\nlogging.metrics.enabled: false\n\nsetup.kibana.host: ${KIBANA_HOST}\nsetup.ilm.enabled: true\n\noutput.elasticsearch:\n  hosts: ${ELASTIC_HOST}\n  indices:\n    - index: \"audit-%{+yyyy.MM.dd}\"\n      when.has_fields: [\"_audit\"]\n    - index: \"logs-%{+yyyy.MM.dd}\"\n      when.has_fields: [\"app\", \"env\"]\n    - index: \"invalid-stream-%{+yyyy.MM.dd}\"\n      when.has_fields: [\"error.data\", \"error.message\"]\n\nfilebeat.autodiscover:\n  suppliers:\n    - kind: docker\n      templates:\n        - config:\n            - kind: container\n              paths:\n                - \/var\/lib\/docker\/containers\/${information.docker.container.id}\/*.log\n\nprocessors:\n  - decode_json_fields:\n      fields: [\"message\"]\n      process_array: false\n      max_depth: 1\n      goal: \"\"\n      overwrite_keys: false\n      add_error_key: true<\/code><\/pre>\n<\/p><\/div><\/div>\n<\/div>\n<p>\n <br \/>As soon as ELK is about up, you possibly can configure information backups known as snapshots to the &#8216;elastic-backup&#8217; GCS bucket by way of the Kibana console.\n<\/p>\n<h2 draggable=\"false\">Conclusion<\/h2>\n<p><span class=\"fr-img-caption fr-fic fr-dib\" style=\"width: 808px;\"><span class=\"fr-img-wrap\"><img decoding=\"async\" data-image=\"true\" data-new=\"false\" data-sizeformatted=\"383.3 kB\" data-mimetype=\"image\/png\" data-creationdate=\"1743807835507\" data-creationdateformatted=\"04\/04\/2025 11:03 PM\" data-type=\"temp\" data-url=\"https:\/\/dz2cdn1.dzone.com\/storage\/temp\/18321932-kibana-gui.png\" data-modificationdate=\"null\" data-size=\"383290\" data-name=\"kibana-gui.png\" data-id=\"18321932\" alt=\"Figure 2\" src=\"https:\/\/dz2cdn1.dzone.com\/storage\/temp\/18321932-kibana-gui.png\" class=\"lazyload\"\/><\/span><\/span><\/p><figcaption class=\"fr-inner\" contenteditable=\"true\">\n <em>Determine 2<\/em><br \/>\n<\/figcaption><p>\n With information being ingested from numerous sources, corresponding to Filebeat, into the Elasticsearch cluster, you possibly can entry Kibana&#8217;s UI to look logs (Determine 2), create visualizations, monitor logs, and arrange alerts successfully.\n<\/p>\n<div draggable=\"false\">\n By putting in and configuring the open-source ELK stack, you possibly can considerably scale back licensing prices whereas solely paying for the GCP infrastructure you employ. Terraform and Ansible automation make it easier to rise up and operating rapidly, permitting for simple scaling with minimal effort.\n <\/div>\n<div draggable=\"false\">\n Good luck! Be happy to attach with me on <a rel=\"nofollow\" target=\"_blank\" href=\"https:\/\/www.linkedin.com\/in\/pradeep-gaddamidi-27009625\/\" rel=\"noopener noreferrer\" target=\"_blank\">LinkedIn<\/a>.\n<\/div>\n<\/div>\n\n","protected":false},"excerpt":{"rendered":"<p>If your organization has finances constraints, buying licensed merchandise like Splunk for logging infrastructure is probably not possible. Fortuitously, a robust open-source different exists: ELK (Elasticsearch, Logstash, and Kibana). ELK gives strong logging and visualization capabilities. At a startup the place I labored, value minimization was a precedence, so I applied ELK for logging. On [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":1072,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[56],"tags":[475,906,903,904,907,905],"class_list":["post-1070","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-software","tag-building","tag-centralized","tag-costeffective","tag-elk","tag-logging","tag-stack"],"_links":{"self":[{"href":"https:\/\/techtrendfeed.com\/index.php?rest_route=\/wp\/v2\/posts\/1070","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/techtrendfeed.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/techtrendfeed.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/techtrendfeed.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/techtrendfeed.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1070"}],"version-history":[{"count":1,"href":"https:\/\/techtrendfeed.com\/index.php?rest_route=\/wp\/v2\/posts\/1070\/revisions"}],"predecessor-version":[{"id":1071,"href":"https:\/\/techtrendfeed.com\/index.php?rest_route=\/wp\/v2\/posts\/1070\/revisions\/1071"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/techtrendfeed.com\/index.php?rest_route=\/wp\/v2\/media\/1072"}],"wp:attachment":[{"href":"https:\/\/techtrendfeed.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1070"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/techtrendfeed.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1070"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/techtrendfeed.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1070"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}<!-- This website is optimized by Airlift. Learn more: https://airlift.net. Template:. Learn more: https://airlift.net. Template: 69d9690a190636c2e0989534. Config Timestamp: 2026-04-10 21:18:02 UTC, Cached Timestamp: 2026-06-15 09:17:53 UTC -->